Date: Thu, 12 Jan 2017 00:37:53 -0800 From: Mark Millard <markmi@dsl-only.net> To: Ed Maste <emaste@freebsd.org>, Roman Divacky <rdivacky@vlakno.cz> Cc: FreeBSD Toolchain <freebsd-toolchain@freebsd.org> Subject: Re: /usr/bin/ld.lld on powerpc64: produces a.out for which: ld-elf.so.1: assert failed: /usr/src/libexec/rtld-elf/powerpc64/reloc.c:374 Message-ID: <EF97071B-AE4A-4520-A997-52249B8DAB5A@dsl-only.net> In-Reply-To: <CAPyFy2DG3ucUkxDCwRJ10a-nhC1=YvVrwR7v0dw6LJk=e61nvQ@mail.gmail.com> References: <7139F615-8F18-4EDC-9051-5FFEC0C4057F@dsl-only.net> <CAPyFy2CSmNyUjQcXyq4qUWp_A=Qr81O7fpRbZ5GcfFHFhdSntw@mail.gmail.com> <CF2D86C8-8EEB-4536-8D83-6F8C676EFEF6@dsl-only.net> <20170111194844.GA16135@vlakno.cz> <8242A7B9-7ED3-4861-8209-F3728113D188@dsl-only.net> <20170111210658.GA20265@vlakno.cz> <CAPyFy2DG3ucUkxDCwRJ10a-nhC1=YvVrwR7v0dw6LJk=e61nvQ@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On 2017-Jan-11, at 1:23 PM, Ed Maste <emaste at freebsd.org> wrote: > On 11 January 2017 at 21:06, Roman Divacky <rdivacky at vlakno.cz> = wrote: >> Looks like a progress :) Three questions... >>=20 >> Is the readelf -a reasonable now? >=20 > FYI, I just committed an ELF Tool Chain fix (r311941) so readelf > should display the relocation types properly now. Thanks. I updated to -r311950 to pick this up. >> If you compile with -g, does the >> backtrace make a bit more sense? And finally, can you try to = "nexti/stepi" in gdb from >> _start to see where things go wrong? Possibly doing it both for ld = linked a.out >> and lld linked a.out and compare where things differ. I had compiled with -g. It never gets to main. . . # /usr/local/bin/gdb a.out . . . Reading symbols from a.out...done. (gdb) start Temporary breakpoint 1 at 0x1001045c: file main.c, line 3. Starting program: /root/c_tests/a.out=20 Program received signal SIGSEGV, Segmentation fault. 0x000000001001056c in ?? () Note that the temporary breakpoint is never hit. (gdb) bt #0 0x000000001001056c in ?? () #1 0x00000000100100d8 in ?? () #2 0x00000000500279b0 in ._rtld_start () at = /usr/src/libexec/rtld-elf/powerpc64/rtld_start.S:104 Backtrace stopped: frame did not save the PC (gdb) up 2 #2 0x00000000500279b0 in ._rtld_start () at = /usr/src/libexec/rtld-elf/powerpc64/rtld_start.S:104 104 blrl /* _start(argc, argv, envp, obj, cleanup, = ps_strings) */ (gdb) disass Dump of assembler code for function ._rtld_start: 0x0000000050027930 <+0>: stdu r1,-144(r1) 0x0000000050027934 <+4>: std r3,96(r1) 0x0000000050027938 <+8>: std r4,104(r1) 0x000000005002793c <+12>: std r5,112(r1) 0x0000000050027940 <+16>: std r8,136(r1) 0x0000000050027944 <+20>: bl 0x50027950 <._rtld_start+32> 0x0000000050027948 <+24>: .long 0x0 0x000000005002794c <+28>: .long 0x30e40 0x0000000050027950 <+32>: mflr r3 0x0000000050027954 <+36>: ld r4,0(r3) 0x0000000050027958 <+40>: add r3,r4,r3 0x000000005002795c <+44>: ld r4,-32768(r2) 0x0000000050027960 <+48>: subf r4,r4,r2 0x0000000050027964 <+52>: bl 0x50027c64 <reloc_non_plt_self> 0x0000000050027968 <+56>: nop 0x000000005002796c <+60>: ld r4,104(r1) 0x0000000050027970 <+64>: addi r3,r4,-8 0x0000000050027974 <+68>: addi r4,r1,128 0x0000000050027978 <+72>: addi r5,r1,120 0x000000005002797c <+76>: bl 0x50028608 <_rtld> 0x0000000050027980 <+80>: nop 0x0000000050027984 <+84>: ld r2,8(r3) 0x0000000050027988 <+88>: ld r11,16(r3) 0x000000005002798c <+92>: ld r3,0(r3) 0x0000000050027990 <+96>: mtlr r3 0x0000000050027994 <+100>: ld r3,96(r1) 0x0000000050027998 <+104>: ld r4,104(r1) 0x000000005002799c <+108>: ld r5,112(r1) 0x00000000500279a0 <+112>: ld r6,120(r1) 0x00000000500279a4 <+116>: ld r7,128(r1) 0x00000000500279a8 <+120>: ld r8,136(r1) 0x00000000500279ac <+124>: blrl =3D> 0x00000000500279b0 <+128>: li r0,1 0x00000000500279b4 <+132>: sc =20 0x00000000500279b8 <+136>: nop 0x00000000500279bc <+140>: nop End of assembler dump. So setting a breakpoint at 0x00000000500279ac and trying again: (gdb) run Starting program: /root/c_tests/a.out=20 Breakpoint 3, ._rtld_start () at = /usr/src/libexec/rtld-elf/powerpc64/rtld_start.S:104 104 blrl /* _start(argc, argv, envp, obj, cleanup, = ps_strings) */ (gdb) info registers r0 0x50027980 1342339456 r1 0xffffffffffffdaf0 18446744073709542128 r2 0x10028138 268599608 r3 0x1 1 r4 0xffffffffffffdbb8 18446744073709542328 r5 0xffffffffffffdbc8 18446744073709542344 r6 0x5004c000 1342488576 r7 0x50058b30 1342540592 r8 0x0 0 r9 0x0 0 r10 0x0 0 r11 0x0 0 r12 0x20000000 536870912 r13 0x50057010 1342533648 r14 0x0 0 r15 0x0 0 r16 0x0 0 r17 0x0 0 r18 0x0 0 r19 0x0 0 r20 0x0 0 r21 0x0 0 r22 0x0 0 r23 0x0 0 r24 0x0 0 r25 0x0 0 r26 0x0 0 r27 0x0 0 r28 0x0 0 r29 0x0 0 r30 0x0 0 r31 0x0 0 pc 0x500279ac 0x500279ac <._rtld_start+124> msr <unavailable> cr 0x22000c00 570428416 lr 0x10010000 0x10010000 ctr 0x50043a80 1342454400 xer 0x20000000 536870912 (gdb) stepi 0x0000000010010000 in ?? () and that is effectively at ._start . NOTE: There is no ._start name in the disassembly listed by objdump. By contrast for -fuse-ld=3Dbfd building a.out objdump shows: 0000000010000438 <._start> mflr r0 000000001000043c <._start+0x4> mfcr r12 0000000010000440 <._start+0x8> std r31,-8(r1) 0000000010000444 <._start+0xc> std r0,16(r1) 0000000010000448 <._start+0x10> stw r12,8(r1) 000000001000044c <._start+0x14> stdu r1,-176(r1) . . . In gdb for ld.lld used: Reading symbols from a.out...done. (gdb) br *0x00000000500279ac Breakpoint 1 at 0x500279ac (gdb) run Starting program: /root/c_tests/a.out=20 Breakpoint 1, ._rtld_start () at = /usr/src/libexec/rtld-elf/powerpc64/rtld_start.S:104 104 blrl /* _start(argc, argv, envp, obj, cleanup, = ps_strings) */ (gdb) stepi 0x0000000010010000 in ?? () (gdb)=20 0x0000000010010004 in ?? () (gdb) display/i $pc 1: x/i $pc =3D> 0x10010004: mfcr r12 (gdb) stepi 0x0000000010010008 in ?? () 1: x/i $pc =3D> 0x10010008: std r31,-8(r1) (gdb)=20 0x000000001001000c in ?? () 1: x/i $pc =3D> 0x1001000c: std r0,16(r1) . . . (gdb)=20 0x00000000100100a0 in ?? () 1: x/i $pc =3D> 0x100100a0: beq 0x100100ac (gdb)=20 0x00000000100100ac in ?? () 1: x/i $pc =3D> 0x100100ac: cmpldi r8,0 (gdb)=20 0x00000000100100b0 in ?? () 1: x/i $pc =3D> 0x100100b0: beq 0x100100c0 (gdb)=20 0x00000000100100c0 in ?? () 1: x/i $pc =3D> 0x100100c0: addis r3,r2,0 (gdb)=20 0x00000000100100c4 in ?? () 1: x/i $pc =3D> 0x100100c4: ld r3,32552(r3) (gdb)=20 0x00000000100100c8 in ?? () 1: x/i $pc =3D> 0x100100c8: cmpldi r3,0 (gdb)=20 0x00000000100100cc in ?? () 1: x/i $pc =3D> 0x100100cc: beq 0x100100e0 (gdb)=20 0x00000000100100d0 in ?? () 1: x/i $pc =3D> 0x100100d0: mr r3,r7 (gdb)=20 0x00000000100100d4 in ?? () 1: x/i $pc =3D> 0x100100d4: bl 0x10010560 Note: Below is from plt : Disassembly of section .plt: 0000000010010560 <.plt> std r2,40(r1) 0000000010010564 <.plt+0x4> addis r11,r2,0 0000000010010568 <.plt+0x8> ld r12,32512(r11) 000000001001056c <.plt+0xc> ld r11,0(r12) <<<<<=3D=3D=3D=3D=3D = Fails here. 0000000010010570 <.plt+0x10> mtctr r11 0000000010010574 <.plt+0x14> ld r2,8(r12) 0000000010010578 <.plt+0x18> ld r11,16(r12) 000000001001057c <.plt+0x1c> bctr (By setting breakpoints in the 3 such .plt code blocks: this is the first .plt code block executed and it fails.) The .plt is different from what ld.bfd generates: no __glink_PLTresolve or its use and the code does not appear strictly equivalent to me. Back to gdb based information: (gdb) info registers r0 0x500279b0 1342339504 r1 0xffffffffffffda40 18446744073709541952 r2 0x10028138 268599608 r3 0x50058b30 1342540592 r4 0x0 0 r5 0xffffffffffffdbc8 18446744073709542344 r6 0x5004c000 1342488576 r7 0x50058b30 1342540592 r8 0x0 0 r9 0x0 0 r10 0x0 0 r11 0x0 0 r12 0x22000c00 570428416 r13 0x50057010 1342533648 r14 0x0 0 r15 0x0 0 r16 0x0 0 r17 0x0 0 r18 0x0 0 r19 0x0 0 r20 0x0 0 r21 0x0 0 r22 0x0 0 r23 0x0 0 r24 0x0 0 r25 0x10028138 268599608 r26 0x0 0 r27 0x0 0 r28 0x1 1 r29 0xffffffffffffdbb8 18446744073709542328 r30 0xffffffffffffdbc8 18446744073709542344 r31 0xffffffffffffda40 18446744073709541952 pc 0x10010560 0x10010560 msr <unavailable> cr 0x42000c00 1107299328 lr 0x100100d8 0x100100d8 ctr 0x50043a80 1342454400 xer 0x20000000 536870912 (gdb)=20 0x0000000010010560 in ?? () 1: x/i $pc =3D> 0x10010560: std r2,40(r1) (gdb)=20 0x0000000010010564 in ?? () 1: x/i $pc =3D> 0x10010564: addis r11,r2,0 (gdb)=20 0x0000000010010568 in ?? () 1: x/i $pc =3D> 0x10010568: ld r12,32512(r11) (gdb)=20 0x000000001001056c in ?? () 1: x/i $pc =3D> 0x1001056c: ld r11,0(r12) (gdb)=20 Program received signal SIGSEGV, Segmentation fault. 0x000000001001056c in ?? () 1: x/i $pc =3D> 0x1001056c: ld r11,0(r12) The source code (from lib/csu/powerpc64/crt1.c ) is: void _start(int argc, char **argv, char **env, const struct Struct_Obj_Entry *obj __unused, void (*cleanup)(void), struct ps_strings *ps_strings) { handle_argv(argc, argv, env); if (ps_strings !=3D (struct ps_strings *)0) __ps_strings =3D ps_strings; if (&_DYNAMIC !=3D NULL) atexit(cleanup); else _init_tls(); #ifdef GCRT atexit(_mcleanup); monstartup(&eprol, &etext); #endif handle_static_init(argc, argv, env); exit(main(argc, argv, env)); } The 3 plt code blocks are for: atexit _init_tls exit from what I can tell, possibly not in that order. Overall: The plt handling seems to be broken. > You can also build rtld with additional debugging by adding -DDEBUG to > CFLAGS. In libexec/rtld-elf/Makefile there's an example command line > for building it locally, but I've just added CFLAGS+=3D-DDEBUG to the > Makefile in my test tree and built it along with the rest of my full > cross build. # svnlite diff /usr/src/libexec/rtld-elf/Makefile Index: /usr/src/libexec/rtld-elf/Makefile =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /usr/src/libexec/rtld-elf/Makefile (revision 311950) +++ /usr/src/libexec/rtld-elf/Makefile (working copy) @@ -17,6 +17,7 @@ malloc.c xmalloc.c debug.c libmap.c MAN=3D rtld.1 CSTD?=3D gnu99 +CFLAGS+=3D-DDEBUG CFLAGS+=3D -Wall -DFREEBSD_ELF -DIN_RTLD -ffreestanding CFLAGS+=3D -I${SRCTOP}/lib/csu/common .if exists(${.CURDIR}/${MACHINE_ARCH}) The above did not seem to make much of a difference for the code involved, likely because crt1.c is from lib/csu/powerpc64/ instead of from libexec/rtld-elf/ . =3D=3D=3D Mark Millard markmi at dsl-only.net
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?EF97071B-AE4A-4520-A997-52249B8DAB5A>