x86_64: Create proper PLT and GOT also for -run

This makes us use the normal PLT/GOT codepaths also for -run,
which formerly used an on-the-side blob for the jump tables.
For x86_64 only for now, arm coming up.
master
Michael Matz 2014-04-06 00:30:22 +02:00
parent c4427747e6
commit 9750d0b725
3 changed files with 24 additions and 17 deletions

3
tcc.h
View File

@ -712,7 +712,7 @@ struct TCCState {
void *write_mem;
unsigned long mem_size;
# endif
# if !defined TCC_TARGET_PE && (defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM)
# if !defined TCC_TARGET_PE && (defined TCC_TARGET_ARM)
/* write PLT and GOT here */
char *runtime_plt_and_got;
unsigned runtime_plt_and_got_offset;
@ -1265,6 +1265,7 @@ ST_FUNC void put_stabd(int type, int other, int desc);
ST_FUNC void relocate_common_syms(void);
ST_FUNC void relocate_syms(TCCState *s1, int do_resolve);
ST_FUNC void relocate_section(TCCState *s1, Section *s);
ST_FUNC void relocate_plt(TCCState *s1);
ST_FUNC void tcc_add_linker_symbols(TCCState *s1);
ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset);

View File

@ -851,8 +851,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
/* We've put the PLT slot offset into r_addend when generating
it, and that's what we must use as relocation value (adjusted
by section offset of course). */
if (s1->output_type != TCC_OUTPUT_MEMORY)
val = s1->plt->sh_addr + rel->r_addend;
val = s1->plt->sh_addr + rel->r_addend;
/* fallthrough. */
plt32pc32:
@ -878,7 +877,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
case R_X86_64_GLOB_DAT:
case R_X86_64_JUMP_SLOT:
/* They don't need addend */
*(int *)ptr = val - rel->r_addend;
*(addr_t *)ptr = val - rel->r_addend;
break;
case R_X86_64_GOTPCREL:
#ifdef TCC_HAS_RUNTIME_PLTGOT
@ -1042,7 +1041,7 @@ static unsigned long put_got_entry(TCCState *s1,
if (!s1->got)
build_got(s1);
need_plt_entry = s1->dynsym &&
need_plt_entry =
#ifdef TCC_TARGET_X86_64
(reloc_type == R_X86_64_JUMP_SLOT);
#elif defined(TCC_TARGET_I386)
@ -1053,6 +1052,13 @@ static unsigned long put_got_entry(TCCState *s1,
0;
#endif
if (need_plt_entry && !s1->plt) {
/* add PLT */
s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
SHF_ALLOC | SHF_EXECINSTR);
s1->plt->sh_entsize = 4;
}
/* If a got/plt entry already exists for that symbol, no need to add one */
if (sym_index < s1->nb_sym_attrs) {
if (need_plt_entry && s1->sym_attrs[sym_index].plt_offset)
@ -1067,10 +1073,9 @@ static unsigned long put_got_entry(TCCState *s1,
if (!need_plt_entry)
symattr->got_offset = s1->got->data_offset;
if (s1->dynsym) {
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
name = (char *) symtab_section->link->data + sym->st_name;
offset = sym->st_value;
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
name = (char *) symtab_section->link->data + sym->st_name;
offset = sym->st_value;
#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
if (need_plt_entry) {
Section *plt;
@ -1165,10 +1170,13 @@ static unsigned long put_got_entry(TCCState *s1,
offset = plt->data_offset - 16;
}
#elif defined(TCC_TARGET_C67)
if (s1->dynsym) {
tcc_error("C67 got not implemented");
}
#else
#error unsupported CPU
#endif
if (s1->dynsym) {
/* XXX This might generate multiple syms for name. */
index = put_elf_sym(s1->dynsym, offset,
size, info, 0, sym->st_shndx, name);
@ -1316,8 +1324,7 @@ ST_FUNC void build_got_entries(TCCState *s1)
reloc_type = R_X86_64_JUMP_SLOT;
ofs = put_got_entry(s1, reloc_type, sym->st_size,
sym->st_info, sym_index);
if (type == R_X86_64_PLT32
&& s1->output_type != TCC_OUTPUT_MEMORY)
if (type == R_X86_64_PLT32)
/* We store the place of the generated PLT slot
in our addend. */
rel->r_addend += ofs;
@ -1754,10 +1761,13 @@ static void export_global_syms(TCCState *s1)
/* relocate the PLT: compute addresses and offsets in the PLT now that final
address for PLT and GOT are known (see fill_program_header) */
static void relocate_plt(TCCState *s1)
ST_FUNC void relocate_plt(TCCState *s1)
{
uint8_t *p, *p_end;
if (!s1->plt)
return;
p = s1->plt->data;
p_end = p + s1->plt->data_offset;
if (p < p_end) {
@ -2346,11 +2356,6 @@ static int elf_output_file(TCCState *s1, const char *filename)
dynamic->link = dynstr;
dynamic->sh_entsize = sizeof(ElfW(Dyn));
/* add PLT */
s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
SHF_ALLOC | SHF_EXECINSTR);
s1->plt->sh_entsize = 4;
build_got(s1);
if (file_type == TCC_OUTPUT_EXE) {

View File

@ -197,6 +197,7 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr)
if (s->reloc)
relocate_section(s1, s);
}
relocate_plt(s1);
for(i = 1; i < s1->nb_sections; i++) {
s = s1->sections[i];