aboutsummaryrefslogtreecommitdiff
path: root/tccelf.c
diff options
context:
space:
mode:
authorThomas Preud'homme <robotux@celest.fr>2015-04-18 15:28:02 +0800
committerThomas Preud'homme <robotux@celest.fr>2015-04-18 15:34:04 +0800
commit9336fa7ae50ef60cb0049136a7831e7e8d94a20a (patch)
tree649e8c3af3a4a3c1d582eec258768294b3e3d731 /tccelf.c
parentb472d53672bb8840511cc6d59316c5ea435a396e (diff)
downloadtinycc-9336fa7ae50ef60cb0049136a7831e7e8d94a20a.tar.gz
tinycc-9336fa7ae50ef60cb0049136a7831e7e8d94a20a.tar.bz2
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.
Diffstat (limited to 'tccelf.c')
-rw-r--r--tccelf.c23
1 files 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);
}
}
}