Date: Sat, 21 Jan 2017 12:19:21 -0800 From: Mark Millard <markmi@dsl-only.net> To: Ed Maste <emaste@freebsd.org>, FreeBSD Toolchain <freebsd-toolchain@freebsd.org>, FreeBSD PowerPC ML <freebsd-ppc@freebsd.org> Cc: Roman Divacky <rdivacky@vlakno.cz>, Justin Hibbits <chmeeedalf@gmail.com>, Nathan Whitehorn <nwhitehorn@freebsd.org> Subject: I have submitted llvm bugzilla 31716 for lld 3.9.1's incoherent .plt vs. .got.plt content for powerpc64 Message-ID: <B7467500-68C6-4BAA-9281-1F1ADB2D4824@dsl-only.net>
next in thread | raw e-mail | index | archive | help
I've copied the submittal information later below. I've also added 31716 to llvm bugzilla 25780 (the meta-submittal for using clang as the FreeBSD/ppc system context). If this is wrong for some reason fell free to delete the item from the Depends On list. I did reference: > I've not found any powerpc family documentation > for .got.plt use: No such powerpc64 ABI yet? What I wrote in the submittal was: > powerpc64 context for: >=20 > # more main.c > static volatile char big_area[67001] =3D "This is a test"; >=20 > int main () > { > big_area[67000] =3D '9'; > } >=20 > via: >=20 > clang -fuse-ld=3Dlld -g main.c >=20 > 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: >=20 > void PPC64TargetInfo::writePlt(uint8_t *Buf, uint64_t GotEntryAddr, > uint64_t PltEntryAddr, int32_t Index, > unsigned RelOff) const { > uint64_t Off =3D GotEntryAddr - getPPC64TocBase(); >=20 > // FIXME: What we should do, in theory, is get the offset of the = function > // descriptor in the .opd section, and use that as the offset from %r2 = (the > // TOC-base pointer). Instead, we have the GOT-entry offset, and that = will > // be a pointer to the function descriptor in the .opd section. Using > // this scheme is simpler, but requires an extra indirection per PLT = dispatch. >=20 > write32be(Buf, 0xf8410028); // std %r2, 40(%r1) > write32be(Buf + 4, 0x3d620000 | applyPPCHa(Off)); // addis %r11, %r2, = X@ha > write32be(Buf + 8, 0xe98b0000 | applyPPCLo(Off)); // ld %r12, = X@l(%r11) > write32be(Buf + 12, 0xe96c0000); // 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 > } >=20 > But what ld.lld generated for relocation was: >=20 > Relocation section with addend (.rela.plt): > r_offset r_info r_type st_value st_name = + r_addend > 000010030038 000300000015 R_PPC64_JMP_SLOT 0000000000000000 atexit = + 0 > 000010030040 000200000015 R_PPC64_JMP_SLOT 0000000000000000 = _init_tls + 0 > 000010030048 000500000015 R_PPC64_JMP_SLOT 0000000000000000 exit + = 0 >=20 > These r_offset's are in the .got.plt area, not in the .plt area: >=20 > 0x0000000010030020 - 0x0000000010030050 is .got.plt >=20 > The increment is 0x8 between entries, not 0x18 (or more) that > would be needed for function descriptors: There is no > function descriptor space here. >=20 > It looks like the other side of this that is not establishing > space for function descriptors is in the code in: >=20 > /usr/src/contrib/llvm/tools/lld/ELF/Relocations.cpp >=20 > in its scanRelocs : >=20 > // At this point we are done with the relocated position. Some = relocations > // also require us to create a got or plt entry. >=20 > // If a relocation needs PLT, we create a PLT and a GOT slot for = the symbol. > if (needsPlt(Expr)) { > if (Body.isInPlt()) > continue; > Out<ELFT>::Plt->addEntry(Body); >=20 > uint32_t Rel; > if (Body.isGnuIFunc() && !Preemptible) > Rel =3D Target->IRelativeRel; > else > Rel =3D Target->PltRel; >=20 > Out<ELFT>::GotPlt->addEntry(Body); > Out<ELFT>::RelaPlt->addReloc({Rel, Out<ELFT>::GotPlt, > Body.getGotPltOffset<ELFT>(), = !Preemptible, > &Body, 0}); > continue; > } >=20 > The code is explicitly targeting creating GotPlt space, not > .opd space, as well., not matching the earlier comment in > PPC64TargetInfo::writePlt . >=20 > The effect of such code and the wrtPlt code need to be > correctly matching but currently are not. >=20 > For ld.lld's a.out its .plt (not .got.plt) is code, > unlike in the ld.bfd generated a.out: >=20 > Disassembly of section .plt: > 0000000010010550 <.plt> std r2,40(r1) > 0000000010010554 <.plt+0x4> addis r11,r2,0 > 0000000010010558 <.plt+0x8> ld r12,32512(r11) Note: = r12=3D=3D0x000010030038 results > 000000001001055c <.plt+0xc> ld r11,0(r12) > 0000000010010560 <.plt+0x10> mtctr r11 > 0000000010010564 <.plt+0x14> ld r2,8(r12) Note: accesses = 0x000010030040 see .plt+0x28 > 0000000010010568 <.plt+0x18> ld r11,16(r12) Note: accesses = 0x000010030048 see .plt+0x48 > 000000001001056c <.plt+0x1c> bctr >=20 > Note: The code expects 0(12), 8(12), and 16(r12) storage > but not such structure is present: 8(r12) above is > equivalent to 0(r12) below as an example. >=20 > 0000000010010570 <.plt+0x20> std r2,40(r1) > 0000000010010574 <.plt+0x24> addis r11,r2,0 > 0000000010010578 <.plt+0x28> ld r12,32520(r11) Note: = r12=3D=3D0x000010030040 results > 000000001001057c <.plt+0x2c> ld r11,0(r12) > 0000000010010580 <.plt+0x30> mtctr r11 > 0000000010010584 <.plt+0x34> ld r2,8(r12) Note: accesses = 0x000010030048 see .plt+0x48 > 0000000010010588 <.plt+0x38> ld r11,16(r12) Note: accesses = 0x000010030050 > 000000001001058c <.plt+0x3c> bctr >=20 > Note: 0x000010030050 is from: >=20 > 0x0000000010030050 - 0x00000000100300a0 is .toc >=20 > 0000000010010590 <.plt+0x40> std r2,40(r1) > 0000000010010594 <.plt+0x44> addis r11,r2,0 > 0000000010010598 <.plt+0x48> ld r12,32528(r11) Note: = r12=3D=3D0x000010030048 results > 000000001001059c <.plt+0x4c> ld r11,0(r12) > 00000000100105a0 <.plt+0x50> mtctr r11 > 00000000100105a4 <.plt+0x54> ld r2,8(r12) Note: accesses = 0x000010030050 > 00000000100105a8 <.plt+0x58> ld r11,16(r12) Note: accesses = 0x000010030058 > 00000000100105ac <.plt+0x5c> bctr >=20 > Note: 0x000010030050 and 0x000010030058 are from: >=20 > 0x0000000010030050 - 0x00000000100300a0 is .toc >=20 > Either the .got.plt entry layout changes to have room > for 8(r12) and 16(r12) positions (size change to 0x18 > Bytes per entry) 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: No such powerpc64 ABI yet?) >=20 > By contrast the -fuse-ld=3Dbfd ends up with: >=20 > Relocation section with addend (.rela.plt): > r_offset r_info r_type st_value st_name = + r_addend > 0000100218b0 000300000015 R_PPC64_JMP_SLOT 0000000000000000 atexit = + 0 > 0000100218c8 000400000015 R_PPC64_JMP_SLOT 0000000000000000 = _init_tls + 0 > 0000100218e0 000600000015 R_PPC64_JMP_SLOT 0000000000000000 exit + = 0 >=20 > is an increment of 0x18 between entries (room for the > function descriptors). The r_offset's are from the > ld.bfd generated .plt section: >=20 > 0x0000000010021898 - 0x00000000100218f8 is .plt >=20 > NOTE: For the FreeBSD ld.bfd context the .plt does not have > blocks of code for such, just the function descriptors. =3D=3D=3D Mark Millard markmi at dsl-only.net
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?B7467500-68C6-4BAA-9281-1F1ADB2D4824>