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 .

===
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.]
> 
> On 2017-Jan-16, at 3:28 PM, Mark Millard <mar...@dsl-only.net> wrote:
> 
>> Looking up definitions of the section naming
>> (using http://www.cs.stevens.edu/~jschauma/810/elf.html ). . .
>> (Intel context)
>> 
>> 
>> 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:
>> 
>> GNU_RELRO:
>> 
>> 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.
>> 
>> BUT NOTE: The ld.lld output has .jcr section in the RELRO segment and the 
>> .dynamic just after it.
> 
> 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.
> 
>> Showing the objdump output for RELRO:
>> 
>>  RELRO off    0x0000000000020000 vaddr 0x0000000010020000 paddr 
>> 0x0000000010020000 align 2**0
>>        filesz 0x0000000000000138 memsz 0x0000000000000138 flags r--
>> 
>> .got.plt and .toc do not go in the RELRO segment.
>> 
>> 
>> Quoting section descriptions. . .
>> 
>> 
>> .rela.plt:
>> 
>> 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.
>> 
>> 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.
>> 
>> Simply put, this table holds information to relocate entries in .got.plt 
>> section.
>> 
>> 
>> .got:
>> For dynamic binaries, this Global Offset Table holds the addresses of 
>> variables which are relocated upon loading.
>> 
>> [Note: .got was empty because of a lack of global variables. But it
>> was still present.]
>> 
>> 
>> .got.plt:
>> 
>> 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.
>> 
>> 
>> .toc:
>> 
>> Was not listed. (Likely powerpc64 and/or powerpc specific.)
>> 
>> 
>> 
>> So ld.lld is keeping the .got with the other RELRO materials,
>> as it is supposed to.
>> 
>> And is setting up to allow lazy binding (.got.plt).
>> 
>> 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.
>> 
>> 
>> 
>> As far as I can tell the powerpc and powerpc64 FreeBSD code is
>> not set up for any variation of such things.
>> 
>> It may be that changes are needed to allow RELRO with the .got
>> inside, for example.
>> 
>> 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.
> 
> 
> ===
> 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     <<<<<===== note
        0x0000000010000468 - 0x0000000010000474 is .eh_frame_hdr
        0x0000000010010000 - 0x00000000100104f8 is .text
        0x0000000010010500 - 0x000000001001052c is .init
        0x0000000010010530 - 0x0000000010010554 is .fini
        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!!!!
        0x00000000100300a0 - 0x0000000010030160 is .opd
        0x0000000010030160 - 0x0000000010030170 is .bss

It matches the readelf and objdump output reports.

===
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:
> 
>> I think the TOC (.got + .plt) has to be contiguous in memory. The on-disk
>> layout is not that important.
> 
> 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.
> 
> (Later in repsonse t your question I show what I expect is a sufficient
> confirmation.)
> 
> Note: objdump and readelf agree (VMA and LMA). Here is the objdump
> equivalent:
> 
> 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
> . . .
> 
> 
>> Can you check whats the difference of the in-memory TOC between lld and 
>> ld.bfd?
> 
> 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.
> 
> 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.
> 
> 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.)
> 
> 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
> 
> Examples of gdb reporting symbol information for some of those addresses:
> 
> (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
> 
> ld.lld (as configured?) just does not set up for the sections to have
> the property:
> 
> .got, .toc, .tocbss, .plt in that order
> 
> (in memory) and ld.lld (as configured?) puts out sections that ld.bfd
> does not:
> 
> .got.plt
> .toc
> 
> 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.
> 
===
Mark Millard
markmi at dsl-only.net

On Fri, Jan 13, 2017 at 02:07:00PM -0800, Mark Millard wrote:
> Just an FYI:
> 
> elfdump -a (from -r311950) does not dump .plt or .got.plt or .toc :
> 
> # 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):
> 
> (The "global offset table" was empty but its title was listed.)
> 
> ===
> Mark Millard
> markmi at dsl-only.net
> 
> On 2017-Jan-12, at 5:58 PM, Mark Millard <markmi at dsl-only.net> wrote:
> 
> On 2017-Jan-12, at 11:22 AM, Roman Divacky <rdivacky at vlakno.cz> wrote:
> 
>> Can you check if the TOC is correct? LLD assumes this:
>> 
>> static uint64_t PPC64TocOffset = 0x8000;
>> 
>> 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 = In<ELF64BE>::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;
>> }
> 
> [I warn that I'm outside familiar territory here.]
> 
> If I understand the 1st comment right the following does not look
> like a match for -fuse-dl=lld (readelf -a output):
> 
> 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
> 
> Possibly contributing reasons:
> 
> 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.
> 
> [I guess that .rela.plt does not matter but I showed it
> in case I'm wrong.]
> 
> 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.
> 
> 
> By contrast for -fuse-dl-bfd I see:
> 
> 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
> 
> So no .toc or .tocbase sections.
> 
> 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.
> 
> So my guess is that -fuse-dl-bfd looks to be as expected,
> unlike -fuse-dl=lld .
> 
> 
>> 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:
>> 
>> // 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.
>> 
>> 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).
>> 
>> I suspect there might be some Linux vs FreeBSD difference that prevents this 
>> from working.
>> 
>> Roman
> 
> ===
> Mark Millard
> markmi at dsl-only.net
> 
> 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:
>> 
>>> On 11 January 2017 at 21:06, Roman Divacky <rdivacky at vlakno.cz> wrote:
>>>> Looks like a progress :) Three questions...
>>>> 
>>>> Is the readelf -a reasonable now?
>>> 
>>> 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 
>> 
>> 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
>> => 0x00000000500279b0 <+128>:        li      r0,1
>> 0x00000000500279b4 <+132>:   sc      
>> 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 
>> 
>> 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=bfd 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 
>> 
>> 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) 
>> 0x0000000010010004 in ?? ()
>> (gdb) display/i $pc
>> 1: x/i $pc
>> => 0x10010004:       mfcr    r12
>> (gdb) stepi
>> 0x0000000010010008 in ?? ()
>> 1: x/i $pc
>> => 0x10010008:       std     r31,-8(r1)
>> (gdb) 
>> 0x000000001001000c in ?? ()
>> 1: x/i $pc
>> => 0x1001000c:       std     r0,16(r1)
>> 
>> . . .
>> 
>> (gdb) 
>> 0x00000000100100a0 in ?? ()
>> 1: x/i $pc
>> => 0x100100a0:       beq     0x100100ac
>> (gdb) 
>> 0x00000000100100ac in ?? ()
>> 1: x/i $pc
>> => 0x100100ac:       cmpldi  r8,0
>> (gdb) 
>> 0x00000000100100b0 in ?? ()
>> 1: x/i $pc
>> => 0x100100b0:       beq     0x100100c0
>> (gdb) 
>> 0x00000000100100c0 in ?? ()
>> 1: x/i $pc
>> => 0x100100c0:       addis   r3,r2,0
>> (gdb) 
>> 0x00000000100100c4 in ?? ()
>> 1: x/i $pc
>> => 0x100100c4:       ld      r3,32552(r3)
>> (gdb) 
>> 0x00000000100100c8 in ?? ()
>> 1: x/i $pc
>> => 0x100100c8:       cmpldi  r3,0
>> (gdb) 
>> 0x00000000100100cc in ?? ()
>> 1: x/i $pc
>> => 0x100100cc:       beq     0x100100e0
>> (gdb) 
>> 0x00000000100100d0 in ?? ()
>> 1: x/i $pc
>> => 0x100100d0:       mr      r3,r7
>> (gdb) 
>> 0x00000000100100d4 in ?? ()
>> 1: x/i $pc
>> => 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) <<<<<===== 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) 
>> 0x0000000010010560 in ?? ()
>> 1: x/i $pc
>> => 0x10010560:       std     r2,40(r1)
>> (gdb) 
>> 0x0000000010010564 in ?? ()
>> 1: x/i $pc
>> => 0x10010564:       addis   r11,r2,0
>> (gdb) 
>> 0x0000000010010568 in ?? ()
>> 1: x/i $pc
>> => 0x10010568:       ld      r12,32512(r11)
>> (gdb) 
>> 0x000000001001056c in ?? ()
>> 1: x/i $pc
>> => 0x1001056c:       ld      r11,0(r12)
>> (gdb) 
>> 
>> Program received signal SIGSEGV, Segmentation fault.
>> 0x000000001001056c in ?? ()
>> 1: x/i $pc
>> => 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 != (struct ps_strings *)0)
>>          __ps_strings = ps_strings;
>> 
>>  if (&_DYNAMIC != 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+=-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
>> ===================================================================
>> --- /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=         rtld.1
>> CSTD?=               gnu99
>> +CFLAGS+=-DDEBUG
>> CFLAGS+=     -Wall -DFREEBSD_ELF -DIN_RTLD -ffreestanding
>> CFLAGS+=     -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/ .
>> 
>> 
>> ===
>> Mark Millard
>> markmi at dsl-only.net
> 
> _______________________________________________
> freebsd-toolchain@freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-toolchain
> To unsubscribe, send any mail to "freebsd-toolchain-unsubscr...@freebsd.org"

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

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

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

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

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

Reply via email to