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