[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