Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 16 Jan 2017 17:18:34 -0800
From:      Mark Millard <markmi@dsl-only.net>
To:        Roman Divacky <rdivacky@vlakno.cz>, Ed Maste <emaste@freebsd.org>
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:  <27422F1B-6906-4D37-860A-D1BC8DC83BBF@dsl-only.net>
In-Reply-To: <F38C9607-5AB9-4BF9-BEC1-88EA2518A9CE@dsl-only.net>
References:  <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> <EF97071B-AE4A-4520-A997-52249B8DAB5A@dsl-only.net> <20170112192223.GA49469@vlakno.cz> <932E3C38-B226-4BF1-B587-5A2D5EA19300@dsl-only.net> <F3923971-6FDF-4269-A7CA-3428249A128F@dsl-only.net> <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> <F38C9607-5AB9-4BF9-BEC1-88EA2518A9CE@dsl-only.net>

next in thread | previous in thread | raw e-mail | index | archive | help
I found some wording relating older-style .got to newer style =
.got/.got.plt
pair of sections (that need not be near each other). . .

https://sourceware.org/ml/binutils/2004-03/msg00350.html

says that the .got has been split in two: in essence the RELRO part
and the non-RELRO part. Quoting:

> .got.plt section contains the 3 reserved entries plus the GOT entries
> corresponding to the .plt stubs.  The point of separating this from
> .got (where this lived at the beginning of .got, i.e.
> .got : ( *(.got.plt) *(.got) ) in the linker script) is to put the =
reminder
> of .got to an area which can be write protected after relocation is
> finished because it is constant after relocation is finished.  This is =
not
> true for .got.plt, which is written to during lazy binding.

That fits with what I've read about the end result that involves =
.got.plt .

=3D=3D=3D
Mark Millard
markmi at dsl-only.net

On 2017-Jan-16, at 3:39 PM, Mark Millard <markmi at dsl-only.net> wrote:

> [Correcting a poor wording/interpetatation.]
>=20
> On 2017-Jan-16, at 3:28 PM, Mark Millard <markmi@dsl-only.net> wrote:
>=20
>> Looking up definitions of the section naming
>> (using http://www.cs.stevens.edu/~jschauma/810/elf.html ). . .
>> (Intel context)
>>=20
>>=20
>> It looks like the RELRO segment (program header information) requires
>> the .got section to be with the .ctors, .dtros, .jcr and such =
sections:
>> .got is supposed to be inside the RELRO region. ld.lld output was =
using
>> RELRO. Quoting the description of RELRO:
>>=20
>> GNU_RELRO:
>>=20
>> This segment indicates the memory region which should be made =
Read-Only after relocation is done. This segment usually appears in a =
dynamic link library and it contains .ctors, .dtors, .dynamic, .got =
sections. See paragraph below.
>>=20
>> BUT NOTE: The ld.lld output has .jcr section in the RELRO segment and =
the .dynamic just after it.
>=20
> That "BUT NOTE" is wrong because both .dynamic and .got were empty and =
so are not really outside
> the RELRO region: just at the boundary. If they had some positive size =
then the end of RELRO
> would be after those sections start and would include their content.
>=20
>> Showing the objdump output for RELRO:
>>=20
>>  RELRO off    0x0000000000020000 vaddr 0x0000000010020000 paddr =
0x0000000010020000 align 2**0
>>        filesz 0x0000000000000138 memsz 0x0000000000000138 flags r--
>>=20
>> .got.plt and .toc do not go in the RELRO segment.
>>=20
>>=20
>> Quoting section descriptions. . .
>>=20
>>=20
>> .rela.plt:
>>=20
>> Runtime/Dynamic relocation table.
>> This relocation table is similar to the one in .rela.dyn section; the =
difference is this one is for functions, not variables.
>>=20
>> The relocation type of entries in this table is R_386_JMP_SLOT or =
R_X86_64_JUMP_SLOT and the "offset" refers to memory addresses which are =
inside .got.plt section.
>>=20
>> Simply put, this table holds information to relocate entries in =
.got.plt section.
>>=20
>>=20
>> .got:
>> For dynamic binaries, this Global Offset Table holds the addresses of =
variables which are relocated upon loading.
>>=20
>> [Note: .got was empty because of a lack of global variables. But it
>> was still present.]
>>=20
>>=20
>> .got.plt:
>>=20
>> For dynamic binaries, this Global Offset Table holds the addresses of =
functions in dynamic libraries. They are used by trampoline code in .plt =
section. If .got.plt section is present, it contains at least three =
entries, which have special meanings.
>>=20
>>=20
>> .toc:
>>=20
>> Was not listed. (Likely powerpc64 and/or powerpc specific.)
>>=20
>>=20
>>=20
>> So ld.lld is keeping the .got with the other RELRO materials,
>> as it is supposed to.
>>=20
>> And is setting up to allow lazy binding (.got.plt).
>>=20
>> It did keep the non-RELRO materials .got.plt and .toc together.
>> But .plt is off by itself, before both the RELRO segment and the
>> .got.plt/.toc pair.
>>=20
>>=20
>>=20
>> As far as I can tell the powerpc and powerpc64 FreeBSD code is
>> not set up for any variation of such things.
>>=20
>> It may be that changes are needed to allow RELRO with the .got
>> inside, for example.
>>=20
>> It is not obvious that disabling RELRO in ld.lld would change
>> the order and contiguity in memory to what powerpc and powerpc64
>> FreeBSD expect.
>=20
>=20
> =3D=3D=3D
> Mark Millard
> markmi at dsl-only.net

On 2017-Jan-16, at 2:32 PM, Mark Millard <markmi at dsl-only.net> wrote:

Here is a more direct list of section addresse rangess from gdb
for ld.lld output:
(I've added comments on the right.)

(gdb) info file
Symbols from "/root/c_tests/a.out".
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     =
<<<<<=3D=3D=3D=3D=3D note
	0x0000000010000468 - 0x0000000010000474 is .eh_frame_hdr
	0x0000000010010000 - 0x00000000100104f8 is .text
	0x0000000010010500 - 0x000000001001052c is .init
	0x0000000010010530 - 0x0000000010010554 is .fini
	0x0000000010010560 - 0x00000000100105c0 is .plt          =
<<<<<=3D=3D=3D=3D=3D NOTE!!!!
	0x0000000010020000 - 0x0000000010020010 is .ctors
	0x0000000010020010 - 0x0000000010020020 is .dtors
	0x0000000010020020 - 0x0000000010020028 is .jcr
	0x0000000010020028 - 0x0000000010020138 is .dynamic
	0x0000000010020138 - 0x0000000010020138 is .got          =
<<<<<=3D=3D=3D=3D=3D NOTE!!!!
	0x0000000010030000 - 0x0000000010030019 is .data
	0x0000000010030020 - 0x0000000010030050 is .got.plt      =
<<<<<=3D=3D=3D=3D=3D NOTE!!!!
	0x0000000010030050 - 0x00000000100300a0 is .toc          =
<<<<<=3D=3D=3D=3D=3D NOTE!!!!
	0x00000000100300a0 - 0x0000000010030160 is .opd
	0x0000000010030160 - 0x0000000010030170 is .bss

It matches the readelf and objdump output reports.

=3D=3D=3D
Mark Millard
markmi at dsl-only.net

On 2017-Jan-16, at 1:39 PM, Mark Millard <markmiat dsl-only.net> wrote:

> On 2017-Jan-16, at 11:40 AM, Roman Divacky <rdivacky at vlakno.cz> =
wrote:
>=20
>> I think the TOC (.got + .plt) has to be contiguous in memory. The =
on-disk
>> layout is not that important.
>=20
> I showed the address column that I would expect to accurately reflect =
addresses
> to load to in the process. I also showed the Offset Align which would =
be relative
> to whatever base was used (even if different) as far as I can tell.
>=20
> (Later in repsonse t your question I show what I expect is a =
sufficient
> confirmation.)
>=20
> Note: objdump and readelf agree (VMA and LMA). Here is the objdump
> equivalent:
>=20
> Sections:
> Idx Name          Size      VMA               LMA               File =
off  Algn
> . . .
> 9 .rela.plt     00000048  0000000010000420  0000000010000420  00000420 =
 2**3
>               CONTENTS, ALLOC, LOAD, READONLY, DATA
> . . .
> 14 .plt          00000060  0000000010010560  0000000010010560  =
00010560  2**4
>               CONTENTS, ALLOC, LOAD, READONLY, CODE
> . . .
> 19 .got          00000000  0000000010020138  0000000010020138  =
00020138  2**3
>               CONTENTS, ALLOC, LOAD, DATA
> . . .
> 21 .got.plt      00000030  0000000010030020  0000000010030020  =
00030020  2**3
>               CONTENTS, ALLOC, LOAD, DATA
> 22 .toc          00000050  0000000010030050  0000000010030050  =
00030050  2**3
>               CONTENTS, ALLOC, LOAD, DATA
> . . .
>=20
>=20
>> Can you check whats the difference of the in-memory TOC between lld =
and ld.bfd?
>=20
> gdb reports agreement with the addresses listed by the likes of =
objdump for
> the symbols it reports. There are examples from sections .note.tag, =
.eh_frame,
> .ctors, .dtors, .jcr, .dynamic, .data, .pod, and .bss . None of these =
sections
> move. So I expect the other sections do not move either.
>=20
> Below I compare objdump symbols reporting to gdb reporting of what =
symbol is
> at an address, at least one address for each one of those sections =
with a
> symbol.
>=20
> Here is what objdump shows for assigned symbols (sorted):
> (I've inserted some comments about some other sections
> that have no symbols based on the addresses from objdump
> and readelf.)
>=20
> 0000000010000288 l     O .note.tag      0000000000000018              =
abitag
> 00000000100002a0 l     O .note.tag      0000000000000018              =
crt_noinit_tag
> 00000000100002bb l     O .eh_frame      0000000000000004              =
__FRAME_END__
> .rela.plt fits between here: 0000000010000420 (start)
> .plt fits between here     : 0000000010010560 (start)
> 0000000010020000 l     O .ctors 0000000000000008              =
__CTOR_LIST__
> 0000000010020008 l     O .ctors 0000000000000008              =
__CTOR_END__
> 0000000010020010 l     O .dtors 0000000000000008              =
__DTOR_LIST__
> 0000000010020018 l     O .dtors 0000000000000008              =
__DTOR_END__
> 0000000010020020 l     O .jcr   0000000000000000              =
__JCR_LIST__
> 0000000010020020 l     O .jcr   0000000000000008              =
__JCR_END__
> 0000000010020028 l       .dynamic       0000000000000000              =
.hidden _DYNAMIC
> .got fits between here     : 0000000010020138 (start and end: size =
zero)
> 0000000010030000 g     O .data  0000000000000008              =
__progname
> 0000000010030008 l     O .data  0000000000000008              .hidden =
__dso_handle
> 0000000010030010 l     O .data  0000000000000008              =
__do_global_dtors_aux.p
> 0000000010030018 l     O .data  0000000000000001              =
__do_global_dtors_aux.completed
> .got.plt fits between here : 0000000010030020 (start)
> .toc fits between here     : 0000000010030050 (start)
> 00000000100300a0 g     F .opd   0000000000000264              _start
> 00000000100300b8 l     F .opd   00000000000000d0              =
finalizer
> 00000000100300d0 l     F .opd   0000000000000000              .hidden =
_init
> 00000000100300e8 l     F .opd   0000000000000000              .hidden =
_fini
> 0000000010030100 l     F .opd   00000000000000a4              =
__do_global_dtors_aux
> 0000000010030118 l     F .opd   000000000000007c              =
frame_dummy
> 0000000010030130 g     F .opd   000000000000001c              main
> 0000000010030148 l     F .opd   0000000000000088              =
__do_global_ctors_aux
> 0000000010030160 g     O .bss   0000000000000008              =
__ps_strings
> 0000000010030168 g     O .bss   0000000000000008              environ
> 0000000010030170 g       *ABS*  0000000000000000              _end
>=20
> Examples of gdb reporting symbol information for some of those =
addresses:
>=20
> (gdb) info symbol 0x0000000010000288
> abitag in section .note.tag
> (gdb) info symbol 0x00000000100002a0
> crt_noinit_tag in section .note.tag
> (gdb) info symbol 0x00000000100002a4
> crt_noinit_tag + 4 in section .note.tag
> (gdb) info symbol 0x0000000010020008
> __CTOR_END__ in section .ctors
> (gdb) info symbol 0x0000000010020010
> __DTOR_LIST__ in section .dtors
> (gdb) info symbol 0x0000000010020020
> __JCR_END__ in section .jcr
> (gdb) info symbol 0x0000000010020028
> _DYNAMIC in section .dynamic
> (gdb) info symbol 0x0000000010030010
> __do_global_dtors_aux.p in section .data
> (gdb) info symbol 0x00000000100300a0
> _start in section .opd
> (gdb) info symbol 0x0000000010030130
> main in section .opd
> (gdb) info symbol 0x0000000010030160
> __ps_strings in section .bss
>=20
> ld.lld (as configured?) just does not set up for the sections to have
> the property:
>=20
> .got, .toc, .tocbss, .plt in that order
>=20
> (in memory) and ld.lld (as configured?) puts out sections that ld.bfd
> does not:
>=20
> .got.plt
> .toc
>=20
> I'd guess that ld.lld has build-time and/or run-time configuration
> requirements in order for its results to basically match what ld.bfd
> does for the same input files --if it even can.
>=20
=3D=3D=3D
Mark Millard
markmi at dsl-only.net

On Fri, Jan 13, 2017 at 02:07:00PM -0800, Mark Millard wrote:
> Just an FYI:
>=20
> elfdump -a (from -r311950) does not dump .plt or .got.plt or .toc :
>=20
> # elfdump -a a.out | egrep "(got|toc|plt|:$)" | more
> elf header:
> program header:
> section header:
>    sh_name: .rela.plt
>    sh_name: .plt
>    sh_name: .got
>    sh_name: .got.plt
>    sh_name: .toc
> interp:
> symbol table (.dynsym):
> relocation with addend (.rela.plt):
> dynamic:
> global offset table:
> symbol table (.symtab):
>=20
> (The "global offset table" was empty but its title was listed.)
>=20
> =3D=3D=3D
> Mark Millard
> markmi at dsl-only.net
>=20
> On 2017-Jan-12, at 5:58 PM, Mark Millard <markmi at dsl-only.net> =
wrote:
>=20
> On 2017-Jan-12, at 11:22 AM, Roman Divacky <rdivacky at vlakno.cz> =
wrote:
>=20
>> Can you check if the TOC is correct? LLD assumes this:
>>=20
>> static uint64_t PPC64TocOffset =3D 0x8000;
>>=20
>> 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 =3D In<ELF64BE>::Got->getVA();
>>=20
>> // 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;
>> }
>=20
> [I warn that I'm outside familiar territory here.]
>=20
> If I understand the 1st comment right the following does not look
> like a match for -fuse-dl=3Dlld (readelf -a output):
>=20
> Section Headers:
> [Nr] Name              Type             Address           Offset
>  Size              EntSize          Flags  Link  Info  Align
> [ 0]                   NULL             0000000000000000  00000000
>  0000000000000000  0000000000000000           0     0     0
> . . .
> [10] .rela.plt         RELA             0000000010000420  00000420
>  0000000000000048  0000000000000018   A       5     0     8
> . . .
> [15] .plt              PROGBITS         0000000010010560  00010560
>  0000000000000060  0000000000000000  AX       0     0     16
> . . .
> [20] .got              PROGBITS         0000000010020138  00020138
>  0000000000000000  0000000000000000  WA       0     0     8
> . . .
> [22] .got.plt          PROGBITS         0000000010030020  00030020
>  0000000000000030  0000000000000000  WA       0     0     8
> . . .
> [23] .toc              PROGBITS         0000000010030050  00030050
>  0000000000000050  0000000000000000  WA       0     0     8
>=20
> Possibly contributing reasons:
>=20
> A) .got is not "first" of the 4 sections (by Address or by [Nr]).
> (.got is listed as zero size as well)
> B) There is no reference to .got.plt in the comment.
> C) .got and .toc have .got.plt and other things between
> -- and .got and .got.plt have stuff between.
> D) There is no .tocbss at all (guess: optional so possibly okay).
> E) .plt is before .got by address and by [Nr]
> (it is als not next to .got or .got.plt or .toc).
> F) There is no reference to .got.plt in the comment.
> G) In general there are other things between the sections
> making them spread over a wider address range.
>=20
> [I guess that .rela.plt does not matter but I showed it
> in case I'm wrong.]
>=20
> Another potential issue is .plt being PROGBITS instead of
> NOBITS (see below). Related is AX flags above vs. WA
> flags below being a potential issue.
>=20
>=20
> By contrast for -fuse-dl-bfd I see:
>=20
> Section Headers:
> [Nr] Name              Type             Address           Offset
>  Size              EntSize          Flags  Link  Info  Align
> [ 0]                   NULL             0000000000000000  00000000
>  0000000000000000  0000000000000000           0     0     0
> . . .
> [ 8] .rela.plt         RELA             0000000010000370  00000370
>  0000000000000048  0000000000000018   A       4    22     8
> . . .
> [21] .got              PROGBITS         0000000010010c48  00000c48
>  0000000000000058  0000000000000008  WA       0     0     8
> [22] .plt              NOBITS           0000000010010ca0  00000ca0
>  0000000000000060  0000000000000018  WA       0     0     8
>=20
> So no .toc or .tocbase sections.
>=20
> But .got and .plt are next to each other with .got first
> (by address and by [Nr]). This would fit the comments if
> .toc and .tocbss are optional --and apparently they are.
>=20
> So my guess is that -fuse-dl-bfd looks to be as expected,
> unlike -fuse-dl=3Dlld .
>=20
>=20
>> Perhaps thats not true on FreeBSD? Especially the hardcoded constant =
seems suspicious.
>> When it comes to the actual PLT entry, there's this comment in the =
code:
>>=20
>> // FIXME: What we should do, in theory, is get the offset of the =
function
>> // descriptor in the .opd section, and use that as the offset from =
%r2 (the
>> // TOC-base pointer). Instead, we have the GOT-entry offset, and that =
will
>> // be a pointer to the function descriptor in the .opd section. Using
>> // this scheme is simpler, but requires an extra indirection per PLT =
dispatch.
>>=20
>> So I think that while it's different it might not be wrong. What =
might be wrong
>> is the TOC entry (either it's content or it's position).
>>=20
>> I suspect there might be some Linux vs FreeBSD difference that =
prevents this from working.
>>=20
>> Roman
>=20
> =3D=3D=3D
> Mark Millard
> markmi at dsl-only.net
>=20
> On Thu, Jan 12, 2017 at 12:37:53AM -0800, Mark Millard wrote:
>> On 2017-Jan-11, at 1:23 PM, Ed Maste <emaste at freebsd.org> wrote:
>>=20
>>> 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.
>>=20
>> Thanks. I updated to -r311950 to pick this up.
>>=20
>>>> 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.
>>=20
>> I had compiled with -g. It never gets to main. . .
>>=20
>> # /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
>>=20
>> Program received signal SIGSEGV, Segmentation fault.
>> 0x000000001001056c in ?? ()
>>=20
>> Note that the temporary breakpoint is never hit.
>>=20
>> (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
>>=20
>> (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.
>>=20
>> So setting a breakpoint at 0x00000000500279ac and
>> trying again:
>>=20
>> (gdb) run
>> Starting program: /root/c_tests/a.out=20
>>=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 ?? ()
>>=20
>> and that is effectively at ._start .
>>=20
>> NOTE: There is no ._start name in the disassembly
>> listed by objdump.
>>=20
>> By contrast for -fuse-ld=3Dbfd building a.out objdump shows:
>>=20
>> 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)
>> . . .
>>=20
>>=20
>> In gdb for ld.lld used:
>>=20
>> Reading symbols from a.out...done.
>> (gdb) br *0x00000000500279ac
>> Breakpoint 1 at 0x500279ac
>> (gdb) run
>> Starting program: /root/c_tests/a.out=20
>>=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)
>>=20
>> . . .
>>=20
>> (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
>>=20
>> Note: Below is from plt :
>>=20
>> 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
>>=20
>> (By setting breakpoints in the 3 such .plt code blocks:
>> this is the first .plt code block executed and it fails.)
>>=20
>> 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.
>>=20
>> Back to gdb based information:
>>=20
>> (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
>>=20
>> (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
>>=20
>> Program received signal SIGSEGV, Segmentation fault.
>> 0x000000001001056c in ?? ()
>> 1: x/i $pc
>> =3D> 0x1001056c:	ld      r11,0(r12)
>>=20
>> The source code (from lib/csu/powerpc64/crt1.c ) is:
>>=20
>> void
>> _start(int argc, char **argv, char **env,
>> const struct Struct_Obj_Entry *obj __unused, void (*cleanup)(void),
>> struct ps_strings *ps_strings)
>> {
>>=20
>>  handle_argv(argc, argv, env);
>>=20
>>  if (ps_strings !=3D (struct ps_strings *)0)
>>          __ps_strings =3D ps_strings;
>>=20
>>  if (&_DYNAMIC !=3D NULL)
>>          atexit(cleanup);
>>  else
>>          _init_tls();
>>=20
>> #ifdef GCRT
>>  atexit(_mcleanup);
>>  monstartup(&eprol, &etext);
>> #endif
>>=20
>>  handle_static_init(argc, argv, env);
>>  exit(main(argc, argv, env));
>> }
>>=20
>> The 3 plt code blocks are for:
>>=20
>> atexit
>> _init_tls
>> exit
>>=20
>> from what I can tell, possibly not in that order.
>>=20
>> Overall: The plt handling seems to be broken.
>>=20
>>=20
>>> 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.
>>=20
>> # 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})
>>=20
>> 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/ .
>>=20
>>=20
>> =3D=3D=3D
>> Mark Millard
>> markmi at dsl-only.net
>=20
> _______________________________________________
> freebsd-toolchain@freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-toolchain
> To unsubscribe, send any mail to =
"freebsd-toolchain-unsubscribe@freebsd.org"

_______________________________________________
freebsd-toolchain@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-toolchain
To unsubscribe, send any mail to =
"freebsd-toolchain-unsubscribe@freebsd.org"

_______________________________________________
freebsd-toolchain@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-toolchain
To unsubscribe, send any mail to =
"freebsd-toolchain-unsubscribe@freebsd.org"

_______________________________________________
freebsd-toolchain@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-toolchain
To unsubscribe, send any mail to =
"freebsd-toolchain-unsubscribe@freebsd.org"

_______________________________________________
freebsd-toolchain@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-toolchain
To unsubscribe, send any mail to =
"freebsd-toolchain-unsubscribe@freebsd.org"




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?27422F1B-6906-4D37-860A-D1BC8DC83BBF>