Generate PIC code so that we can create shared objects properly.
- Add got_table in TCCState. This approach is naive and the distance between executable code and GOT can be longer than 32bit. - Handle R_X86_64_GOTPCREL properly. We use got_table for TCC_OUTPUT_MEMORY case for now. - Fix load() and store() so that they access global variables via GOT.
This commit is contained in:
committed by
grischka
parent
6c10429aa5
commit
830b7533c9
29
tccelf.c
29
tccelf.c
@ -502,6 +502,25 @@ static unsigned long add_jmp_table(TCCState *s1, unsigned long val)
|
||||
*(unsigned long *)(p + 6) = val;
|
||||
return (unsigned long)p;
|
||||
}
|
||||
|
||||
#define GOT_TABLE_ENTRY_MAX_NUM 4096
|
||||
static unsigned long add_got_table(TCCState *s1, unsigned long val)
|
||||
{
|
||||
unsigned long *p;
|
||||
if (!s1->got_table) {
|
||||
int size = sizeof(void *) * GOT_TABLE_ENTRY_MAX_NUM;
|
||||
s1->got_table_num = 0;
|
||||
s1->got_table = (char *)tcc_malloc(size);
|
||||
}
|
||||
if (s1->got_table_num == GOT_TABLE_ENTRY_MAX_NUM) {
|
||||
error("relocating >%d symbols are not supported",
|
||||
GOT_TABLE_ENTRY_MAX_NUM);
|
||||
}
|
||||
p = s1->got_table + s1->got_table_num;
|
||||
s1->got_table_num++;
|
||||
*p = val;
|
||||
return (unsigned long)p;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* relocate a given section (CPU dependent) */
|
||||
@ -727,11 +746,13 @@ static void relocate_section(TCCState *s1, Section *s)
|
||||
*(int *)ptr = val;
|
||||
break;
|
||||
case R_X86_64_GOTPCREL:
|
||||
*(int *)ptr += s1->got->sh_addr - addr;
|
||||
/* XXX: is this OK? */
|
||||
if (s1->output_type == TCC_OUTPUT_DLL) {
|
||||
*(int *)ptr += s1->got_offsets[sym_index] - 4;
|
||||
if (s1->output_type == TCC_OUTPUT_MEMORY) {
|
||||
val = add_got_table(s1, val - rel->r_addend) + rel->r_addend;
|
||||
*(int *)ptr += val - addr;
|
||||
break;
|
||||
}
|
||||
*(int *)ptr += (s1->got->sh_addr - addr +
|
||||
s1->got_offsets[sym_index] - 4);
|
||||
break;
|
||||
case R_X86_64_GOTTPOFF:
|
||||
*(int *)ptr += val - s1->got->sh_addr;
|
||||
|
||||
Reference in New Issue
Block a user