Hello Thomas, On Sun, 12 Apr 2015, Thomas Preud'homme wrote:
> I was a bit puzzled because I saw symbols are resolved when a file is > loaded that define them (in tcc_load_object_file). The reason this > doesn't happen here is that the symbol is provided by libc.so.6 and the > function that loads dynamic libraries (tcc_load_dll) only look for > undefined symbols in dynsymtab_section rather than symtab_section. There > might be an obvious reason but I'm not sure why symbols from object > files and libraries are handled differently in terms of name resolution. > Of course relocation happens differently but name resolution should be > the same, shouldn't it? Object files have no dynsym section, only a symtab. Conversely shared objects don't have a symtab (conceptually; in reality they might have one, but then only for debugging purposes); their interface (and that's what is wanted when loading or linking against a shared object) is described by dynsym. It should be (and mostly is) like this in tcc: * symtab_section contains all symbols (defined or undefined) from either .c files or regular .o files (ET_REL) contained on the cmdline * s1->dynsymtab_section contain all symbols (defined or undefined) from all shared objects (ET_DYN) mentioned on the command line (these are collected from their respective .dynsym sections) * s1->dynsym contains the resulting dynamic symbols of the to-be-produced executable or shared library (i.e. that one is built up in several steps during linking) bind_exe_dynsyms is the one converting from symtab_section to .dynsym. After all, all undefined symbols (in symtab) must come from some shared lib (if it came from some .o it would not be undefined in symtab), hence must be recorded somewhere in dynsymtab. But to actually create the import this symbol then must be listed in the executables .dynsym section, and this is what's done in bind_exe_dynsyms (i.e. it resolved undefined symbols to shared libs). Conversely shared libs may also contain undefined symbols. If they are provided by other shared libs the dynamic linker will take care of it. But they may also be provided by the main executable. In order to avoid exporting _all_ global symbols from an executable always, only symbols actually undefined in shared libs and provided by the executable are exported (included as defined in .dynsym). That's the purpose of bind_libs_dynsyms. For creating a shared lib, all global symbols (with default visibility) are exported (included in their .dynsym); that's done by export_global_syms. > But when linking with tcc I get: > > Hello, world! Yes, that's a bug in tcc. The problem is that all .dynsyms from shared libs are load and merged before the symtab of the executable is consulted. Therefore dynsymtab contains a definition for printf (from glibc) and hence bind_libs_dynsyms doesn't see anymore that it was once undefined in one library; it would probably need tweaking in add_elf_sym (if the to-be-added symbol is from shared libs, and should be added into dynsymtab, then UNDEF should prevail, not definedness; alternatively this only when also contained in symtab_section as global). > I also found a possible speed improvement. Currently tcc_load_dll load > dll recursively. Yes, but that's not only a speed change, but a semantic one as well. Basically what tcc implements right now is something in between ld's --copy-dt-needed-entries and its negative; tcc will _search_ for symbols also in referenced DSOs, but won't record a DT_NEEDED tag (this is a useless behaviour). > That should only be necessary for tcc_run but that require changing > bind_libs_dynsyms (which requires changing anyway because of the bug > above). I don't see that. Also undefined references from shared libs should only be satisfied by the executable if they are mentioned directly on the command line I think. Ciao, Michael. _______________________________________________ Tinycc-devel mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/tinycc-devel
