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

2017-01-20 Thread Mark Millard
On 2017-Jan-20, at 3:19 PM, Mark Millard  wrote:

> FYI: The code that is put in the .plt that does not
> match the .got.plt layout used (expecting function
> descriptors when there are only single addresses per
> function as a .got.plt entry) is:
> 
> void PPC64TargetInfo::writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
>   uint64_t PltEntryAddr, int32_t Index,
>   unsigned RelOff) const {
>  uint64_t Off = GotEntryAddr - getPPC64TocBase();
> 
>  // 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.
> 
>  write32be(Buf,  0xf8410028);   // std %r2, 40(%r1)
>  write32be(Buf + 4,  0x3d62 | applyPPCHa(Off)); // addis %r11, %r2, X@ha
>  write32be(Buf + 8,  0xe98b | applyPPCLo(Off)); // ld %r12, X@l(%r11)
>  write32be(Buf + 12, 0xe96c);   // ld %r11,0(%r12)
>  write32be(Buf + 16, 0x7d6903a6);   // mtctr %r11
>  write32be(Buf + 20, 0xe84c0008);   // ld %r2,8(%r12)
>  write32be(Buf + 24, 0xe96c0010);   // ld %r11,16(%r12)
>  write32be(Buf + 28, 0x4e800420);   // bctr
> }
> 
> Either the .got.plt entry layout changes to have room
> for 8(r12) and 16(r12) positions (size change to 0x18
> Bytes per entryr) or this code (and possibly other
> code) changes --presuming .got.plt style is used at
> all. (I've not found any powerpc family documentation
> for .got.plt use.)
> 
> Unlike what the comment says this code does not reference
> the .opd section at all as things are right now. See the
> prior Email content below for the details as in the
> example used. It references the .got.plt and the .toc
> section via r12 in the example (the size mismatch
> from the layout mismatch).

It looks like the other side of this that is not establishing
space for function descriptors is in the code in:

/usr/src/contrib/llvm/tools/lld/ELF/Relocations.cpp

in its scanRelocs :

// At this point we are done with the relocated position. Some relocations
// also require us to create a got or plt entry.

// If a relocation needs PLT, we create a PLT and a GOT slot for the symbol.
if (needsPlt(Expr)) {
  if (Body.isInPlt())
continue;
  Out::Plt->addEntry(Body);
  
  uint32_t Rel;
  if (Body.isGnuIFunc() && !Preemptible)
Rel = Target->IRelativeRel;
  else
Rel = Target->PltRel;

  Out::GotPlt->addEntry(Body);
  Out::RelaPlt->addReloc({Rel, Out::GotPlt,
Body.getGotPltOffset(), !Preemptible,
, 0});
  continue;
}

The code is explicitly targeting creating GotPlt space, not
.opd space, as well.

The effect of such code and the wrtPlt code need to be
correctly matching but currently are not.

[I'm likely telling you want you already know. But for me
these are finds that took a fair amount of time to discover:
very unfamiliar source code.]

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

On 2017-Jan-20, at 12:54 AM, Mark Millard  wrote:

> I did a bunch more investigation and have 4 major points
> that I think I've established:
> 
> First off: I've still not found a single example
> of a document's coverage of powerpc64 (or powerpc) that
> deals with the .got vs. .got.plt split [.got in RELRO region
> but .got.plt possibly not (lazy relocation then allowed)].
> Everything that I have found is specific to Intel architecture
> for that split. There may be no defined powerpc64 ABI that uses
> .got.plt. If so then ld.lld's use of .got.plt for powerpc64 may
> be an ABI violation (for all powerpc64 ABIs).
> 
> Secondly: The (nonppc) references that I've found indicate
> that RELRO+-PIE+-fPIE sorts of contexts for .got.plt usage.
> .got.plt may be in the RELRO region if lazy relocation
> is t be disallowed but .got.plt is not in the RELRO
> region when lazy relocation is allowed. I've not
> found references to .got.plt for when there is no RELRO.
> Nor when there is no PIE.
> 
> Thirdly: a.out from ld.lld is not using function
> descriptors or its 3 fields. The .plt is blocks
> of code and the relocated addresses are in the
> .got.plt --without room for the function
> descriptors. /usr/src/libexec/rtld-elf/powerpc64/reloc.c
> has no code for the ld.lld .plt / .got.plt pairing
> that ld.lld outputs in a.out, not in the likes of its
> reloc_jmpslots, reloc_jmpslot, or reloc_plt. reloc.c
> is trashing memory by putting function descriptor
> content in place when it should not from what I can
> tell.
> 
> Fourthly: Got is correct and the GotPlt and Plt
> alternatives are wrong for in uint64_t getPPC64TocBase() .
> (Sorry I 

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

2017-01-20 Thread Mark Millard
FYI: The code that is put in the .plt that does not
match the .got.plt layout used (expecting function
descriptors when there are only single addresses per
function as a .got.plt entry) is:

void PPC64TargetInfo::writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
   uint64_t PltEntryAddr, int32_t Index,
   unsigned RelOff) const {
  uint64_t Off = GotEntryAddr - getPPC64TocBase();

  // 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.
  
  write32be(Buf,  0xf8410028);   // std %r2, 40(%r1)
  write32be(Buf + 4,  0x3d62 | applyPPCHa(Off)); // addis %r11, %r2, X@ha
  write32be(Buf + 8,  0xe98b | applyPPCLo(Off)); // ld %r12, X@l(%r11)
  write32be(Buf + 12, 0xe96c);   // ld %r11,0(%r12)
  write32be(Buf + 16, 0x7d6903a6);   // mtctr %r11
  write32be(Buf + 20, 0xe84c0008);   // ld %r2,8(%r12)
  write32be(Buf + 24, 0xe96c0010);   // ld %r11,16(%r12)
  write32be(Buf + 28, 0x4e800420);   // bctr
}

Either the .got.plt entry layout changes to have room
for 8(r12) and 16(r12) positions (size change to 0x18
Bytes per entryr) or this code (and possibly other
code) changes --presuming .got.plt style is used at
all. (I've not found any powerpc family documentation
for .got.plt use.)

Unlike what the comment says this code does not reference
the .opd section at all as things are right now. See the
prior Email content below for the details as in the
example used. It references the .got.plt and the .toc
section via r12 in the example (the size mismatch
from the layout mismatch).


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

On 2017-Jan-20, at 12:54 AM, Mark Millard  wrote:

> I did a bunch more investigation and have 4 major points
> that I think I've established:
> 
> First off: I've still not found a single example
> of a document's coverage of powerpc64 (or powerpc) that
> deals with the .got vs. .got.plt split [.got in RELRO region
> but .got.plt possibly not (lazy relocation then allowed)].
> Everything that I have found is specific to Intel architecture
> for that split. There may be no defined powerpc64 ABI that uses
> .got.plt. If so then ld.lld's use of .got.plt for powerpc64 may
> be an ABI violation (for all powerpc64 ABIs).
> 
> Secondly: The (nonppc) references that I've found indicate
> that RELRO+-PIE+-fPIE sorts of contexts for .got.plt usage.
> .got.plt may be in the RELRO region if lazy relocation
> is t be disallowed but .got.plt is not in the RELRO
> region when lazy relocation is allowed. I've not
> found references to .got.plt for when there is no RELRO.
> Nor when there is no PIE.
> 
> Thirdly: a.out from ld.lld is not using function
> descriptors or its 3 fields. The .plt is blocks
> of code and the relocated addresses are in the
> .got.plt --without room for the function
> descriptors. /usr/src/libexec/rtld-elf/powerpc64/reloc.c
> has no code for the ld.lld .plt / .got.plt pairing
> that ld.lld outputs in a.out, not in the likes of its
> reloc_jmpslots, reloc_jmpslot, or reloc_plt. reloc.c
> is trashing memory by putting function descriptor
> content in place when it should not from what I can
> tell.
> 
> Fourthly: Got is correct and the GotPlt and Plt
> alternatives are wrong for in uint64_t getPPC64TocBase() .
> (Sorry I sent you in the wrong direction for this area.)
> 
> The rest of this note is related the "fourthly" and
> "thirdly" above but is only relevant if more detail
> is wanted.
> 
> 
> I deal with "fourthly" first. . .
> 
> I was wrong about Got vs. Plt vs. GotPlt in:
> 
> uint64_t getPPC64TocBase()
> 
> as for as what the code should reference: I've solid
> evidence that Got is correct. One part of that is
> what I'll present here as it should be sufficient:
> 
> Got stops during /usr/src/libexec/rtld-elf/powerpc64/rtld_start.S:104 called 
> code
> Plt stops during /usr/src/libexec/rtld-elf/powerpc64/rtld_start.S:83 called 
> code
> GotPlt stops during /usr/src/libexec/rtld-elf/powerpc64/rtld_start.S:83 
> called code
> 
> The Got case executed the rtld_start.S:83 related code correctly
> and later fails. (I've traced relevant code under gdb.)
> 
> So the below is based on analyzing the Got variant.
> 
> 
> Now for "thirdly" (lack of function descriptors in .plt). . .
> 
> A ld.bfd vs. ld.lld difference is the r_offset differences
> are smaller in ld.bfd and larger in ld.lld and the relocations are
> in different sections: a.out from ld.lld is not using function
> descriptors or its 3 fields. . .
> 
> For ld.bfd's generated a.out:
> 
> Relocation section with addend (.rela.plt):
> r_offset r_info   

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

2017-01-20 Thread Mark Millard
I did a bunch more investigation and have 4 major points
that I think I've established:

First off: I've still not found a single example
of a document's coverage of powerpc64 (or powerpc) that
deals with the .got vs. .got.plt split [.got in RELRO region
but .got.plt possibly not (lazy relocation then allowed)].
Everything that I have found is specific to Intel architecture
for that split. There may be no defined powerpc64 ABI that uses
.got.plt. If so then ld.lld's use of .got.plt for powerpc64 may
be an ABI violation (for all powerpc64 ABIs).

Secondly: The (nonppc) references that I've found indicate
that RELRO+-PIE+-fPIE sorts of contexts for .got.plt usage.
.got.plt may be in the RELRO region if lazy relocation
is t be disallowed but .got.plt is not in the RELRO
region when lazy relocation is allowed. I've not
found references to .got.plt for when there is no RELRO.
Nor when there is no PIE.

Thirdly: a.out from ld.lld is not using function
descriptors or its 3 fields. The .plt is blocks
of code and the relocated addresses are in the
.got.plt --without room for the function
descriptors. /usr/src/libexec/rtld-elf/powerpc64/reloc.c
has no code for the ld.lld .plt / .got.plt pairing
that ld.lld outputs in a.out, not in the likes of its
reloc_jmpslots, reloc_jmpslot, or reloc_plt. reloc.c
is trashing memory by putting function descriptor
content in place when it should not from what I can
tell.

Fourthly: Got is correct and the GotPlt and Plt
alternatives are wrong for in uint64_t getPPC64TocBase() .
(Sorry I sent you in the wrong direction for this area.)

The rest of this note is related the "fourthly" and
"thirdly" above but is only relevant if more detail
is wanted.


I deal with "fourthly" first. . .

I was wrong about Got vs. Plt vs. GotPlt in:

uint64_t getPPC64TocBase()

as for as what the code should reference: I've solid
evidence that Got is correct. One part of that is
what I'll present here as it should be sufficient:

Got stops during /usr/src/libexec/rtld-elf/powerpc64/rtld_start.S:104 called 
code
Plt stops during /usr/src/libexec/rtld-elf/powerpc64/rtld_start.S:83 called code
GotPlt stops during /usr/src/libexec/rtld-elf/powerpc64/rtld_start.S:83 called 
code

The Got case executed the rtld_start.S:83 related code correctly
and later fails. (I've traced relevant code under gdb.)

So the below is based on analyzing the Got variant.


Now for "thirdly" (lack of function descriptors in .plt). . .

A ld.bfd vs. ld.lld difference is the r_offset differences
are smaller in ld.bfd and larger in ld.lld and the relocations are
in different sections: a.out from ld.lld is not using function
descriptors or its 3 fields. . .

For ld.bfd's generated a.out:

Relocation section with addend (.rela.plt):
r_offset r_info   r_type  st_value st_name + 
r_addend
100218b0 00030015 R_PPC64_JMP_SLOT atexit + 0
100218c8 00040015 R_PPC64_JMP_SLOT _init_tls + 0
100218e0 00060015 R_PPC64_JMP_SLOT exit + 0

is an increment of 0x18 between entries (room for the
function descriptors). The r_offset's are from the
ld.bfd generated .plt section:

0x10021898 - 0x100218f8 is .plt

(gdb) x/12gx 0x10021898
0x10021898: 0x500189f0  0x50058f00
0x100218a8: 0x5003d000  0x5021a7e0
0x100218b8: 0x50299900  0x
0x100218c8: 0x1988  0x
0x100218d8: 0x  0x1990
0x100218e8: 0x  0x
(gdb) info symbol 0x5021a7e0
.atexit in section .text of /lib/libc.so.7
(gdb) info symbol 0x1988
_init_tls@plt in section .text of /root/c_tests/a.out
(gdb) info symbol 0x1990
exit@plt in section .text of /root/c_tests/a.out

NOTE: The .plt contains no code, just function descriptors.

By comparison for what ld.lld generated:

Relocation section with addend (.rela.plt):
r_offset r_info   r_type  st_value st_name + 
r_addend
10030038 00030015 R_PPC64_JMP_SLOT atexit + 0
10030040 00020015 R_PPC64_JMP_SLOT _init_tls + 0
10030048 00050015 R_PPC64_JMP_SLOT exit + 0

These r_offset's are in the .got.plt area, not in the .plt area:

0x10030020 - 0x10030050 is .got.plt

The increment is 0x8 between entries, not 0x18. There are no
function descriptor here.

The actual content from the /usr/src/libexec/rtld-elf/powerpc64/reloc.c
code results ends up being as shown:

(gdb) x/6gx 0x10030038
0x10030038: 0x0020  0x0028
0x10030048: 0x0030  0x10030168
0x10030058: 0x10030160  0x10020028

which appears to be incorrect for how the 0(r12) code is used
buy the .plt code (shown below) and leads to the crash. 

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

2017-01-19 Thread Roman Divacky
Type = 38 should be R_ABS so thats fine. If what I expected to be in .got
is in .got.plt, what happens if you modify the getPPC64TocBase() to
use ::GotPlt instead of ::Got ?


On Thu, Jan 19, 2017 at 01:46:02AM -0800, Mark Millard wrote:
> I should have noted that -pie gets the same sort of
> readonly segment errors as -shared did:
> 
> # clang -fuse-ld=lld -g -pie empty_src.c
> Type = 50
> Type = 64
> Type = 50
> Type = 64
> Type = 50
> Type = 64
> Type = 50
> Type = 64
> Type = 50
> Type = 64
> Type = 10
> Type = 10
> Type = 50
> Type = 64
> Type = 50
> Type = 48
> Type = 10
> Type = 50
> Type = 50
> Type = 48
> Type = 48
> Type = 50
> Type = 48
> Type = 50
> Type = 50
> Type = 48
> Type = 48
> Type = 50
> Type = 50
> Type = 48
> Type = 48
> Type = 10
> can't create dynamic relocation R_PPC64_REL24 against readonly segment
> Type = 50
> Type = 48
> Type = 50
> Type = 50
> Type = 48
> Type = 48
> Type = 10
> can't create dynamic relocation R_PPC64_REL24 against readonly segment
> Type = 10
> Type = 50
> Type = 50
> Type = 48
> Type = 48
> Type = 50
> Type = 50
> Type = 48
> Type = 48
> Type = 10
> can't create dynamic relocation R_PPC64_REL24 against readonly segment
> Type = 38
> Unhandled type = 38
> Type = 51
> Type = 38
> Unhandled type = 38
> Type = 51
> Type = 38
> Unhandled type = 38
> Type = 38
> Unhandled type = 38
> Type = 38
> Unhandled type = 38
> Type = 38
> Unhandled type = 38
> Type = 38
> Unhandled type = 38
> Type = 38
> Unhandled type = 38
> Type = 51
> Type = 38
> Unhandled type = 38
> Type = 51
> Type = 50
> Type = 48
> Type = 50
> Type = 64
> Type = 50
> Type = 64
> Type = 10
> Type = 50
> Type = 64
> Type = 50
> Type = 64
> Type = 64
> Type = 50
> Type = 48
> Type = 50
> Type = 64
> Type = 50
> Type = 64
> Type = 50
> Type = 48
> Type = 10
> can't create dynamic relocation R_PPC64_REL24 against readonly segment
> Type = 10
> can't create dynamic relocation R_PPC64_REL24 against readonly segment
> Type = 38
> Unhandled type = 38
> Type = 51
> Type = 38
> Unhandled type = 38
> Type = 51
> Type = 38
> Unhandled type = 38
> Type = 38
> Unhandled type = 38
> Type = 38
> Unhandled type = 38
> Type = 38
> Unhandled type = 38
> Type = 50
> Type = 48
> Type = 50
> Type = 48
> Type = 10
> can't create dynamic relocation R_PPC64_REL24 against readonly segment
> Type = 38
> Unhandled type = 38
> Type = 51
> undefined symbol: main in /usr/lib/Scrt1.o
> clang: error: linker command failed with exit code 1 (use -v to see 
> invocation)
> 
> # more main.c
> int main ()
> {
> }
> # clang -fuse-ld=lld -g -pie main.c
> Type = 50
> Type = 64
> Type = 50
> Type = 64
> Type = 50
> Type = 64
> Type = 50
> Type = 64
> Type = 50
> Type = 64
> Type = 10
> Type = 10
> Type = 50
> Type = 64
> Type = 50
> Type = 48
> Type = 10
> Type = 50
> Type = 50
> Type = 48
> Type = 48
> Type = 50
> Type = 48
> Type = 50
> Type = 50
> Type = 48
> Type = 48
> Type = 50
> Type = 50
> Type = 48
> Type = 48
> Type = 10
> can't create dynamic relocation R_PPC64_REL24 against readonly segment
> Type = 50
> Type = 48
> Type = 50
> Type = 50
> Type = 48
> Type = 48
> Type = 10
> can't create dynamic relocation R_PPC64_REL24 against readonly segment
> Type = 10
> Type = 50
> Type = 50
> Type = 48
> Type = 48
> Type = 50
> Type = 50
> Type = 48
> Type = 48
> Type = 10
> can't create dynamic relocation R_PPC64_REL24 against readonly segment
> Type = 38
> Unhandled type = 38
> Type = 51
> Type = 38
> Unhandled type = 38
> Type = 51
> Type = 38
> Unhandled type = 38
> Type = 38
> Unhandled type = 38
> Type = 38
> Unhandled type = 38
> Type = 38
> Unhandled type = 38
> Type = 38
> Unhandled type = 38
> Type = 38
> Unhandled type = 38
> Type = 51
> Type = 38
> Unhandled type = 38
> Type = 51
> Type = 50
> Type = 48
> Type = 50
> Type = 64
> Type = 50
> Type = 64
> Type = 10
> Type = 50
> Type = 64
> Type = 50
> Type = 64
> Type = 64
> Type = 50
> Type = 48
> Type = 50
> Type = 64
> Type = 50
> Type = 64
> Type = 50
> Type = 48
> Type = 10
> can't create dynamic relocation R_PPC64_REL24 against readonly segment
> Type = 10
> can't create dynamic relocation R_PPC64_REL24 against readonly segment
> Type = 38
> Unhandled type = 38
> Type = 51
> Type = 38
> Unhandled type = 38
> Type = 51
> Type = 38
> Unhandled type = 38
> Type = 38
> Unhandled type = 38
> Type = 38
> Unhandled type = 38
> Type = 38
> Unhandled type = 38
> Type = 38
> Unhandled type = 38
> Type = 51
> Type = 50
> Type = 48
> Type = 50
> Type = 48
> Type = 10
> can't create dynamic relocation R_PPC64_REL24 against readonly segment
> Type = 38
> Unhandled type = 38
> Type = 51
> clang: error: linker command failed with exit code 1 (use -v to see 
> invocation)
> 
> 
> So making something with a relocatable global variable is problematical
> via lld.
> 
> ===
> Mark Millard
> markmi at dsl-only.net
> 
> On 2017-Jan-18, at 10:48 PM, Mark Millard  wrote:
> 
> The log messages code does not work because of Assertion failures:
> 
> # clang -fuse-ld=lld -g main.c
> Type = 50, name = 

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

2017-01-19 Thread Mark Millard
I should have noted that -pie gets the same sort of
readonly segment errors as -shared did:

# clang -fuse-ld=lld -g -pie empty_src.c
Type = 50
Type = 64
Type = 50
Type = 64
Type = 50
Type = 64
Type = 50
Type = 64
Type = 50
Type = 64
Type = 10
Type = 10
Type = 50
Type = 64
Type = 50
Type = 48
Type = 10
Type = 50
Type = 50
Type = 48
Type = 48
Type = 50
Type = 48
Type = 50
Type = 50
Type = 48
Type = 48
Type = 50
Type = 50
Type = 48
Type = 48
Type = 10
can't create dynamic relocation R_PPC64_REL24 against readonly segment
Type = 50
Type = 48
Type = 50
Type = 50
Type = 48
Type = 48
Type = 10
can't create dynamic relocation R_PPC64_REL24 against readonly segment
Type = 10
Type = 50
Type = 50
Type = 48
Type = 48
Type = 50
Type = 50
Type = 48
Type = 48
Type = 10
can't create dynamic relocation R_PPC64_REL24 against readonly segment
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 51
Type = 50
Type = 48
Type = 50
Type = 64
Type = 50
Type = 64
Type = 10
Type = 50
Type = 64
Type = 50
Type = 64
Type = 64
Type = 50
Type = 48
Type = 50
Type = 64
Type = 50
Type = 64
Type = 50
Type = 48
Type = 10
can't create dynamic relocation R_PPC64_REL24 against readonly segment
Type = 10
can't create dynamic relocation R_PPC64_REL24 against readonly segment
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 50
Type = 48
Type = 50
Type = 48
Type = 10
can't create dynamic relocation R_PPC64_REL24 against readonly segment
Type = 38
Unhandled type = 38
Type = 51
undefined symbol: main in /usr/lib/Scrt1.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)

# more main.c
int main ()
{
}
# clang -fuse-ld=lld -g -pie main.c
Type = 50
Type = 64
Type = 50
Type = 64
Type = 50
Type = 64
Type = 50
Type = 64
Type = 50
Type = 64
Type = 10
Type = 10
Type = 50
Type = 64
Type = 50
Type = 48
Type = 10
Type = 50
Type = 50
Type = 48
Type = 48
Type = 50
Type = 48
Type = 50
Type = 50
Type = 48
Type = 48
Type = 50
Type = 50
Type = 48
Type = 48
Type = 10
can't create dynamic relocation R_PPC64_REL24 against readonly segment
Type = 50
Type = 48
Type = 50
Type = 50
Type = 48
Type = 48
Type = 10
can't create dynamic relocation R_PPC64_REL24 against readonly segment
Type = 10
Type = 50
Type = 50
Type = 48
Type = 48
Type = 50
Type = 50
Type = 48
Type = 48
Type = 10
can't create dynamic relocation R_PPC64_REL24 against readonly segment
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 51
Type = 50
Type = 48
Type = 50
Type = 64
Type = 50
Type = 64
Type = 10
Type = 50
Type = 64
Type = 50
Type = 64
Type = 64
Type = 50
Type = 48
Type = 50
Type = 64
Type = 50
Type = 64
Type = 50
Type = 48
Type = 10
can't create dynamic relocation R_PPC64_REL24 against readonly segment
Type = 10
can't create dynamic relocation R_PPC64_REL24 against readonly segment
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 51
Type = 50
Type = 48
Type = 50
Type = 48
Type = 10
can't create dynamic relocation R_PPC64_REL24 against readonly segment
Type = 38
Unhandled type = 38
Type = 51
clang: error: linker command failed with exit code 1 (use -v to see invocation)


So making something with a relocatable global variable is problematical
via lld.

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

On 2017-Jan-18, at 10:48 PM, Mark Millard  wrote:

The log messages code does not work because of Assertion failures:

# clang -fuse-ld=lld -g main.c
Type = 50, name = Assertion failed: (!isLocal()), function getName, file 
/usr/src/contrib/llvm/tools/lld/ELF/Symbols.cpp, line 100.
clang: error: unable to execute command: Abort trap (core dumped)
clang: error: linker command failed due to signal (use -v to see invocation)

So for now I've disabled the name part of the line. At least we will
see the numeric type of each and the reports of any "unhandled" values.

I decided to use the Got variation instead of the Plt variant first.

Some examples:

# more empty_src.c

# clang -fuse-ld=lld -g -shared -o empty_src.so empty_src.c
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 51
Type = 50
Type = 48
Type = 50
Type = 64
Type = 50
Type = 64
Type = 10
Type = 50
Type = 64
Type = 50
Type = 64
Type = 64
Type = 50
Type = 48

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

2017-01-18 Thread Mark Millard
The log messages code does not work because of Assertion failures:

# clang -fuse-ld=lld -g main.c
Type = 50, name = Assertion failed: (!isLocal()), function getName, file 
/usr/src/contrib/llvm/tools/lld/ELF/Symbols.cpp, line 100.
clang: error: unable to execute command: Abort trap (core dumped)
clang: error: linker command failed due to signal (use -v to see invocation)

So for now I've disabled the name part of the line. At least we will
see the numeric type of each and the reports of any "unhandled" values.

I decided to use the Got variation instead of the Plt variant first.

Some examples:

# more empty_src.c

# clang -fuse-ld=lld -g -shared -o empty_src.so empty_src.c
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 51
Type = 50
Type = 48
Type = 50
Type = 64
Type = 50
Type = 64
Type = 10
Type = 50
Type = 64
Type = 50
Type = 64
Type = 64
Type = 50
Type = 48
Type = 50
Type = 64
Type = 50
Type = 64
Type = 50
Type = 48
Type = 10
can't create dynamic relocation R_PPC64_REL24 against readonly segment
Type = 10
can't create dynamic relocation R_PPC64_REL24 against readonly segment
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 50
Type = 48
Type = 50
Type = 48
Type = 10
can't create dynamic relocation R_PPC64_REL24 against readonly segment
Type = 38
Unhandled type = 38
Type = 51
clang: error: linker command failed with exit code 1 (use -v to see invocation)

# clang -fuse-ld=lld -g empty_src.c
Type = 50
Type = 64
Type = 50
Type = 64
Type = 50
Type = 48
Type = 50
Type = 64
Type = 50
Type = 64
Type = 50
Type = 64
Type = 10
Type = 10
Type = 50
Type = 64
Type = 50
Type = 48
Type = 10
Type = 50
Type = 50
Type = 64
Type = 64
Type = 50
Type = 64
Type = 50
Type = 50
Type = 64
Type = 64
Type = 50
Type = 50
Type = 64
Type = 64
Type = 10
Type = 50
Type = 64
Type = 50
Type = 50
Type = 64
Type = 64
Type = 10
Type = 10
Type = 50
Type = 50
Type = 64
Type = 64
Type = 50
Type = 50
Type = 64
Type = 64
Type = 10
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 51
Type = 50
Type = 48
Type = 50
Type = 64
Type = 50
Type = 64
Type = 64
Type = 50
Type = 48
Type = 50
Type = 64
Type = 50
Type = 64
Type = 50
Type = 48
Type = 10
Type = 10
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 50
Type = 48
Type = 50
Type = 48
Type = 10
Type = 38
Unhandled type = 38
Type = 51
undefined symbol: main in /usr/lib/crt1.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)

# more main.c
volatile void* gblvar = 0;

int main ()
{
gblvar = 
}

# clang -fuse-ld=lld -g main.c
Type = 50
Type = 64
Type = 50
Type = 64
Type = 50
Type = 48
Type = 50
Type = 64
Type = 50
Type = 64
Type = 50
Type = 64
Type = 10
Type = 10
Type = 50
Type = 64
Type = 50
Type = 48
Type = 10
Type = 50
Type = 50
Type = 64
Type = 64
Type = 50
Type = 64
Type = 50
Type = 50
Type = 64
Type = 64
Type = 50
Type = 50
Type = 64
Type = 64
Type = 10
Type = 50
Type = 64
Type = 50
Type = 50
Type = 64
Type = 64
Type = 10
Type = 10
Type = 50
Type = 50
Type = 64
Type = 64
Type = 50
Type = 50
Type = 64
Type = 64
Type = 10
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 51
Type = 50
Type = 48
Type = 50
Type = 64
Type = 50
Type = 64
Type = 64
Type = 50
Type = 48
Type = 50
Type = 64
Type = 50
Type = 64
Type = 50
Type = 48
Type = 10
Type = 10
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 51
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 50
Type = 48
Type = 38
Unhandled type = 38
Type = 51
Type = 50
Type = 48
Type = 50
Type = 48
Type = 10
Type = 38
Unhandled type = 38
Type = 51
Type = 1
Unhandled type = 1
Type = 1
Unhandled type = 1
Type = 1
Unhandled type = 1
Type = 1
Unhandled type = 1
Type = 1
Unhandled type = 1
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 1
Unhandled type = 1
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 38
Unhandled type = 38
Type = 1
Unhandled type = 1
Type = 1
Unhandled 

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

2017-01-18 Thread Mark Millard
Well trying to have the global variable in various forms produced
more information when I tried having it in a shared object:
(This was before your changes to add log messages.)

# more gblvar.c
volatile long gblvar = 1;

# clang -g -fuse-ld=lld -shared -o gblvar.so gblvar.c
can't create dynamic relocation R_PPC64_REL24 against readonly segment
can't create dynamic relocation R_PPC64_REL24 against readonly segment
can't create dynamic relocation R_PPC64_REL24 against readonly segment
clang: error: linker command failed with exit code 1 (use -v to see invocation)

By contrast:

# clang -g -fuse-ld=bfd -shared -o gblvar.so gblvar.c
# 

(so no problem reported).


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

On 2017-Jan-18, at 3:41 PM, Mark Millard  wrote:

On 2017-Jan-18, at 1:54 PM, Roman Divacky  wrote:

> 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.

>From what I've read: for code references the .got.plt section would
be involved when it exists, not the .got section.

> For some reason, GOT is empty, in our case.

I think that I've already explained this: lld produces two different
sections instead of just one .got section: .got and .got.plt .

.got is now for only global variables. (These can be in the
RELRO region: read-only after upfront relocation.) My program
had no global variables. If you want I can change it to have one
and use it so that the .got will not be empty.

.got.plt is for code references that allow lazy relocation.
(These can not being the the RELRO region.) Having the global
variable would not change this from what I can tell.

In the older toolchain these were both in the .got section and
the global variable relocations could not be in the RELRO region
because of the mixing in one section.

> I believe this might be caused
> by a relocation thats wrongly mapped to R_ABS in 
> PPC64TargetInfo::getRelExpr().

That is not it from what I can tell reading about what the .got.plt
section is for and why it was split from the .got section.

I think I'll add a global variable and use it so that their is no
question what goes in the .got section instead of having no examples.

I think you are not going in the right direction now for what the
.got section is for as lld is producing things for powerpc64 (not
that I'm an expert in the older or newer techniques).

> 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? 

I think that I will first add the global variable and its use
and show what the last change with Plt instead of Got ends
up looking like --but with your log notices added.

Then I'll retry with the Plt use reverted.

> 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 ) 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:

It may be a bit before I get the Plt and/or Got examples done.
I might report the Plt case first and separately, later report
the Got case.

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

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.
> 0x100104a8 in .__do_global_ctors_aux ()
> (gdb) bt
> #0  0x100104a8 in .__do_global_ctors_aux ()
> #1  0x10010518 in ._init ()
> #2  0x5002ac78 in objlist_call_init (list=, 
> lockstate=) at 

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

2017-01-17 Thread Mark Millard
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.
0x100104a8 in .__do_global_ctors_aux ()
(gdb) bt
#0  0x100104a8 in .__do_global_ctors_aux ()
#1  0x10010518 in ._init ()
#2  0x5002ac78 in objlist_call_init (list=, 
lockstate=) at /usr/src/libexec/rtld-elf/rtld.c:2541
#3  0x50029fa8 in _rtld (sp=, exit_proc=, 
objp=) at /usr/src/libexec/rtld-elf/rtld.c:668
#4  0x500279b0 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:
   0x10010470 <+0>: mflrr0
   0x10010474 <+4>: std r31,-8(r1)
   0x10010478 <+8>: std r0,16(r1)
   0x1001047c <+12>:stdur1,-128(r1)
   0x10010480 <+16>:addis   r3,r2,-1 < Note: r3 derives 
from r2
   0x10010484 <+20>:mr  r31,r1
   0x10010488 <+24>:addir3,r3,32464
   0x1001048c <+28>:std r30,112(r31)
   0x10010490 <+32>:ld  r3,-8(r3)
   0x10010494 <+36>:cmpdi   r3,-1
   0x10010498 <+40>:beq 0x100104d4 <.__do_global_ctors_aux+100>
   0x1001049c <+44>:addis   r4,r2,-1
   0x100104a0 <+48>:addir4,r4,32464
   0x100104a4 <+52>:addir30,r4,-8
=> 0x100104a8 <+56>:ld  r4,8(r3) < Note: 8(r3) 
fails.
   0x100104ac <+60>:ld  r11,16(r3)
   0x100104b0 <+64>:ld  r3,0(r3)
   0x100104b4 <+68>:std r2,40(r1)
   0x100104b8 <+72>:mr  r2,r4< Note: 8(r3) 
result should have been the new r2 value
   0x100104bc <+76>:mtctr   r3
   0x100104c0 <+80>:bctrl
   0x100104c4 <+84>:ld  r2,40(r1)
   0x100104c8 <+88>:ldu r3,-8(r30)
   0x100104cc <+92>:cmpdi   r3,-1
   0x100104d0 <+96>:bne 0x100104a8 <.__do_global_ctors_aux+56>
   0x100104d4 <+100>:   ld  r30,112(r31)
   0x100104d8 <+104>:   addir1,r1,128
   0x100104dc <+108>:   ld  r0,16(r1)
   0x100104e0 <+112>:   ld  r31,-8(r1)
   0x100104e4 <+116>:   mtlrr0
   0x100104e8 <+120>:   blr
   0x100104ec <+124>:   .long 0x0
   0x100104f0 <+128>:   .long 0x0
   0x100104f4 <+132>:   .long 0x0
End of assembler dump.
(gdb) info registers
r0 0x10010518   268502296
r1 0xcbf0   18446744073709538288
r2 0x10018560   268535136
r3 0x7ca903a64e800421   8982714944583631905
r4 0x10010430   268502064
r5 0x100300d0   268632272
r6 0x50043ab0   1342454448
r7 0x50067f00   1342603008
r8 0xdfcc   18446744073709543372
r9 0x0  0
r100x0  0
r110x0  0
r120xdfd0   18446744073709543376
r130x50057010   1342533648
r140x0  0
r150x0  0
r160x50047f00   1342471936
r170x500613e0   1342575584
r180x50253388   1344615304
r190x2  2
r200x0  0
r210x9  9
r220x0  0
r230x40 18014398509481984
r240x5004a100   1342480640
r250x5004c400   1342489600
r260xcd18   18446744073709538584
r270xcd3c   18446744073709538620
r280xcd3c   18446744073709538620
r290x0  0
r300x10010428   268502056
r310xcbf0   18446744073709538288
pc 0x100104a8   0x100104a8 <.__do_global_ctors_aux+56>
msr
cr 0x48200c00   1210059776
lr 0x10010518   0x10010518 <._init+24>
ctr0x10010500   268502272
xer0x2000   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 

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

2017-01-17 Thread Roman Divacky
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:
> 
>   0x10010560 - 0x100105c0 is .plt  <= 
> NOTE
>   0x1002 - 0x10020010 is .ctors
>   0x10020010 - 0x10020020 is .dtors
>   0x10020020 - 0x10020028 is .jcr
>   0x10020028 - 0x10020138 is .dynamic
>   0x10020138 - 0x10020138 is .got  <= 
> NOTE
>   0x1003 - 0x10030019 is .data
>   0x10030020 - 0x10030050 is .got.plt  <= 
> NOTE
>   0x10030050 - 0x100300a0 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
___
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"


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

2017-01-17 Thread Roman Divacky
Mark,

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


would make any difference? It's not correct but might shed some light on what 
needs to be done
if I am right.

Could you explore this please?

Thanks, Roman

On Mon, Jan 16, 2017 at 05:18:34PM -0800, Mark Millard wrote:
> 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  wrote:
> 
> > [Correcting a poor wording/interpetatation.]
> > 
> > On 2017-Jan-16, at 3:28 PM, Mark Millard  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 off0x0002 vaddr 0x1002 paddr 
> >> 0x1002 align 2**0
> >>filesz 0x0138 memsz 0x0138 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 

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

2017-01-16 Thread Mark Millard
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  wrote:

> [Correcting a poor wording/interpetatation.]
> 
> On 2017-Jan-16, at 3:28 PM, Mark Millard  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 off0x0002 vaddr 0x1002 paddr 
>> 0x1002 align 2**0
>>filesz 0x0138 memsz 0x0138 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  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
0x1270 - 0x1285 is .interp
0x1288 - 0x12b8 is .note.tag
0x12b8 - 0x12b9 is .rodata
0x12bc - 0x12bc is .eh_frame
0x12c0 - 0x1368 is .dynsym
0x1368 - 0x1376 is .gnu.version

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

2017-01-16 Thread Mark Millard
[Correcting a poor wording/interpetatation.]

On 2017-Jan-16, at 3:28 PM, Mark Millard  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 off0x0002 vaddr 0x1002 paddr 
> 0x1002 align 2**0
> filesz 0x0138 memsz 0x0138 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  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
0x1270 - 0x1285 is .interp
0x1288 - 0x12b8 is .note.tag
0x12b8 - 0x12b9 is .rodata
0x12bc - 0x12bc is .eh_frame
0x12c0 - 0x1368 is .dynsym
0x1368 - 0x1376 is .gnu.version
0x1378 - 0x1398 is .gnu.version_r
0x1398 - 0x13d8 is .hash
0x13d8 - 0x141a is .dynstr
0x1420 - 0x1468 is .rela.plt <= note
0x1468 - 0x1474 is .eh_frame_hdr
0x1001 - 0x100104f8 is .text
0x10010500 - 0x1001052c is .init
0x10010530 - 0x10010554 is .fini
0x10010560 - 0x100105c0 is .plt  <= 
NOTE
0x1002 - 0x10020010 is .ctors
0x10020010 - 0x10020020 is .dtors
0x10020020 - 0x10020028 is .jcr
0x10020028 - 0x10020138 is .dynamic
0x10020138 - 0x10020138 is .got  <= 
NOTE
0x1003 - 0x10030019 is .data
0x10030020 - 0x10030050 is .got.plt  <= 
NOTE
0x10030050 - 

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

2017-01-16 Thread Mark Millard
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.


Showing the objdump output for RELRO:

   RELRO off0x0002 vaddr 0x1002 paddr 
0x1002 align 2**0
 filesz 0x0138 memsz 0x0138 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  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
0x1270 - 0x1285 is .interp
0x1288 - 0x12b8 is .note.tag
0x12b8 - 0x12b9 is .rodata
0x12bc - 0x12bc is .eh_frame
0x12c0 - 0x1368 is .dynsym
0x1368 - 0x1376 is .gnu.version
0x1378 - 0x1398 is .gnu.version_r
0x1398 - 0x13d8 is .hash
0x13d8 - 0x141a is .dynstr
0x1420 - 0x1468 is .rela.plt <= note
0x1468 - 0x1474 is .eh_frame_hdr
0x1001 - 0x100104f8 is .text
0x10010500 - 0x1001052c is .init
0x10010530 - 0x10010554 is .fini
0x10010560 - 0x100105c0 is .plt  <= 
NOTE
0x1002 - 0x10020010 is .ctors
0x10020010 - 0x10020020 is .dtors
0x10020020 - 0x10020028 is .jcr
0x10020028 - 0x10020138 is .dynamic
0x10020138 - 0x10020138 is .got  <= 
NOTE
0x1003 - 0x10030019 is .data
0x10030020 - 0x10030050 is .got.plt  <= 
NOTE
0x10030050 - 0x100300a0 is .toc  <= 
NOTE
0x100300a0 - 0x10030160 is .opd
0x10030160 - 0x10030170 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  wrote:

> On 2017-Jan-16, at 11:40 AM, Roman Divacky  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 
> 

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

2017-01-16 Thread Mark Millard
On 2017-Jan-16, at 11:40 AM, Roman Divacky  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 0048  1420  1420  0420  2**3
  CONTENTS, ALLOC, LOAD, READONLY, DATA
. . .
 14 .plt  0060  10010560  10010560  00010560  2**4
  CONTENTS, ALLOC, LOAD, READONLY, CODE
. . .
 19 .got    10020138  10020138  00020138  2**3
  CONTENTS, ALLOC, LOAD, DATA
. . .
 21 .got.plt  0030  10030020  10030020  00030020  2**3
  CONTENTS, ALLOC, LOAD, DATA
 22 .toc  0050  10030050  10030050  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.)

1288 l O .note.tag  0018  abitag
12a0 l O .note.tag  0018  
crt_noinit_tag
12bb l O .eh_frame  0004  
__FRAME_END__
.rela.plt fits between here: 1420 (start)
.plt fits between here : 10010560 (start)
1002 l O .ctors 0008  __CTOR_LIST__
10020008 l O .ctors 0008  __CTOR_END__
10020010 l O .dtors 0008  __DTOR_LIST__
10020018 l O .dtors 0008  __DTOR_END__
10020020 l O .jcr     __JCR_LIST__
10020020 l O .jcr   0008  __JCR_END__
10020028 l   .dynamic     .hidden 
_DYNAMIC
.got fits between here : 10020138 (start and end: size zero)
1003 g O .data  0008  __progname
10030008 l O .data  0008  .hidden 
__dso_handle
10030010 l O .data  0008  
__do_global_dtors_aux.p
10030018 l O .data  0001  
__do_global_dtors_aux.completed
.got.plt fits between here : 10030020 (start)
.toc fits between here : 10030050 (start)
100300a0 g F .opd   0264  _start
100300b8 l F .opd   00d0  finalizer
100300d0 l F .opd     .hidden _init
100300e8 l F .opd     .hidden _fini
10030100 l F .opd   00a4  
__do_global_dtors_aux
10030118 l F .opd   007c  frame_dummy
10030130 g F .opd   001c  main
10030148 l F .opd   0088  
__do_global_ctors_aux
10030160 g O .bss   0008  __ps_strings
10030168 g O .bss   0008  environ
10030170 g   *ABS*    _end

Examples of gdb reporting symbol information for some of those addresses:

(gdb) info symbol 0x1288
abitag in section .note.tag
(gdb) info symbol 0x12a0
crt_noinit_tag in section .note.tag
(gdb) info symbol 0x12a4
crt_noinit_tag + 4 in section .note.tag
(gdb) info symbol 0x10020008
__CTOR_END__ in section .ctors
(gdb) info symbol 0x10020010
__DTOR_LIST__ in section .dtors
(gdb) info symbol 0x10020020
__JCR_END__ in section .jcr
(gdb) info symbol 0x10020028
_DYNAMIC in section .dynamic
(gdb) info symbol 0x10030010
__do_global_dtors_aux.p in section .data
(gdb) info symbol 0x100300a0
_start in section .opd
(gdb) info symbol 

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

2017-01-16 Thread Roman Divacky
Mark,

I think the TOC (.got + .plt) has to be contiguous in memory. The on-disk
layout is not that important.

Can you check whats the difference of the in-memory TOC between lld and ld.bfd?

Thanks, Roman

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  wrote:
> 
> On 2017-Jan-12, at 11:22 AM, Roman Divacky  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::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   
>        0 0 0
> . . .
>  [10] .rela.plt RELA 1420  0420
>   0048  0018   A   5 0 8
> . . .
>  [15] .plt  PROGBITS 10010560  00010560
>   0060    AX   0 0 16
> . . .
>  [20] .got  PROGBITS 10020138  00020138
>       WA   0 0 8
> . . .
>  [22] .got.plt  PROGBITS 10030020  00030020
>   0030    WA   0 0 8
> . . .
>  [23] .toc  PROGBITS 10030050  00030050
>   0050    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   
>        0 0 0
> . . .
>  [ 8] .rela.plt RELA 1370  0370
>   0048  0018   A   422 8
> . . .
>  [21] .got  PROGBITS 10010c48  0c48
>   0058  0008  WA   0 0 8
>  [22] .plt  NOBITS   10010ca0  0ca0
>   0060  0018  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 
> 

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

2017-01-13 Thread Mark Millard
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  wrote:

On 2017-Jan-12, at 11:22 AM, Roman Divacky  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::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   
       0 0 0
. . .
 [10] .rela.plt RELA 1420  0420
  0048  0018   A   5 0 8
. . .
 [15] .plt  PROGBITS 10010560  00010560
  0060    AX   0 0 16
. . .
 [20] .got  PROGBITS 10020138  00020138
      WA   0 0 8
. . .
 [22] .got.plt  PROGBITS 10030020  00030020
  0030    WA   0 0 8
. . .
 [23] .toc  PROGBITS 10030050  00030050
  0050    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   
       0 0 0
. . .
 [ 8] .rela.plt RELA 1370  0370
  0048  0018   A   422 8
. . .
 [21] .got  PROGBITS 10010c48  0c48
  0058  0008  WA   0 0 8
 [22] .plt  NOBITS   10010ca0  0ca0
  0060  0018  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 

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

2017-01-12 Thread Mark Millard
On 2017-Jan-12, at 11:22 AM, Roman Divacky  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::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   
        0 0 0
. . .
  [10] .rela.plt RELA 1420  0420
   0048  0018   A   5 0 8
. . .
  [15] .plt  PROGBITS 10010560  00010560
   0060    AX   0 0 16
. . .
  [20] .got  PROGBITS 10020138  00020138
       WA   0 0 8
. . .
  [22] .got.plt  PROGBITS 10030020  00030020
   0030    WA   0 0 8
. . .
  [23] .toc  PROGBITS 10030050  00030050
   0050    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   
        0 0 0
. . .
  [ 8] .rela.plt RELA 1370  0370
   0048  0018   A   422 8
. . .
  [21] .got  PROGBITS 10010c48  0c48
   0058  0008  WA   0 0 8
  [22] .plt  NOBITS   10010ca0  0ca0
   0060  0018  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  wrote:
> 
>> On 11 January 2017 at 21:06, Roman Divacky  wrote:
>>> Looks like a progress :) Three questions...
>>> 
>>> Is the readelf -a reasonable now?
>> 
>> FYI, I 

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

2017-01-12 Thread Mark Millard
On 2017-Jan-11, at 1:23 PM, Ed Maste  wrote:

> On 11 January 2017 at 21:06, Roman Divacky  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.
0x1001056c in ?? ()

Note that the temporary breakpoint is never hit.

(gdb) bt
#0  0x1001056c in ?? ()
#1  0x100100d8 in ?? ()
#2  0x500279b0 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  0x500279b0 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:
   0x50027930 <+0>: stdur1,-144(r1)
   0x50027934 <+4>: std r3,96(r1)
   0x50027938 <+8>: std r4,104(r1)
   0x5002793c <+12>:std r5,112(r1)
   0x50027940 <+16>:std r8,136(r1)
   0x50027944 <+20>:bl  0x50027950 <._rtld_start+32>
   0x50027948 <+24>:.long 0x0
   0x5002794c <+28>:.long 0x30e40
   0x50027950 <+32>:mflrr3
   0x50027954 <+36>:ld  r4,0(r3)
   0x50027958 <+40>:add r3,r4,r3
   0x5002795c <+44>:ld  r4,-32768(r2)
   0x50027960 <+48>:subfr4,r4,r2
   0x50027964 <+52>:bl  0x50027c64 
   0x50027968 <+56>:nop
   0x5002796c <+60>:ld  r4,104(r1)
   0x50027970 <+64>:addir3,r4,-8
   0x50027974 <+68>:addir4,r1,128
   0x50027978 <+72>:addir5,r1,120
   0x5002797c <+76>:bl  0x50028608 <_rtld>
   0x50027980 <+80>:nop
   0x50027984 <+84>:ld  r2,8(r3)
   0x50027988 <+88>:ld  r11,16(r3)
   0x5002798c <+92>:ld  r3,0(r3)
   0x50027990 <+96>:mtlrr3
   0x50027994 <+100>:   ld  r3,96(r1)
   0x50027998 <+104>:   ld  r4,104(r1)
   0x5002799c <+108>:   ld  r5,112(r1)
   0x500279a0 <+112>:   ld  r6,120(r1)
   0x500279a4 <+116>:   ld  r7,128(r1)
   0x500279a8 <+120>:   ld  r8,136(r1)
   0x500279ac <+124>:   blrl
=> 0x500279b0 <+128>:   li  r0,1
   0x500279b4 <+132>:   sc  
   0x500279b8 <+136>:   nop
   0x500279bc <+140>:   nop
End of assembler dump.

So setting a breakpoint at 0x500279ac 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 0xdaf0   18446744073709542128
r2 0x10028138   268599608
r3 0x1  1
r4 0xdbb8   18446744073709542328
r5 0xdbc8   18446744073709542344
r6 0x5004c000   1342488576
r7 0x50058b30   1342540592
r8 0x0  0
r9 0x0  0
r100x0  0
r110x0  0
r120x2000   536870912
r130x50057010   1342533648
r140x0  0
r150x0  0
r160x0  0
r170x0  0
r180x0  0
r190x0  0
r200x0  0
r210x0  0
r220x0  0
r230x0  0
r240x0  0
r250x0  0
r260x0  0
r270x0  0
r280x0  0
r290x0  0
r300x0  0
r310x0  0
pc 0x500279ac   0x500279ac <._rtld_start+124>
msr
cr 0x22000c00   570428416
lr 0x1001   0x1001
ctr0x50043a80   1342454400
xer0x2000   536870912
(gdb) stepi
0x1001 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 

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

2017-01-11 Thread Roman Divacky
Can you try this patch?

Index: tools/lld/ELF/Target.cpp
===
--- tools/lld/ELF/Target.cpp(revision 291691)
+++ tools/lld/ELF/Target.cpp(working copy)
@@ -1062,7 +1062,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;


On Wed, Jan 11, 2017 at 09:47:34AM -0800, Mark Millard wrote:
> 
> On 2017-Jan-11, at 8:07 AM, Ed Maste  wrote:
> 
> > On 11 January 2017 at 04:15, Mark Millard  wrote:
> >> 
> >> # ./a.out
> >> ld-elf.so.1: assert failed: /usr/src/libexec/rtld-elf/powerpc64/reloc.c:374
> >> Abort trap (core dumped)
> > 
> > Would you paste the output of `readelf -r a.out`?
> 
> Here you go, for ld.lld and for ld.bfd . . .
> 
> For -fuse-ld=lld :
> 
> # readelf -r a.out
> 
> Relocation section with addend (.rela.plt):
> r_offset r_info   r_type  st_value st_name + 
> r_addend
> 10030038 00030014   atexit + 0
> 10030040 00020014   _init_tls + 0
> 10030048 00050014   exit + 0
> 
> For -fuse-ld=bfd :
> 
> # readelf -r a.out
> 
> Relocation section with addend (.rela.plt):
> r_offset r_info   r_type  st_value st_name + 
> r_addend
> 10010cb8 00030015   atexit + 0
> 10010cd0 00040015   _init_tls + 0
> 10010ce8 00060015   exit + 0
> 
> These were done on the powerpc64 machine (native).
> 
> 
> ===
> 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"


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

2017-01-11 Thread Mark Millard

On 2017-Jan-11, at 8:07 AM, Ed Maste  wrote:

> On 11 January 2017 at 04:15, Mark Millard  wrote:
>> 
>> # ./a.out
>> ld-elf.so.1: assert failed: /usr/src/libexec/rtld-elf/powerpc64/reloc.c:374
>> Abort trap (core dumped)
> 
> Would you paste the output of `readelf -r a.out`?

Here you go, for ld.lld and for ld.bfd . . .

For -fuse-ld=lld :

# readelf -r a.out

Relocation section with addend (.rela.plt):
r_offset r_info   r_type  st_value st_name + 
r_addend
10030038 00030014   atexit + 0
10030040 00020014   _init_tls + 0
10030048 00050014   exit + 0

For -fuse-ld=bfd :

# readelf -r a.out

Relocation section with addend (.rela.plt):
r_offset r_info   r_type  st_value st_name + 
r_addend
10010cb8 00030015   atexit + 0
10010cd0 00040015   _init_tls + 0
10010ce8 00060015   exit + 0

These were done on the powerpc64 machine (native).


===
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"


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

2017-01-11 Thread Ed Maste
On 11 January 2017 at 04:15, Mark Millard  wrote:
>
> # ./a.out
> ld-elf.so.1: assert failed: /usr/src/libexec/rtld-elf/powerpc64/reloc.c:374
> Abort trap (core dumped)

Would you paste the output of `readelf -r a.out`?
___
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"