From 9336fa7ae50ef60cb0049136a7831e7e8d94a20a Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Sat, 18 Apr 2015 15:28:02 +0800 Subject: [PATCH] Fix program symbols exported in dynsym section Prior to this commit TinyCC was exporting symbols defined in programs only when they resolve an undefined symbol of a library. However, the expected behavior (see --export-dynamic in GNU ld manpage) is that all symbols used by libraries and defined by a program should be exported in dynsym section. This is because symbol resolution search first in program and then in libraries, thus allowing program symbol to interpose symbol defined in a library. --- tccelf.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/tccelf.c b/tccelf.c index db81201..552a39f 100644 --- a/tccelf.c +++ b/tccelf.c @@ -1875,20 +1875,19 @@ static void bind_libs_dynsyms(TCCState *s1) /* now look at unresolved dynamic symbols and export corresponding symbol */ for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) { - if (esym->st_shndx == SHN_UNDEF) { - name = (char *) s1->dynsymtab_section->link->data + esym->st_name; - sym_index = find_elf_sym(symtab_section, name); - if (sym_index) { - /* XXX: avoid adding a symbol if already present because of - -rdynamic ? */ - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; + name = (char *) s1->dynsymtab_section->link->data + esym->st_name; + sym_index = find_elf_sym(symtab_section, name); + if (sym_index) { + /* XXX: avoid adding a symbol if already present because of + -rdynamic ? */ + sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; + if (sym->st_shndx != SHN_UNDEF) put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info, 0, sym->st_shndx, name); - } else { - /* weak symbols can stay undefined */ - if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK) - tcc_warning("undefined dynamic symbol '%s'", name); - } + } else if (esym->st_shndx == SHN_UNDEF) { + /* weak symbols can stay undefined */ + if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK) + tcc_warning("undefined dynamic symbol '%s'", name); } } }