Bug 2729 - ld terminated with signal 11 [Segmentation fault]
Summary: ld terminated with signal 11 [Segmentation fault]
Status: NEW
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.19
: P2 normal
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-06-06 17:12 UTC by Martin Koeppe
Modified: 2020-01-31 02:24 UTC (History)
4 users (show)

See Also:
Host: i686-pc-linux-gnu
Target: i586-pc-interix3
Build: i686-pc-linux-gnu
Last reconfirmed:


Attachments
object file that fails linking (189 bytes, application/octet-stream)
2006-06-08 19:37 UTC, Martin Koeppe
Details
Cope with missing .idata sections when building DataDictionary (397 bytes, patch)
2006-06-22 17:43 UTC, Nick Clifton
Details | Diff
Real version of previous patch (1.10 KB, patch)
2006-06-23 14:30 UTC, Nick Clifton
Details | Diff
cref table from working interix ld (2.55 KB, text/plain)
2006-06-24 01:31 UTC, Martin Koeppe
Details
cref table from failing cross ld (2.57 KB, text/plain)
2006-06-24 01:32 UTC, Martin Koeppe
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Koeppe 2006-06-06 17:12:00 UTC
Hello,

I tried to build a cross compiler on linux to build tools for interix 3.5.
I managed to build such a compiler and linker, and the compiler seems to work
fine, but the linker doesn't.

Linux platform is Debian etch, kernel 2.6.11, gcc-4.0.

I used binutils 2.16.91 20060413 (currently ships with debian etch) and
configured with
--target=i586-pc-interix3 --with-gnu-as --with-gnu-ld

For cross-gcc, I used gcc-4.1.0 and configured with
--target=i586-pc-interix3 --enable-languages=c --enable-threads=no
--disable-shared --with-stabs --enable-nls --disable-libssp --with-gnu-as
--with-gnu-ld

I tried the following short program:
int main()
{
    return 3;
}

and got:
$ i586-pc-interix3-gcc -c hello.c
so compiling is ok, but ...

$ i586-pc-interix3-gcc hello.o
collect2: ld terminated with signal 11 [Segmentation fault]
/usr/local/lib/gcc/i586-pc-interix3/4.1.0/libgcc.a(__main.o): In function
`__do_global_ctors':
/srv/src/gcc-4.1/build2/gcc/../../src/gcc/libgcc2.c:1956: undefined reference to
`_atexit'
/usr/local/lib/gcc/i586-pc-interix3/4.1.0/../../../../i586-pc-interix3/lib/libpsxdll.a(PSXDLL.dll.a):(.idata$2+0x0):
undefined reference to `.idata$4'

... linking segfaults.

(The .../lib/libpsxdll.a and all other libs I copied over from an interix 3.5
installation's /usr/lib/* to /usr/local/i586-pc-interix3/lib/*.)

(The only binutils bug related to interix I could find is Bug 324, but it is old
and marked resolved.)
Comment 1 Nick Clifton 2006-06-08 10:16:52 UTC
Hi,

  Please could you provide us with the files necessary to reproduce this bug ? 
(ie: main.o, crt0.o etc and the libraries).  Also, please could you run gcc with
the -v switch and tell us the precise command line that gcc is using to invoke
the linker.

Cheers
  Nick
Comment 2 Martin Koeppe 2006-06-08 19:37:38 UTC
Created attachment 1066 [details]
object file that fails linking

ok, here is my object file from this tiny program:
int main() { return 3; }

The gcc link command with -v shows:
$ LANG=C i586-pc-interix3-gcc -v  hello.o
Using built-in specs.
Target: i586-pc-interix3
Configured with: ../src/configure --target=i586-pc-interix3
--enable-languages=c --enable-threads=no --disable-shared --with-stabs
--enable-nls --disable-libssp --with-gnu-as --with-gnu-ld
Thread model: single
gcc version 4.1.0
 /usr/local/libexec/gcc/i586-pc-interix3/4.1.0/collect2 -stack 0x400000,0x10000
-subsystem posix
/usr/local/lib/gcc/i586-pc-interix3/4.1.0/../../../../i586-pc-interix3/lib/crt0.o
-L/usr/local/lib/gcc/i586-pc-interix3/4.1.0
-L/usr/local/lib/gcc/i586-pc-interix3/4.1.0/../../../../i586-pc-interix3/lib
hello.o -lgcc -lc -lpsxdll -lc -lpsxdll -v -lgcc
collect2 version 4.1.0 (i386 Interix)
/usr/local/lib/gcc/i586-pc-interix3/4.1.0/../../../../i586-pc-interix3/bin/ld
-stack 0x400000,0x10000 -subsystem posix
/usr/local/lib/gcc/i586-pc-interix3/4.1.0/../../../../i586-pc-interix3/lib/crt0.o
-L/usr/local/lib/gcc/i586-pc-interix3/4.1.0
-L/usr/local/lib/gcc/i586-pc-interix3/4.1.0/../../../../i586-pc-interix3/lib
hello.o -lgcc -lc -lpsxdll -lc -lpsxdll -v -lgcc
collect2: ld terminated with signal 11 [Segmentation fault]
/usr/local/lib/gcc/i586-pc-interix3/4.1.0/libgcc.a(__main.o): In function
`__do_global_ctors':
/srv/src/gcc-4.1/build2/gcc/../../src/gcc/libgcc2.c:1956: undefined reference
to `_atexit'
/usr/local/lib/gcc/i586-pc-interix3/4.1.0/../../../../i586-pc-interix3/lib/libpsxdll.a(PSXDLL.dll.a):(.idata$2+0x0):
undefined reference to `.idata$4'
Comment 3 Martin Koeppe 2006-06-08 19:53:49 UTC
The libraries I copied from the self extracting archive
SFU35SEL_EN.exe which can be obtained from here (you need a MS passport account):
http://www.microsoft.com/downloads/details.aspx?FamilyID=896c9688-601b-44f1-81a4-02878ff11778&DisplayLang=en

From this archive I copied
BaseUtils/usr/lib/*  and  SDK/usr/lib/*  to
/usr/local/i586-pc-interix3/lib
(You need to make the symlinks manually, symlinks in the sfx archive
are shown as small regular files)

There is a new interix version (5.2) included in W2K3R2.
The tools for that can be obtained from here (no passport needed):
http://www.microsoft.com/downloads/details.aspx?FamilyID=8b4987e6-d960-49a2-bf52-d3fbd654254c&DisplayLang=en
Utilities and SDK for UNIX-based Applications_X86.exe

With these files, ld segfaults nevertheless.
Comment 4 Nick Clifton 2006-06-22 17:42:23 UTC
Hi Martin,

  Thanks for the test case.

  I can now reproduce the problem and I am uploading a patch which will prevent
the seg fault.  As it stands however the patch will still prevent the linker
from completing successfully.  I think that this is the right thing to do, since
the DataDictionary has not been fully constructed.  Please could you try out the
patch and let me know if you have any problems with it.

  The problem is the missing .idata$4 section.  It is needed (and the unpatched
linker was assuming that it was always there).  I am not sure why it is missing
though, and it may not be important.  If you want to, try changing the "result =
FALSE" statements in the patch to "result = TRUE" and see if the resulting
linked executable actually works.

Cheers
  Nick
Comment 5 Nick Clifton 2006-06-22 17:43:47 UTC
Created attachment 1112 [details]
Cope with missing .idata sections when building DataDictionary
Comment 6 Martin Koeppe 2006-06-22 22:08:25 UTC
Hi Nick,

(In reply to comment #5)
> Created an attachment (id=1112)
> Cope with missing .idata sections when building DataDictionary

is this the complete patch? It does apply and build,
but ld segfaults nevertheless. :-(
 
(In reply to comment #4)

> If you want to, try changing the "result =
> FALSE" statements in the patch to "result = TRUE" and see if the resulting
> linked executable actually works.

Where do I find these statements?

Martin
Comment 7 Nick Clifton 2006-06-23 14:30:51 UTC
Created attachment 1116 [details]
Real version of previous patch
Comment 8 Nick Clifton 2006-06-23 14:31:46 UTC
Subject: Re:  ld terminated with signal 11 [Segmentation fault]

Hi Martin,

>> Cope with missing .idata sections when building DataDictionary
> 
> is this the complete patch?

No.  Bum.  I sent you the wrong one.  Sorry about that.  I have uploaded 
the proper version this time.

Cheers
   Nick





Comment 9 Martin Koeppe 2006-06-24 01:29:13 UTC
Hi Nick,

thank you very much. Now it does apply and build, and the segfault is away.
Unfortunately, linking is not yet successful, even with result=TRUE, due to
missing symbols, namely ".idata$4" and "atexit".

I now linked exactly the same files (besides libgcc.a) with --cref, once on
original interix with their version of gnu ld, where linking succeeds, and once
with my cross compiled ld, and produced 2 cref tables. There is a difference
just at these 2 symbols. Could you please have a look?

Martin
Comment 10 Martin Koeppe 2006-06-24 01:31:09 UTC
Created attachment 1119 [details]
cref table from working interix ld
Comment 11 Martin Koeppe 2006-06-24 01:32:08 UTC
Created attachment 1120 [details]
cref table from failing cross ld
Comment 12 Nick Clifton 2006-07-24 16:48:57 UTC
Hi Martin,

  Sorry for the long delay in responding - work has been really hectic recently.

  Anyway, I am glad that the patch is workign for you as well.  I will check it
in to the sources so that it does not get lost.

  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 ?

  Cheers
  Nick
Comment 13 Martin Koeppe 2006-07-24 21:34:10 UTC
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;


##########################################################################


Comment 14 Nick Clifton 2006-08-08 13:57:17 UTC
Subject: Re:  ld terminated with signal 11 [Segmentation fault]

Hi Martin,

> 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.

No thanks - I do not want to become contaminated. :-)

Unless the author(s) of the patch submits it (or allows someone to 
submit it on their behalf) we cannot accept it into the binutils 
sources.  Further the author(s) will also need have to assigned the 
copyright of the patch to the FSF before it can be accepted.

Mind you, it would be very nice if the patch was officially and properly 
submitted.

Cheers
   Nick
Comment 15 Martin Koeppe 2006-09-07 21:44:33 UTC
(In reply to comment #14)

Hi Nick,

the following text is from the README file in the patch dir.
So MS seems to be willing to have these patches included.
The copyright issue is still open, of course...

Martin

gcc.tgz/gcc-source/queued/README:
[...]
Reminder: all the code herein, and the sources that these apply
to, are subject to the GPL.  You should understand the obligations
it creates for you.  The patches herein have had the appropriate
releases signed and accepted by the FSF for them, and could be
included in the official gcc trees over time.  It is our hope that
that does happen.  Of course, consistent with the GPL, no warranty
of any form is expressed or implied.  Microsoft provides no support
for these instructions, the patches, or the binaries and is not
responsible for errors or omissions in them.

Ada Core Technologies (www.gnatpro.com) has assisted Microsoft in
the development of the Interix version of GCC and in proposing the
patches for inclusion into the FSF GCC source tree.
[...]
Comment 16 Brandon M. Petty 2009-07-15 19:09:39 UTC
I am getting this same error:
collect2: ld terminated with signal 11 [Segmentation fault]

My system information:
Red Hat Enterprise Linux ES release 4 (Nahant Update 4)
Linux 2.6.9-42.0.10.ELsmp
g++ (GCC) 4.2.3
GNU ld (GNU Binutils) 2.19.1

I downloaded the latest version of binutils, 2.19.1, and started receiving this
error.

I am a commercial developer and can not provide any source/object files.
I will see if I can reproduce this on a simpler project and send it.

I take it there is a patch... but it has never been merged into binutils?  If
so... is Waiting the correct status for it?