From owner-freebsd-toolchain@freebsd.org Wed Jan 18 21:56:57 2017 Return-Path: Delivered-To: freebsd-toolchain@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C58E9CB6F2C for ; Wed, 18 Jan 2017 21:56:57 +0000 (UTC) (envelope-from rdivacky@vlakno.cz) Received: from vlakno.cz (mail.vlakno.cz [91.217.96.224]) by mx1.freebsd.org (Postfix) with ESMTP id 2FC76114F; Wed, 18 Jan 2017 21:56:56 +0000 (UTC) (envelope-from rdivacky@vlakno.cz) Received: by vlakno.cz (Postfix, from userid 1002) id 8D32812CA54; Wed, 18 Jan 2017 22:54:20 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=vlakno.cz; s=mail; t=1484776460; bh=e5lS0APQvI97eVO0PhEE3bkn6TNXmVjASFHyIkTPim4=; h=Date:From:To:Cc:Subject:References:In-Reply-To; b=LGfJyX1zT+XW8EgLtcLp8Yg4BWTdv2GofEa7J/LT2mgzhHGNRLsmLxWgHFGlYEiEF ASdd3REy4wsxQ6GRPUMomV/TEydmWSHe7koQ2ldG4ar2LLfnaOpUMxetoMPHBa0/fC XiIjZeBWmOuuVnVKbJceEbJMokniNdzm+prrAW44= Date: Wed, 18 Jan 2017 22:54:20 +0100 From: Roman Divacky To: Mark Millard Cc: Ed Maste , FreeBSD Toolchain 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: <20170118215420.GA65399@vlakno.cz> References: <20170116194035.GA20175@vlakno.cz> <2B1414C5-C56D-42F2-A1CB-4B1FE074667B@dsl-only.net> <43DBF7C7-6632-4906-BB37-FD00621AF857@dsl-only.net> <82402941-D1B2-4938-A43D-E21A390DE041@dsl-only.net> <27422F1B-6906-4D37-860A-D1BC8DC83BBF@dsl-only.net> <20170117195424.GA89237@vlakno.cz> <237EB920-0795-4B18-94D4-2EAC0FC76F01@dsl-only.net> <20170117215613.GA95258@vlakno.cz> <45D0BB1C-490A-4809-BAB1-F4E552FECEDD@dsl-only.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <45D0BB1C-490A-4809-BAB1-F4E552FECEDD@dsl-only.net> User-Agent: Mutt/1.7.2 (2016-11-26) X-BeenThere: freebsd-toolchain@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Maintenance of FreeBSD's integrated toolchain List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Jan 2017 21:56:57 -0000 I think I got it all wrong. I think what lld is trying to achieve is to have the PLT entry to jump to GOT which references the real symbol. For some reason, GOT is empty, in our case. I believe this might be caused by a relocation thats wrongly mapped to R_ABS in PPC64TargetInfo::getRelExpr(). Mark, can you apply this patch and rerun the linking and send me back what relocations are applied to what symbols? Or even, if there's an unhandled relocation, try to adjust the switch and rerun your test? Thanks Index: ../tools/lld/ELF/Target.cpp =================================================================== --- ../tools/lld/ELF/Target.cpp (revision 292428) +++ ../tools/lld/ELF/Target.cpp (working copy) @@ -1075,7 +1075,8 @@ } PPC64TargetInfo::PPC64TargetInfo() { - PltRel = GotRel = R_PPC64_GLOB_DAT; + GotRel = R_PPC64_GLOB_DAT; + PltRel = R_PPC64_JMP_SLOT; RelativeRel = R_PPC64_RELATIVE; GotEntrySize = 8; GotPltEntrySize = 8; @@ -1114,8 +1115,10 @@ } RelExpr PPC64TargetInfo::getRelExpr(uint32_t Type, const SymbolBody &S) const { + llvm::outs() << "Type = " << Type << ", name = " << S.getName() << "\n"; switch (Type) { default: + llvm::outs() << "Unhandled type = " << Type << "\n"; return R_ABS; case R_PPC64_TOC16: case R_PPC64_TOC16_DS: On Tue, Jan 17, 2017 at 09:38:07PM -0800, Mark Millard wrote: > Using the new changed line (Plt use now): > > uint64_t TocVA = Out::Plt->getVA(); > > changed the behavior and it gets farther for > -fuse-ld=lld based linking. But it is r2 leading > to r3 content that is dereferenced and 8(r3) fails > this time. This was in the process of finding > the new r2 value for the following bctrl. > r2==0x10018560 initially in __do_global_ctors_aux > seems wrong. If so then objlist_call_init produced > a wrong r2 value. > > [I've no clue if this is what you expected from > the Plt experiment or not.] > > Details. . . > > # /usr/local/bin/gdb a.out > GNU gdb (GDB) 7.11.1 [GDB v7.11.1 for FreeBSD] > . . . > Reading symbols from a.out...done. > (gdb) run > Starting program: /root/c_tests/a.out > > Program received signal SIGSEGV, Segmentation fault. > 0x00000000100104a8 in .__do_global_ctors_aux () > (gdb) bt > #0 0x00000000100104a8 in .__do_global_ctors_aux () > #1 0x0000000010010518 in ._init () > #2 0x000000005002ac78 in objlist_call_init (list=, lockstate=) at /usr/src/libexec/rtld-elf/rtld.c:2541 > #3 0x0000000050029fa8 in _rtld (sp=, exit_proc=, objp=) at /usr/src/libexec/rtld-elf/rtld.c:668 > #4 0x00000000500279b0 in ._rtld_start () at /usr/src/libexec/rtld-elf/powerpc64/rtld_start.S:83 > Backtrace stopped: frame did not save the PC > (gdb) disass > Dump of assembler code for function .__do_global_ctors_aux: > 0x0000000010010470 <+0>: mflr r0 > 0x0000000010010474 <+4>: std r31,-8(r1) > 0x0000000010010478 <+8>: std r0,16(r1) > 0x000000001001047c <+12>: stdu r1,-128(r1) > 0x0000000010010480 <+16>: addis r3,r2,-1 <<<<<==== Note: r3 derives from r2 > 0x0000000010010484 <+20>: mr r31,r1 > 0x0000000010010488 <+24>: addi r3,r3,32464 > 0x000000001001048c <+28>: std r30,112(r31) > 0x0000000010010490 <+32>: ld r3,-8(r3) > 0x0000000010010494 <+36>: cmpdi r3,-1 > 0x0000000010010498 <+40>: beq 0x100104d4 <.__do_global_ctors_aux+100> > 0x000000001001049c <+44>: addis r4,r2,-1 > 0x00000000100104a0 <+48>: addi r4,r4,32464 > 0x00000000100104a4 <+52>: addi r30,r4,-8 > => 0x00000000100104a8 <+56>: ld r4,8(r3) <<<<<==== Note: 8(r3) fails. > 0x00000000100104ac <+60>: ld r11,16(r3) > 0x00000000100104b0 <+64>: ld r3,0(r3) > 0x00000000100104b4 <+68>: std r2,40(r1) > 0x00000000100104b8 <+72>: mr r2,r4 <<<<<==== Note: 8(r3) result should have been the new r2 value > 0x00000000100104bc <+76>: mtctr r3 > 0x00000000100104c0 <+80>: bctrl > 0x00000000100104c4 <+84>: ld r2,40(r1) > 0x00000000100104c8 <+88>: ldu r3,-8(r30) > 0x00000000100104cc <+92>: cmpdi r3,-1 > 0x00000000100104d0 <+96>: bne 0x100104a8 <.__do_global_ctors_aux+56> > 0x00000000100104d4 <+100>: ld r30,112(r31) > 0x00000000100104d8 <+104>: addi r1,r1,128 > 0x00000000100104dc <+108>: ld r0,16(r1) > 0x00000000100104e0 <+112>: ld r31,-8(r1) > 0x00000000100104e4 <+116>: mtlr r0 > 0x00000000100104e8 <+120>: blr > 0x00000000100104ec <+124>: .long 0x0 > 0x00000000100104f0 <+128>: .long 0x0 > 0x00000000100104f4 <+132>: .long 0x0 > End of assembler dump. > (gdb) info registers > r0 0x10010518 268502296 > r1 0xffffffffffffcbf0 18446744073709538288 > r2 0x10018560 268535136 > r3 0x7ca903a64e800421 8982714944583631905 > r4 0x10010430 268502064 > r5 0x100300d0 268632272 > r6 0x50043ab0 1342454448 > r7 0x50067f00 1342603008 > r8 0xffffffffffffdfcc 18446744073709543372 > r9 0x0 0 > r10 0x0 0 > r11 0x0 0 > r12 0xffffffffffffdfd0 18446744073709543376 > r13 0x50057010 1342533648 > r14 0x0 0 > r15 0x0 0 > r16 0x50047f00 1342471936 > r17 0x500613e0 1342575584 > r18 0x50253388 1344615304 > r19 0x2 2 > r20 0x0 0 > r21 0x9 9 > r22 0x0 0 > r23 0x40000000000000 18014398509481984 > r24 0x5004a100 1342480640 > r25 0x5004c400 1342489600 > r26 0xffffffffffffcd18 18446744073709538584 > r27 0xffffffffffffcd3c 18446744073709538620 > r28 0xffffffffffffcd3c 18446744073709538620 > r29 0x0 0 > r30 0x10010428 268502056 > r31 0xffffffffffffcbf0 18446744073709538288 > pc 0x100104a8 0x100104a8 <.__do_global_ctors_aux+56> > msr > cr 0x48200c00 1210059776 > lr 0x10010518 0x10010518 <._init+24> > ctr 0x10010500 268502272 > xer 0x20000000 536870912 > (gdb) info file > Symbols from "/root/c_tests/a.out". > Native process: > Using the running image of child LWP 100093 of process 1091. > While running this, GDB does not access memory from... > Local exec file: > `/root/c_tests/a.out', file type elf64-powerpc-freebsd. > Entry point: 0x100300a0 > 0x0000000010000270 - 0x0000000010000285 is .interp > 0x0000000010000288 - 0x00000000100002b8 is .note.tag > 0x00000000100002b8 - 0x00000000100002b9 is .rodata > 0x00000000100002bc - 0x00000000100002bc is .eh_frame > 0x00000000100002c0 - 0x0000000010000368 is .dynsym > 0x0000000010000368 - 0x0000000010000376 is .gnu.version > 0x0000000010000378 - 0x0000000010000398 is .gnu.version_r > 0x0000000010000398 - 0x00000000100003d8 is .hash > 0x00000000100003d8 - 0x000000001000041a is .dynstr > 0x0000000010000420 - 0x0000000010000468 is .rela.plt > 0x0000000010000468 - 0x0000000010000474 is .eh_frame_hdr > 0x0000000010010000 - 0x00000000100104f8 is .text > 0x0000000010010500 - 0x000000001001052c is .init > 0x0000000010010530 - 0x0000000010010554 is .fini > 0x0000000010010560 - 0x00000000100105c0 is .plt > 0x0000000010020000 - 0x0000000010020010 is .ctors > 0x0000000010020010 - 0x0000000010020020 is .dtors > 0x0000000010020020 - 0x0000000010020028 is .jcr > 0x0000000010020028 - 0x0000000010020138 is .dynamic > 0x0000000010020138 - 0x0000000010020138 is .got > 0x0000000010030000 - 0x0000000010030019 is .data > 0x0000000010030020 - 0x0000000010030050 is .got.plt > 0x0000000010030050 - 0x00000000100300a0 is .toc > 0x00000000100300a0 - 0x0000000010030160 is .opd > 0x0000000010030160 - 0x0000000010030170 is .bss > 0x0000000050020158 - 0x0000000050020228 is .hash in /libexec/ld-elf.so.1 > 0x0000000050020228 - 0x0000000050020540 is .dynsym in /libexec/ld-elf.so.1 > 0x0000000050020540 - 0x00000000500206b6 is .dynstr in /libexec/ld-elf.so.1 > 0x00000000500206b6 - 0x00000000500206f8 is .gnu.version in /libexec/ld-elf.so.1 > 0x00000000500206f8 - 0x0000000050020808 is .gnu.version_d in /libexec/ld-elf.so.1 > 0x0000000050020808 - 0x0000000050027960 is .rela.dyn in /libexec/ld-elf.so.1 > 0x0000000050027960 - 0x0000000050045a04 is .text in /libexec/ld-elf.so.1 > 0x0000000050045a04 - 0x00000000500484a3 is .rodata in /libexec/ld-elf.so.1 > 0x00000000500484a4 - 0x00000000500484a4 is .eh_frame in /libexec/ld-elf.so.1 > 0x000000005005cf50 - 0x000000005005cf58 is .fini_array in /libexec/ld-elf.so.1 > 0x000000005005cf58 - 0x000000005005d260 is .data.rel.ro in /libexec/ld-elf.so.1 > 0x000000005005d260 - 0x000000005005d3b0 is .dynamic in /libexec/ld-elf.so.1 > 0x000000005005d3b0 - 0x000000005005ff00 is .opd in /libexec/ld-elf.so.1 > 0x000000005005ff00 - 0x000000005005ff08 is .got in /libexec/ld-elf.so.1 > 0x0000000050060000 - 0x0000000050060628 is .data in /libexec/ld-elf.so.1 > 0x0000000050060628 - 0x0000000050061478 is .bss in /libexec/ld-elf.so.1 > 0x00000000500621c8 - 0x00000000500672b0 is .hash in /lib/libc.so.7 > 0x00000000500672b0 - 0x0000000050079778 is .dynsym in /lib/libc.so.7 > 0x0000000050079778 - 0x0000000050080846 is .dynstr in /lib/libc.so.7 > 0x0000000050080846 - 0x00000000500820ac is .gnu.version in /lib/libc.so.7 > 0x00000000500820b0 - 0x00000000500821c0 is .gnu.version_d in /lib/libc.so.7 > 0x00000000500821c0 - 0x00000000500c2678 is .rela.dyn in /lib/libc.so.7 > 0x00000000500c2678 - 0x00000000500c7868 is .rela.plt in /lib/libc.so.7 > 0x00000000500c7870 - 0x00000000500c789c is .init in /lib/libc.so.7 > 0x00000000500c78a0 - 0x0000000050227ca0 is .text in /lib/libc.so.7 > 0x0000000050227ca0 - 0x0000000050227cc4 is .fini in /lib/libc.so.7 > 0x0000000050227d00 - 0x000000005023b606 is .rodata in /lib/libc.so.7 > 0x000000005023b608 - 0x000000005023b6ec is .eh_frame_hdr in /lib/libc.so.7 > 0x000000005023b6f0 - 0x000000005023bad4 is .eh_frame in /lib/libc.so.7 > 0x0000000050253318 - 0x0000000050253380 is .tdata in /lib/libc.so.7 > 0x0000000050253380 - 0x0000000050253390 is .tbss in /lib/libc.so.7 > 0x0000000050253380 - 0x0000000050253390 is .init_array in /lib/libc.so.7 > 0x0000000050253390 - 0x0000000050253398 is .fini_array in /lib/libc.so.7 > 0x0000000050253398 - 0x00000000502533a8 is .ctors in /lib/libc.so.7 > 0x00000000502533a8 - 0x00000000502533b8 is .dtors in /lib/libc.so.7 > 0x00000000502533b8 - 0x00000000502533c0 is .jcr in /lib/libc.so.7 > 0x00000000502533c0 - 0x0000000050258a90 is .data.rel.ro in /lib/libc.so.7 > 0x0000000050258a90 - 0x0000000050258c60 is .dynamic in /lib/libc.so.7 > 0x0000000050258c60 - 0x000000005026f8f8 is .opd in /lib/libc.so.7 > 0x000000005026f900 - 0x0000000050271f98 is .got in /lib/libc.so.7 > 0x0000000050272000 - 0x0000000050277208 is .plt in /lib/libc.so.7 > 0x0000000050277208 - 0x000000005027b0b0 is .data in /lib/libc.so.7 > 0x000000005027b0b0 - 0x0000000050294738 is .bss in /lib/libc.so.7 > > > === > Mark Millard > markmi at dsl-only.net > > On 2017-Jan-17, at 1:56 PM, Roman Divacky wrote: > > > Go with Out. > > > > On Tue, Jan 17, 2017 at 01:53:14PM -0800, Mark Millard wrote: > >> On 2017-Jan-17, at 11:54 AM, Roman Divacky wrote: > >> > >> . . . > >>> I wonder if it doesnt work because of my first patch (the one to turn GOT > >>> reloc into PLT one). > >>> > >>> LLD understands that we use GOT as TOC (which was true before my patch), > >>> I wonder if something like this: > >>> > >>> ndex: tools/lld/ELF/Target.cpp > >>> =================================================================== > >>> --- tools/lld/ELF/Target.cpp (revision 292071) > >>> +++ tools/lld/ELF/Target.cpp (working copy) > >>> @@ -1070,7 +1070,8 @@ > >>> } > >>> > >>> PPC64TargetInfo::PPC64TargetInfo() { > >>> - PltRel = GotRel = R_PPC64_GLOB_DAT; > >>> + GotRel = R_PPC64_GLOB_DAT; > >>> + PltRel = R_PPC64_JMP_SLOT; > >>> RelativeRel = R_PPC64_RELATIVE; > >>> GotEntrySize = 8; > >>> GotPltEntrySize = 8; > >>> @@ -1099,7 +1100,7 @@ > >>> // TOC starts where the first of these sections starts. We always create a > >>> // .got when we see a relocation that uses it, so for us the start is always > >>> // the .got. > >>> - uint64_t TocVA = In::Got->getVA(); > >>> + uint64_t TocVA = In::Plt->getVA(); > >>> > >>> // Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000 > >>> // thus permitting a full 64 Kbytes segment. Note that the glibc startup > >> > >> The modern 3.9.1 source does not match for the last. Note the > >> "Out" vs. "In" below ("svnlite status" does not show my source > >> as different in this area): > >> > >> uint64_t getPPC64TocBase() { > >> // The TOC consists of sections .got, .toc, .tocbss, .plt in that order. The > >> // TOC starts where the first of these sections starts. We always create a > >> // .got when we see a relocation that uses it, so for us the start is always > >> // the .got. > >> uint64_t TocVA = Out::Got->getVA(); > >> > >> // Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000 > >> // thus permitting a full 64 Kbytes segment. Note that the glibc startup > >> // code (crt1.o) assumes that you can get from the TOC base to the > >> // start of the .toc section with only a single (signed) 16-bit relocation. > >> return TocVA + PPC64TocOffset; > >> } > >> > >> [Also the "// TOC . . ." comment is at line 1005 (given the prior > >> GotRel vs. PltRel split into separate lines).] > >> > >> Which should I use?: In vs. Out > >> > >>> would make any difference? It's not correct but might shed some light on what needs to be done > >>> if I am right. > >> > >> Separately if I understand the change you are picking out which section > >> is first of .got, .toc, .tocbss, .plt (.got.plt as well?). But for the > >> order of things that would still make the .ctors, .dtors, .jcr, .dynamic, > >> and .data sections as being inside the TOC and taking TOC address range > >> space: > >> > >> 0x0000000010010560 - 0x00000000100105c0 is .plt <<<<<===== NOTE!!!! > >> 0x0000000010020000 - 0x0000000010020010 is .ctors > >> 0x0000000010020010 - 0x0000000010020020 is .dtors > >> 0x0000000010020020 - 0x0000000010020028 is .jcr > >> 0x0000000010020028 - 0x0000000010020138 is .dynamic > >> 0x0000000010020138 - 0x0000000010020138 is .got <<<<<===== NOTE!!!! > >> 0x0000000010030000 - 0x0000000010030019 is .data > >> 0x0000000010030020 - 0x0000000010030050 is .got.plt <<<<<===== NOTE!!!! > >> 0x0000000010030050 - 0x00000000100300a0 is .toc <<<<<===== NOTE!!!! > >> > >> Is that expected/desired/allowed? > >> > >>> Could you explore this please? > >> > >> After you report for sure for In vs. Out I'll take a stab > >> at it. > >> > >> === > >> Mark Millard > >> markmi at dsl-only.net