diff options
| author | Michael Matz <matz@suse.de> | 2017-11-27 04:03:03 +0100 |
|---|---|---|
| committer | Michael Matz <matz@suse.de> | 2017-11-27 04:59:29 +0100 |
| commit | 9e0d23cc47359149a39eafffdbb133963980b6ed (patch) | |
| tree | 84ca4bd202768b2c71d3ed4f09abcd3e1a729e7d /tccelf.c | |
| parent | 3494e5de3a03d021845666f55340d35af44e3bfc (diff) | |
| download | tinycc-9e0d23cc47359149a39eafffdbb133963980b6ed.tar.gz tinycc-9e0d23cc47359149a39eafffdbb133963980b6ed.tar.bz2 | |
tccasm: Unify C and asm symbol table
This makes the asm symbols use the same members as the C symbols
for global decls, e.g. using the ELF symbol to hold offset and
section. That allows us to use only one symbol table for C and
asm symbols and to get rid of hacks to synch between them.
We still need some special handling for symbols that come purely
from asm sources.
Diffstat (limited to 'tccelf.c')
| -rw-r--r-- | tccelf.c | 12 |
1 files changed, 9 insertions, 3 deletions
@@ -310,7 +310,8 @@ static void rebuild_hash(Section *s, unsigned int nb_buckets) sym = (ElfW(Sym) *)s->data + 1; for(sym_index = 1; sym_index < nb_syms; sym_index++) { - if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { + if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL + || sym->st_shndx == SHN_UNDEF) { h = elf_hash(strtab + sym->st_name) % nb_buckets; *ptr = hash[h]; hash[h] = sym_index; @@ -349,8 +350,9 @@ ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, int *ptr, *base; ptr = section_ptr_add(hs, sizeof(int)); base = (int *)hs->data; - /* only add global or weak symbols */ - if (ELFW(ST_BIND)(info) != STB_LOCAL) { + /* only add global, weak or undef symbols. The latter might + become global late (from asm references). */ + if (ELFW(ST_BIND)(info) != STB_LOCAL || shndx == SHN_UNDEF) { /* add another hashing entry */ nbuckets = base[0]; h = elf_hash((unsigned char *) name) % nbuckets; @@ -486,6 +488,10 @@ ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size, /* data symbol keeps precedence over common/bss */ } else if (s == tcc_state->dynsymtab_section) { /* we accept that two DLL define the same symbol */ + } else if (esym->st_other & ST_ASM_SET) { + /* If the existing symbol came from an asm .set + we can override. */ + goto do_patch; } else { #if 0 printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n", |
