mirror of
https://github.com/frida/tinycc
synced 2024-12-25 06:26: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_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_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_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_REL32, 0, AUTO_GOTPLT_ENTRY, 0)
|
||||||
INIT_RELOC_INFO (R_ARM_GOTPC, 0, BUILD_GOT_ONLY, 0)
|
INIT_RELOC_INFO (R_ARM_GOTPC, 0, BUILD_GOT_ONLY, 0)
|
||||||
INIT_RELOC_INFO (R_ARM_GOTOFF, 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
|
in s1->symtab. When creating the dynamic symbol table entry for the GOT
|
||||||
relocation, use 'size' and 'info' for the corresponding symbol metadata.
|
relocation, use 'size' and 'info' for the corresponding symbol metadata.
|
||||||
Returns the offset of the GOT or (if any) PLT entry. */
|
Returns the offset of the GOT or (if any) PLT entry. */
|
||||||
static unsigned long put_got_entry(TCCState *s1,
|
static unsigned long put_got_entry(TCCState *s1, int dyn_reloc_type,
|
||||||
int reloc_type, unsigned long size, int info,
|
int reloc_type, unsigned long size,
|
||||||
int sym_index)
|
int info, int sym_index)
|
||||||
{
|
{
|
||||||
int index, need_plt_entry = 0;
|
int index, need_plt_entry = 0;
|
||||||
const char *name;
|
const char *name;
|
||||||
ElfW(Sym) *sym;
|
ElfW(Sym) *sym, *esym;
|
||||||
unsigned long offset;
|
unsigned long offset;
|
||||||
int *ptr;
|
int *ptr;
|
||||||
size_t got_offset;
|
size_t got_offset;
|
||||||
struct sym_attr *symattr;
|
struct sym_attr *symattr;
|
||||||
|
|
||||||
need_plt_entry = (reloc_type == R_JMP_SLOT);
|
need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
|
||||||
|
|
||||||
if (!s1->got)
|
if (!s1->got)
|
||||||
build_got(s1);
|
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
|
/* create the dynamic symbol table entry that the relocation refers to
|
||||||
in its r_info field to identify the symbol */
|
in its r_info field to identify the symbol */
|
||||||
/* XXX This might generate multiple syms for name. */
|
/* XXX This might generate multiple syms for name. */
|
||||||
index = put_elf_sym(s1->dynsym, offset, size, info, 0, sym->st_shndx,
|
index = find_elf_sym (s1->dynsym, name);
|
||||||
name);
|
if (index) {
|
||||||
put_elf_reloc(s1->dynsym, s1->got, got_offset, reloc_type, index);
|
esym = (ElfW(Sym) *) s1->dynsym->data + index;
|
||||||
} else {
|
esym->st_value = offset;
|
||||||
put_elf_reloc(symtab_section, s1->got, got_offset, reloc_type,
|
|
||||||
|
} 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);
|
sym_index);
|
||||||
}
|
|
||||||
|
|
||||||
if (need_plt_entry)
|
if (need_plt_entry)
|
||||||
return symattr->plt_offset;
|
return symattr->plt_offset;
|
||||||
@ -1067,8 +1073,8 @@ ST_FUNC void build_got_entries(TCCState *s1)
|
|||||||
reloc_type = R_JMP_SLOT;
|
reloc_type = R_JMP_SLOT;
|
||||||
else
|
else
|
||||||
reloc_type = R_GLOB_DAT;
|
reloc_type = R_GLOB_DAT;
|
||||||
ofs = put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
|
ofs = put_got_entry(s1, reloc_type, type, sym->st_size,
|
||||||
sym_index);
|
sym->st_info, sym_index);
|
||||||
|
|
||||||
#ifdef DEBUG_RELOC
|
#ifdef DEBUG_RELOC
|
||||||
printf ("maybegot: %s, %d, %d --> ofs=0x%x\n",
|
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
|
* of the function wanted by the caller of dlsym instead of
|
||||||
* the address of the function that would return that
|
* the address of the function that would return that
|
||||||
* address */
|
* address */
|
||||||
put_got_entry(s1, R_JMP_SLOT, esym->st_size,
|
put_elf_sym(s1->dynsym, 0, esym->st_size,
|
||||||
ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC),
|
ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
|
||||||
sym - (ElfW(Sym) *)symtab_section->data);
|
name);
|
||||||
} else if (type == STT_OBJECT) {
|
} else if (type == STT_OBJECT) {
|
||||||
unsigned long offset;
|
unsigned long offset;
|
||||||
ElfW(Sym) *dynsym;
|
ElfW(Sym) *dynsym;
|
||||||
offset = bss_section->data_offset;
|
offset = bss_section->data_offset;
|
||||||
/* XXX: which alignment ? */
|
/* XXX: which alignment ? */
|
||||||
offset = (offset + 16 - 1) & -16;
|
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,
|
index = put_elf_sym(s1->dynsym, offset, esym->st_size,
|
||||||
esym->st_info, 0, bss_section->sh_num,
|
esym->st_info, 0, bss_section->sh_num,
|
||||||
name);
|
name);
|
||||||
|
Loading…
Reference in New Issue
Block a user