Bug #1736


ld segfaults on sparc during python26 build

Added by Yuri Pankov over 11 years ago. Updated about 2 months ago.

cmd - userland programs
Start date:
Due date:
% Done:


Estimated time:
Gerrit CR:
External Bug:


building 'cStringIO' extension
/opt/SUNWspro/sunstudio12.1/bin/cc -m32 -xO4 -xtarget=ultra2 -xarch=sparcvis -xchip=ultra2 -xregs=no%appl,float -W2,-xwrap_int -xmemalign=8s -mt -G build/temp.solaris-2.11-sun4u-2.6/home/yuri/oi-build/components/python/python26/Python-2.6.4/Modules/cStringIO.o -L. -lpython2.6 -o build/lib.solaris-2.11-sun4u-2.6/
cc: Fatal error in /usr/ccs/bin/ld
cc: Status 139

To reproduce:

/usr/bin/env LD_OPTIONS="-M /usr/lib/ld/map.noexstk -M /usr/lib/ld/map.noexbss -M /usr/lib/ld/map.pagealign -Bdirect -z ignore"  DFLAGS="-32" /opt/SUNWspro/sunstudio12.1/bin/cc -m32 -xO4 -xtarget=ultra2 -xarch=sparcvis -xchip=ultra2 -xregs=no%appl,float -W2,-xwrap_int -xmemalign=8s -mt -G cStringIO.o -L. -lpython2.6 -o


cStringIO.o (20.6 KB) cStringIO.o Yuri Pankov, 2011-11-06 01:30 AM (802 KB) Yuri Pankov, 2011-11-06 01:30 AM
core.bz2 (3.04 MB) core.bz2 Yuri Pankov, 2011-11-06 01:30 AM

Related issues

Related to illumos gate - Bug #6360: ld core dump with gcc48 bootstrapNew2015-10-19

Actions #1

Updated by Rich Lowe over 11 years ago

  • Assignee set to Rich Lowe
  • Tags deleted (needs-triage)

Yuri discovered that this problem is triggered by the use of the noexbss mapfile, more specifically it's another bug triggered by the presence of a separate BSS segment (the stock bssalign mapfile will also cause this problem).

A workaround is to avoid the use of mapfiles which don't cause the creation of a separate segment for BSS.

Actions #2

Updated by Rich Lowe over 11 years ago

  • Status changed from New to In Progress
  • % Done changed from 0 to 70

This is, likely, not an actually SPARC specific problem in general, but SPARC specific in that the SPARC compiler is what created these specific input objects.

The problem is that we are using a mapfile, map.noexbss which requests the creation of a BSS segment, to which input bss, tbss, etc will be assigned. However, our input object contains no uninitialized globals, nor uninitialized COMMON symbols, and so has no BSS. Since we were asked to create the segment, we did, and we're left with a segment of 0 size, containing no sections.

Now, if this BSS segment is the last loadable segment we use it to locate the _end symbol, attempting to do so relative to its final section. This makes no attempt to validate the number of sections in the segment, and underflows apl_nitems (the number of elements in the section list), walking considerably past the end of the output section list. In Yuri's case, this appeared to hit a '0', such that we crashed when dereferencing the NULL output section descriptor

             * If we're dealing with a memory reservation there are
             * no sections to establish an index for _end, so assign
             * it as an absolute.
            if (sgp->sg_osdescs != NULL) {
                 * Determine the last section for this segment.
                Os_desc    *osp = sgp->sg_osdescs->apl_data
                    [sgp->sg_osdescs->apl_nitems - 1];

                /* LINTED */
                end_ndx = elf_ndxscn(osp->os_scn);
            } else {
                end_ndx = SHN_ABS;
                end_abs = 1;
> $C
ffffffff7fffe471`update_osym+0xbdc(7fefe4008a8, d, 20000, 20000, 
20000, 7fefe405938)
ffffffff7fffe881`ld32_update_outfile+0xe40(7fefe400020, 7fefda06efc, 
7fefe400f40, 1, 40, d)
ffffffff7fffe9f1`ld32_main+0x764(7fefe400020, ffffffff, 10000000, 
7fefe400020, 7feff4ae110, 80008000)
ffffffff7fffeab1 main+0x140(100000, ffffffff7ffff438, 1b, 100002000, 100002, 
ffffffff7fffeb81 _start+0x17c(0, 0, 0, 0, 0, 0)

> update_osym+0xbdc::dis`update_osym+0xbcc:   sllx      %g1, 0x3, %o4`update_osym+0xbd0:   add       %i5, %o4, %o3`update_osym+0xbd4:   ldx       [%o3 + 0x10], %l7`update_osym+0xbd8:   
call      +0x157d64     <`elf_ndxscn>`update_osym+0xbdc:   ldx       [%l7 + 0x8], %o0`update_osym+0xbe0:   st        %o0, [%fp + 0x73b]`update_osym+0xbe4:   
ba        +0x54         <`update_osym+0xc38>
> <l7=K                               
> ::offsetof Os_desc os_scn
offsetof (Os_desc, os_scn) = 8, sizeof (...->os_scn) = 8

%l7 is the (NULL) Os_desc, we're trying to dereference the ->os_scn in the delay slot of the elf_ndxscn call, to pass as the argument.

It is debatable what we should do about the empty segment. In general, we would prefer to not have needless loadable segments, since we have to think about them while mapping objects. However, the user has explicitly, via the mapfile, requested that a BSS segment of certain properties exist, pruning it would be directly contrary to that (if likely not problematic).

The fix, thus, is to check not only that the last loadable segment is not NULL (that is, that loadable segments exist), but also that this segment contains at least one section.

Actions #3

Updated by Rich Lowe over 11 years ago

  • % Done changed from 70 to 20

The logic that since a segment was asked for, it should remain, is incorrect.
Partially following on from that, it turns out that this is more complicated than it seems, and that while the simple change works it does so accidentally.

I'll update the bug with more information once I'm more sure of it

Actions #4

Updated by Marcel Telka about 1 year ago

  • Related to Bug #6360: ld core dump with gcc48 bootstrap added
Actions #5

Updated by Rich Lowe about 2 months ago

  • Status changed from In Progress to New
  • Assignee deleted (Rich Lowe)

Also available in: Atom PDF