------- Additional Comments From mkoeppe at gmx dot de 2006-07-24 21:34 ------- Hi Nick,
> I am intrigued by the absence of the atexit symbol. Looking at the cross > reference files it appears that the Interix linker is obtainign it from a file > called wk_atexit.o. What is this file ? Is it included in the gcc linker's > command line ? Does it contain a weak definition of the atexit symbol ? yes, it is included, i.e. it's part of interix's libc.a. In between, I had a closer look at the problem, and I already had contact with Aaron W. LaFramboise who I think wrote ld's PECOFF weak linkage support. For a working interix ld there is some stuff missing in upstream bfd/ld (not just a few lines of code!), which can be obtained from the MS patches (e.g. weak alias support and shared lib support). I'm not sure why the MS patches didn't go back to upstream in 2002 or 2003. If this was appreciated now, I could help. I wrote to Aaron the text below and am currently waiting for his response. Martin I now had a closer look at my weak symbol linkage problem. First I decoded the symbol table entries for wk_atexit.o, part of libc.a, where the weak symbol "atexit" is, and which fails during link: There is an normal undefined symbol "__atexit" at index 4 in the coff symbol table. Entry 5 is the weak symbol entry "_atexit". Value=0, SectionNumber=0, Type=0, StorageClass=0x69=105= WEAK EXTERNAL, AuxSymbols=1 Entry 6 (i.e. aux entry): Tag index = 4, i.e. "__atexit" Characteristic = 3 = IMAGE_WEAK_EXTERN_SEARCH_ALIAS Currently cofflink.c says it supports only IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY, however. I think the guys at MS applied their patches before you applied your PECOFF stuff, and unfortunately, these patches didn't go back to upstream binutils. In their patches you can read some interesting comments, i.e. that they only support WEAK ALIAS, see below. It seems to me that they have added these WEAK ALIASES to PECOFF in order to be able to emulate the unix weak symbol behaviour. So maybe WEAK ALIAS support should be added to ld officially. And this seems to be compatible with LINK.EXE, too. The full MS patches are available from MS, or, if you want to, I can send them to you. ####################################################### Add support for .alias pseudo for C_NT_WEAK alias symbols. * config/obj-coff.c (obj_coff_weak): change conditional comp. (obj_coff_alias): New function. (op_pseudo_table): add it. diff -drupP --exclude-from=/M/donn/diffs/exclude.files gas.orig/config/obj-coff.c gas/conf ig/obj-coff.c --- gas.orig/config/obj-coff.c Tue Apr 11 13:03:19 2000 +++ gas/config/obj-coff.c Tue Apr 11 14:05:11 2000 @@ -217,12 +217,8 @@ obj_coff_weak (ignore) S_SET_WEAK (symbolP); #endif -#ifdef TE_PE - S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK); -#else S_SET_STORAGE_CLASS (symbolP, C_WEAKEXT); -#endif - + if (c == ',') { input_line_pointer++; @@ -1437,6 +1433,78 @@ obj_coff_section (ignore) demand_empty_rest_of_line (); } +#ifdef TE_PE +/* Parse .alias directives, which is how PE does weak symbols: + An alias defines a "weak" name for an exising symbol; it does + not label an entry point directly. There are 3 types of PE + weak; we only support the alias form (IMAGE_WEAK_EXTERN_SEARCH_ALIAS) + + Syntax: .alias <new weak name>,<old strong name> + + */ + ######################################################### bfd/cofflink.c: + /* PE weak symbols are aliases... we need to get the aliased + real symbol. */ + if (obj_pe(abfd) && sym.n_sclass == C_NT_WEAK) + { + /* It's a PE weak symbol (type IMAGE_WEAK_EXTERN_SEARCH_ALIAS) + That's implemented as an indirect in our parlance. + Find the aux entry, get the referenced symbol, and insert + its name. */ + + int target_idx; + union internal_auxent auxent; + + BFD_ASSERT (sym.n_numaux == 1); + + /* Read in the aux information */ + + bfd_coff_swap_aux_in (abfd, (PTR) (esym + symesz), sym.n_type, + sym.n_sclass, 0, sym.n_numaux, + (PTR) &auxent); + /* From the aux information, get the backing "strong" + local symbol index. */ + target_idx = auxent.x_sym.x_tagndx.l; + + /* Check for IMAGE_WEAK_EXTERN_SEARCH_ALIAS; it's all + we currently support. (See the 3/98 or later PE docs; + there used to be only two types.) */ + BFD_ASSERT (auxent.x_sym.x_misc.x_fsize == 3); + + /* Now that we've caught it... + + For the moment (unless/until proven otherwise) we'll + assume the real symbol is already declared in this + file (possibly as an UNDEF, but it exists). */ + + BFD_ASSERT(target_idx < sym_idx); + ############################################################### Considering "weak alias" type symbols: To make an archive that contains weak alias symbols that work correctly, the weak symbols must (of course) be in the archive symbol table. However, if a file whose sole purpose is to link the weak to the strong reference, the weak symbol will be undefined (in that file). Thus, change archive.c to put weak symbol (definitions, implicitly) into the archive symbol table even for symbols in the undefined section. NOTE: this could be done by adding a new flag bit or combination to make this more visible, but the spirit of ignoring "definedness" is required. * archive.c (_bfd_compute_and_write_armap): Enter weak symbols into archive symbol table. Index: src/bfd/archive.c =================================================================== RCS file: /dev/fs/H/rupp/devel-local-repository/src/bfd/archive.c,v retrieving revision 1.1.1.1 diff -p -c -r1.1.1.1 archive.c *** src/bfd/archive.c 2001/12/23 00:34:27 1.1.1.1 --- src/bfd/archive.c 2001/12/23 03:56:08 *************** _bfd_compute_and_write_armap (arch, elen *** 1909,1919 **** flagword flags = (syms[src_count])->flags; asection *sec = syms[src_count]->section; ! if ((flags & BSF_GLOBAL || ! flags & BSF_WEAK || ! flags & BSF_INDIRECT || ! bfd_is_com_section (sec)) ! && ! bfd_is_und_section (sec)) { bfd_size_type namelen; struct orl *new_map; --- 1909,1925 ---- flagword flags = (syms[src_count])->flags; asection *sec = syms[src_count]->section; ! /* For ordinary simbols, we only want real definitions; ! however, for weak symbols, it may be an indirection ! to a symbol defined in another file, and thus be ! undefined (in the undefined section) here. But ! we need it defined in the archive symbol table so we ! can get the module and resolve the indirection. */ ! if (((flags & BSF_GLOBAL || ! flags & BSF_INDIRECT || ! bfd_is_com_section (sec)) ! && ! bfd_is_und_section (sec)) ! || flags & BSF_WEAK) { bfd_size_type namelen; struct orl *new_map; ########################################################################## -- http://sourceware.org/bugzilla/show_bug.cgi?id=2729 ------- You are receiving this mail because: ------- You are on the CC list for the bug, or are watching someone who is. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils