mirror of
https://github.com/frida/tinycc
synced 2025-01-11 14:19:19 +03:00
fill got table for static linking
This commit is contained in:
parent
b9aeac0a64
commit
d63ec6f20d
9
libtcc.c
9
libtcc.c
@ -372,6 +372,15 @@ ST_FUNC void *section_ptr_add(Section *sec, unsigned long size)
|
||||
return sec->data + offset;
|
||||
}
|
||||
|
||||
/* reserve at least 'size' bytes from section start */
|
||||
ST_FUNC void section_reserve(Section *sec, unsigned long size)
|
||||
{
|
||||
if (size > sec->data_allocated)
|
||||
section_realloc(sec, size);
|
||||
if (size > sec->data_offset)
|
||||
sec->data_offset = size;
|
||||
}
|
||||
|
||||
/* return a reference to a section, and create it if it does not
|
||||
exists */
|
||||
ST_FUNC Section *find_section(TCCState *s1, const char *name)
|
||||
|
1
tcc.h
1
tcc.h
@ -900,6 +900,7 @@ ST_FUNC void add_char(CString *cstr, int c);
|
||||
ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags);
|
||||
ST_FUNC void section_realloc(Section *sec, unsigned long new_size);
|
||||
ST_FUNC void *section_ptr_add(Section *sec, unsigned long size);
|
||||
ST_FUNC void section_reserve(Section *sec, unsigned long size);
|
||||
ST_FUNC Section *find_section(TCCState *s1, const char *name);
|
||||
|
||||
ST_FUNC void put_extern_sym2(Sym *sym, Section *section, unsigned long value, unsigned long size, int can_add_underscore);
|
||||
|
44
tccelf.c
44
tccelf.c
@ -1365,6 +1365,48 @@ void patch_dynsym_undef(TCCState *s1, Section *s)
|
||||
#define EXTRA_RELITEMS 9
|
||||
#endif
|
||||
|
||||
ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
|
||||
{
|
||||
int sym_index = ELFW(R_SYM) (rel->r_info);
|
||||
ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
|
||||
unsigned long offset;
|
||||
|
||||
if (sym_index >= s1->nb_got_offsets)
|
||||
return;
|
||||
offset = s1->got_offsets[sym_index];
|
||||
section_reserve(s1->got, offset + PTR_SIZE);
|
||||
/* only works for x86-64 */
|
||||
put32(s1->got->data + offset, sym->st_value >> 32);
|
||||
put32(s1->got->data + offset, sym->st_value & 0xffffffff);
|
||||
}
|
||||
|
||||
ST_FUNC void fill_got(TCCState *s1)
|
||||
{
|
||||
Section *s;
|
||||
ElfW_Rel *rel, *rel_end;
|
||||
int i;
|
||||
|
||||
for(i = 1; i < s1->nb_sections; i++) {
|
||||
s = s1->sections[i];
|
||||
if (s->sh_type != SHT_RELX)
|
||||
continue;
|
||||
/* no need to handle got relocations */
|
||||
if (s->link != symtab_section)
|
||||
continue;
|
||||
rel_end = (ElfW_Rel *) (s->data + s->data_offset);
|
||||
for(rel = (ElfW_Rel *) s->data; rel < rel_end; rel++) {
|
||||
switch (ELFW(R_TYPE) (rel->r_info)) {
|
||||
case R_X86_64_GOT32:
|
||||
case R_X86_64_GOTPCREL:
|
||||
case R_X86_64_PLT32:
|
||||
fill_got_entry(s1, rel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* output an ELF file */
|
||||
/* XXX: suppress unneeded sections */
|
||||
static int elf_output_file(TCCState *s1, const char *filename)
|
||||
@ -1985,6 +2027,8 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
||||
else
|
||||
ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
|
||||
}
|
||||
if (file_type == TCC_OUTPUT_EXE && s1->static_link)
|
||||
fill_got(s1);
|
||||
|
||||
/* write elf file */
|
||||
if (file_type == TCC_OUTPUT_OBJ)
|
||||
|
Loading…
Reference in New Issue
Block a user