aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShinichiro Hamaji <shinichiro.hamaji _at_ gmail.com>2009-04-17 10:17:14 +0900
committergrischka <grischka>2009-04-18 15:08:02 +0200
commit9a7173bf69cc1e620f33e2d08550a70d31674a0f (patch)
tree493f0209507800ea5daaeb6644932854dc57caa3
parente6ba81b012b1ce6d7c451ef25d21330c638e1320 (diff)
downloadtinycc-9a7173bf69cc1e620f33e2d08550a70d31674a0f.tar.gz
tinycc-9a7173bf69cc1e620f33e2d08550a70d31674a0f.tar.bz2
x86-64: Fix tcc -run. We need extra memory for PLT and GOT.
Size of the extra buffer is too large for now.
-rw-r--r--tcc.c31
-rw-r--r--tccelf.c8
2 files changed, 27 insertions, 12 deletions
diff --git a/tcc.c b/tcc.c
index acff2e4..3a0f725 100644
--- a/tcc.c
+++ b/tcc.c
@@ -545,6 +545,12 @@ struct TCCState {
/* for tcc_relocate */
int runtime_added;
+
+#ifdef TCC_TARGET_X86_64
+ /* write PLT and GOT here */
+ char *runtime_plt_and_got;
+ unsigned int runtime_plt_and_got_offset;
+#endif
};
/* The current value can be: */
@@ -1311,12 +1317,7 @@ Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
static void free_section(Section *s)
{
-#ifdef TCC_TARGET_X86_64
- /* after tcc_relocate(), some sections share the data buffer.
- let's check if the data is allocated not to free the shared buffers */
- if (s->data_allocated)
-#endif
- tcc_free(s->data);
+ tcc_free(s->data);
}
/* realloc section and set its content to zero */
@@ -10327,14 +10328,22 @@ int tcc_relocate(TCCState *s1, void *ptr)
offset = (offset + length + 15) & ~15;
}
+#ifdef TCC_TARGET_X86_64
+ s1->runtime_plt_and_got_offset = 0;
+ s1->runtime_plt_and_got = (char *)(mem + offset);
+ /* double the size of the buffer for got and plt entries
+ XXX: calculate exact size for them? */
+ offset *= 2;
+#endif
+
+ if (0 == mem)
+ return offset + 15;
+
/* relocate symbols */
relocate_syms(s1, 1);
if (s1->nb_errors)
return -1;
- if (0 == mem)
- return offset + 15;
-
/* relocate each section */
for(i = 1; i < s1->nb_sections; i++) {
s = s1->sections[i];
@@ -10357,6 +10366,10 @@ int tcc_relocate(TCCState *s1, void *ptr)
if (s->sh_flags & SHF_EXECINSTR)
set_pages_executable(ptr, length);
}
+#ifdef TCC_TARGET_X86_64
+ set_pages_executable(s1->runtime_plt_and_got,
+ s1->runtime_plt_and_got_offset);
+#endif
return 0;
}
diff --git a/tccelf.c b/tccelf.c
index 6a26831..11bb82c 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -480,7 +480,8 @@ static void relocate_syms(TCCState *s1, int do_resolve)
#define JMP_TABLE_ENTRY_SIZE 14
static unsigned long add_jmp_table(TCCState *s1, unsigned long val)
{
- char *p = (char *)section_ptr_add(text_section, JMP_TABLE_ENTRY_SIZE);
+ char *p = s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset;
+ s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE;
/* jmp *0x0(%rip) */
p[0] = 0xff;
p[1] = 0x25;
@@ -491,8 +492,9 @@ static unsigned long add_jmp_table(TCCState *s1, unsigned long val)
static unsigned long add_got_table(TCCState *s1, unsigned long val)
{
- unsigned long *p =
- (unsigned long *)section_ptr_add(text_section, sizeof(void *));
+ unsigned long *p =(unsigned long *)(s1->runtime_plt_and_got +
+ s1->runtime_plt_and_got_offset);
+ s1->runtime_plt_and_got_offset += sizeof(void *);
*p = val;
return (unsigned long)p;
}