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.
Unified · Split
| @@ -1875,20 +1875,19 @@ static void bind_libs_dynsyms(TCCState *s1) · 1874 unmodified lines | |||
| 1875 | /* now look at unresolved dynamic symbols and export | 1875 | /* now look at unresolved dynamic symbols and export |
| 1876 | corresponding symbol */ | 1876 | corresponding symbol */ |
| 1877 | for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) { | 1877 | for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) { |
| 1878 | if (esym->st_shndx == SHN_UNDEF) { | 1878 | name = (char *) s1->dynsymtab_section->link->data + esym->st_name; |
| 1879 | name = (char *) s1->dynsymtab_section->link->data + esym->st_name; | 1879 | sym_index = find_elf_sym(symtab_section, name); |
| 1880 | sym_index = find_elf_sym(symtab_section, name); | 1880 | if (sym_index) { |
| 1881 | if (sym_index) { | 1881 | /* XXX: avoid adding a symbol if already present because of |
| 1882 | /* XXX: avoid adding a symbol if already present because of | 1882 | -rdynamic ? */ |
| 1883 | -rdynamic ? */ | 1883 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; |
| 1884 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; | 1884 | if (sym->st_shndx != SHN_UNDEF) |
| 1885 | put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, | 1885 | put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, |
| 1886 | sym->st_info, 0, sym->st_shndx, name); | 1886 | sym->st_info, 0, sym->st_shndx, name); |
| 1887 | } else { | 1887 | } else if (esym->st_shndx == SHN_UNDEF) { |
| 1888 | /* weak symbols can stay undefined */ | 1888 | /* weak symbols can stay undefined */ |
| 1889 | if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK) | 1889 | if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK) |
| 1890 | tcc_warning("undefined dynamic symbol '%s'", name); | 1890 | tcc_warning("undefined dynamic symbol '%s'", name); |
| 1891 | } | ||
| 1892 | } | 1891 | } |
| 1893 | } | 1892 | } |
| 1894 | } | 1893 | } |