[parisc-linux] call_init in libc6 2.3.6.ds1-11

John David Anglin dave at hiauly1.hia.nrc.ca
Sat Feb 17 12:56:59 MST 2007


I had a segv in /bin/sh today:

Core was generated by `/bin/sh -c echo ../../../gcc/libjava/classpath/lib/java/awt/im/spi/*.class > ja'.
Program terminated with signal 11, Segmentation fault.
#0  0x4073b16c in init () from /lib/libc.so.6
(gdb) bt
#0  0x4073b16c in init () from /lib/libc.so.6
#1  0x400d77e8 in call_init () from /lib/ld.so.1
#2  0x400d77e8 in call_init () from /lib/ld.so.1
Previous frame identical to this frame (corrupt stack?)
(gdb) disass 0x4073b15c 0x4073b17c
Dump of assembler code from 0x4073b15c to 0x4073b17c:
0x4073b15c <_dl_start+12>:      stw r19,-20(sp)
0x4073b160 <_dl_start+16>:      nop
0x4073b164 <init+0>:    stw rp,-14(sp)
0x4073b168 <init+4>:    addil L%1000,r19,r1
0x4073b16c <init+8>:    ldw 450(r1),ret0
0x4073b170 <init+12>:   stw,ma r6,40(sp)
0x4073b174 <init+16>:   copy r24,r6
0x4073b178 <init+20>:   stw r5,-3c(sp)
End of assembler dump.
(gdb) p/x $r1
$1 = 0x40df352f
(gdb) p/x $r19
$2 = 0x40df252f

So, the problem is that r19 is corrupt when init is called.  Looking
at call_init, I see:

0x400d77ac <call_init+176>:     bb,<,n r20,1e,0x400d7884 <call_init+392>
0x400d77b0 <call_init+180>:     cmpib,=,n 0,r21,0x400d77ec <call_init+240>
0x400d77b4 <call_init+184>:     ldw 4(r21),r20
0x400d77b8 <call_init+188>:     ldw 0(r3),ret0
0x400d77bc <call_init+192>:     add,l ret0,r20,r22
0x400d77c0 <call_init+196>:     bb,>=,n r22,1e,0x400d7854 <call_init+344>
0x400d77c4 <call_init+200>:     copy r19,r4
0x400d77c8 <call_init+204>:     fstw fr14,-10(sp)
0x400d77cc <call_init+208>:     ldw -10(sp),r26
0x400d77d0 <call_init+212>:     fstw fr13,-10(sp)
0x400d77d4 <call_init+216>:     ldw -10(sp),r25
0x400d77d8 <call_init+220>:     fstw fr12,-10(sp)
0x400d77dc <call_init+224>:     ldw -10(sp),r24
0x400d77e0 <call_init+228>:     b,l 0x400dedd4 <$$dyncall>,r31
0x400d77e4 <call_init+232>:     copy r31,rp
0x400d77e8 <call_init+236>:     copy r4,r19

The address for the call to init is constructed by the loads at
0x400d77b4 and 0x400d77b8, followed by the add at 0x400d77bc:

gdb) p/x $r3
$8 = 0x400010b0
(gdb) x/x 0x400010b0
0x400010b0:     0x4071c000
(gdb) p/x $r21
$9 = 0x408621dc
(gdb) x/4x 0x408621dc
0x408621dc <.LC2+20>:   0x0000000c      0x0001f164      0x0000001a      0x001441e0
(gdb) p/x 0x4071c000 + 0x0001f164
$12 = 0x4073b164

So, init is being called directly.  This highly suspect for a call
in a shared library ($$dyncall won't setup r19).

I still don't completely understand what's happening here as r4 and
r19 don't appear to be consistent.  Here's the register dump:

Feb 17 11:58:01 localhost kernel: do_page_fault() pid=26501 command='sh' type=15 address=0x40df397f
Feb 17 11:58:01 localhost kernel: vm_start = 0x40868000, vm_end = 0x4086a000
Feb 17 11:58:01 localhost kernel:
Feb 17 11:58:01 localhost kernel:      YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI
Feb 17 11:58:01 localhost kernel: PSW: 00000000000001100000000100001111 Not tainted
Feb 17 11:58:01 localhost kernel: r00-03  000000000006010f 0000000040df352f 00000000400d77eb 00000000400010b0
Feb 17 11:58:01 localhost kernel: r04-07  00000000400f49b8 0000000000000002 0000000000000005 00000000400f5888
Feb 17 11:58:01 localhost kernel: r08-11  00000000400f5874 0000000000032000 0000000000033000 0000000000046ee8
Feb 17 11:58:01 localhost kernel: r12-15  0000000000000001 0000000000032000 0000000000046ee8 0000000000046ee8
Feb 17 11:58:01 localhost kernel: r16-19  0000000000000001 0000000000000000 0000000000046ee8 0000000040df252f
Feb 17 11:58:01 localhost kernel: r20-23  000000004086221c 00000000408621dc 000000004073b164 00000000c030e8bc
Feb 17 11:58:01 localhost kernel: r24-27  00000000c030e8bc 00000000c030e8ac 0000000000000003 00000000000d6d34
Feb 17 11:58:01 localhost kernel: r28-31  0000000040df252f 00000000000000d0 00000000c030ec80 00000000400d77eb
Feb 17 11:58:01 localhost kernel: sr00-03  0000000000e8c800 0000000000e8c800 0000000000000000 0000000000e8c800
Feb 17 11:58:01 localhost kernel: sr04-07  0000000000e8c800 0000000000e8c800 0000000000e8c800 0000000000e8c800

This would appear to have something to do with this define:

/* The test for "addr & 2" below is to accomodate old binaries which
   violated the ELF ABI by pointing DT_INIT and DT_FINI at a function
   descriptor.  */
#define DL_DT_INIT_ADDRESS(map, addr) \
  ((Elf32_Addr)(addr) & 2 ? (addr) : DL_AUTO_FUNCTION_ADDRESS (map, addr))

Dave
- 
J. David Anglin                                  dave.anglin at nrc-cnrc.gc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6602)



More information about the parisc-linux mailing list