aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Preud'homme <robotux@celest.fr>2016-11-12 23:16:03 +0800
committerThomas Preud'homme <robotux@celest.fr>2016-12-03 17:26:51 +0000
commite9769a7249444872200c8c1f1a2f2252c498056f (patch)
tree18bb4610f714b0d53e8d8b3723a5ac8b5c52c02d
parentbf692af31b93ca14b63211bd508b4b8bf1179b50 (diff)
downloadtinycc-e9769a7249444872200c8c1f1a2f2252c498056f.tar.gz
tinycc-e9769a7249444872200c8c1f1a2f2252c498056f.tar.bz2
Do not add symbol if it is already there
Do not create a new symbol in add_elf_sym if a symbol with same properties (value, size, info, etc.) already exists. This prevents symbols from being exported twice in the dynamic symbol table.
-rw-r--r--tccelf.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/tccelf.c b/tccelf.c
index 9b019a2..d7015c0 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -394,12 +394,17 @@ ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size,
sym_type = ELFW(ST_TYPE)(info);
sym_vis = ELFW(ST_VISIBILITY)(other);
+ sym_index = find_elf_sym(s, name);
+ esym = &((ElfW(Sym) *)s->data)[sym_index];
+ if (sym_index && esym->st_value == value && esym->st_size == size
+ && esym->st_info == info && esym->st_other == other
+ && esym->st_shndx == sh_num)
+ return sym_index;
+
if (sym_bind != STB_LOCAL) {
/* we search global or weak symbols */
- sym_index = find_elf_sym(s, name);
if (!sym_index)
goto do_def;
- esym = &((ElfW(Sym) *)s->data)[sym_index];
if (esym->st_shndx != SHN_UNDEF) {
esym_bind = ELFW(ST_BIND)(esym->st_info);
/* propagate the most constraining visibility */
@@ -2058,7 +2063,7 @@ static void bind_exe_dynsyms(TCCState *s1)
} else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
/* if -rdynamic option, then export all non local symbols */
name = (char *) symtab_section->link->data + sym->st_name;
- put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
+ add_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
0, sym->st_shndx, name);
}
}
@@ -2081,7 +2086,7 @@ static void bind_libs_dynsyms(TCCState *s1)
-rdynamic ? */
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
if (sym_index && sym->st_shndx != SHN_UNDEF)
- put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
+ add_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
0, sym->st_shndx, name);
else if (esym->st_shndx == SHN_UNDEF) {
/* weak symbols can stay undefined */