mirror of
https://github.com/frida/tinycc
synced 2024-12-24 05:56:49 +03:00
Consolidate GOT creation in build_got_entries
Currently GOT/PLT creation happens in two locations depending on whether the GOT/PLT [entry] is required by the symbol or the relocation: - bind_exe_dynsym for relocations to undefined symbol - build_got_entries/put_got_entry for relocations that require a GOT/PLT entry This commit consolidate GOT/PLT creation in build_got_entries by reducing bind_exe_dynsym's job to create a dynamic symbol for undefined symbols. build_got_entries then invoke put_got_entry if the symbol being relocated is undefined or the relocation asks for a PLT or GOT [entry]. put_got_entry is also modified to only export a symbol in the dynamic symbol table when we are in the case of PLT/GOT [entry] required by the relocation (since undefined symbol are already exported by bind_exe_dynsym).
This commit is contained in:
parent
1c811a4d1d
commit
a11b0a67e3
@ -13,7 +13,7 @@ ST_DATA struct reloc_info relocs_info[] = {
|
||||
INIT_RELOC_INFO (R_ARM_THM_MOVT_ABS, 0, AUTO_GOTPLT_ENTRY, 0)
|
||||
INIT_RELOC_INFO (R_ARM_THM_MOVW_ABS_NC, 0, AUTO_GOTPLT_ENTRY, 0)
|
||||
INIT_RELOC_INFO (R_ARM_PREL31, 1, AUTO_GOTPLT_ENTRY, 0)
|
||||
INIT_RELOC_INFO (R_ARM_ABS32, 0, NO_GOTPLT_ENTRY, 0)
|
||||
INIT_RELOC_INFO (R_ARM_ABS32, 0, AUTO_GOTPLT_ENTRY, 0)
|
||||
INIT_RELOC_INFO (R_ARM_REL32, 0, AUTO_GOTPLT_ENTRY, 0)
|
||||
INIT_RELOC_INFO (R_ARM_GOTPC, 0, BUILD_GOT_ONLY, 0)
|
||||
INIT_RELOC_INFO (R_ARM_GOTOFF, 0, BUILD_GOT_ONLY, 0)
|
||||
|
40
tccelf.c
40
tccelf.c
@ -819,19 +819,19 @@ static void build_got(TCCState *s1)
|
||||
in s1->symtab. When creating the dynamic symbol table entry for the GOT
|
||||
relocation, use 'size' and 'info' for the corresponding symbol metadata.
|
||||
Returns the offset of the GOT or (if any) PLT entry. */
|
||||
static unsigned long put_got_entry(TCCState *s1,
|
||||
int reloc_type, unsigned long size, int info,
|
||||
int sym_index)
|
||||
static unsigned long put_got_entry(TCCState *s1, int dyn_reloc_type,
|
||||
int reloc_type, unsigned long size,
|
||||
int info, int sym_index)
|
||||
{
|
||||
int index, need_plt_entry = 0;
|
||||
const char *name;
|
||||
ElfW(Sym) *sym;
|
||||
ElfW(Sym) *sym, *esym;
|
||||
unsigned long offset;
|
||||
int *ptr;
|
||||
size_t got_offset;
|
||||
struct sym_attr *symattr;
|
||||
|
||||
need_plt_entry = (reloc_type == R_JMP_SLOT);
|
||||
need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
|
||||
|
||||
if (!s1->got)
|
||||
build_got(s1);
|
||||
@ -1001,13 +1001,19 @@ static unsigned long put_got_entry(TCCState *s1,
|
||||
/* create the dynamic symbol table entry that the relocation refers to
|
||||
in its r_info field to identify the symbol */
|
||||
/* XXX This might generate multiple syms for name. */
|
||||
index = put_elf_sym(s1->dynsym, offset, size, info, 0, sym->st_shndx,
|
||||
name);
|
||||
put_elf_reloc(s1->dynsym, s1->got, got_offset, reloc_type, index);
|
||||
} else {
|
||||
put_elf_reloc(symtab_section, s1->got, got_offset, reloc_type,
|
||||
index = find_elf_sym (s1->dynsym, name);
|
||||
if (index) {
|
||||
esym = (ElfW(Sym) *) s1->dynsym->data + index;
|
||||
esym->st_value = offset;
|
||||
|
||||
} else if (s1->output_type == TCC_OUTPUT_MEMORY ||
|
||||
relocs_info[reloc_type].gotplt_entry == ALWAYS_GOTPLT_ENTRY)
|
||||
index = put_elf_sym(s1->dynsym, offset, size, info, 0,
|
||||
sym->st_shndx, name);
|
||||
put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type, index);
|
||||
} else
|
||||
put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
|
||||
sym_index);
|
||||
}
|
||||
|
||||
if (need_plt_entry)
|
||||
return symattr->plt_offset;
|
||||
@ -1067,8 +1073,8 @@ ST_FUNC void build_got_entries(TCCState *s1)
|
||||
reloc_type = R_JMP_SLOT;
|
||||
else
|
||||
reloc_type = R_GLOB_DAT;
|
||||
ofs = put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
|
||||
sym_index);
|
||||
ofs = put_got_entry(s1, reloc_type, type, sym->st_size,
|
||||
sym->st_info, sym_index);
|
||||
|
||||
#ifdef DEBUG_RELOC
|
||||
printf ("maybegot: %s, %d, %d --> ofs=0x%x\n",
|
||||
@ -1420,15 +1426,17 @@ static void bind_exe_dynsyms(TCCState *s1)
|
||||
* of the function wanted by the caller of dlsym instead of
|
||||
* the address of the function that would return that
|
||||
* address */
|
||||
put_got_entry(s1, R_JMP_SLOT, esym->st_size,
|
||||
ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC),
|
||||
sym - (ElfW(Sym) *)symtab_section->data);
|
||||
put_elf_sym(s1->dynsym, 0, esym->st_size,
|
||||
ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
|
||||
name);
|
||||
} else if (type == STT_OBJECT) {
|
||||
unsigned long offset;
|
||||
ElfW(Sym) *dynsym;
|
||||
offset = bss_section->data_offset;
|
||||
/* XXX: which alignment ? */
|
||||
offset = (offset + 16 - 1) & -16;
|
||||
set_elf_sym (s1->symtab, offset, esym->st_size,
|
||||
esym->st_info, 0, bss_section->sh_num, name);
|
||||
index = put_elf_sym(s1->dynsym, offset, esym->st_size,
|
||||
esym->st_info, 0, bss_section->sh_num,
|
||||
name);
|
||||
|
Loading…
Reference in New Issue
Block a user