Commit Graph

6 Commits

Author SHA1 Message Date
Brandon Bergren 275eb8289c [PowerPC] Support powerpcle target in LLD [4/5]
Add support for linking powerpcle code in LLD.

Rewrite lld/test/ELF/emulation-ppc.s to use a shared check block and add powerpcle tests.

Update tests.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D93917
2021-01-02 12:18:05 -06:00
Fangrui Song f5e0ae240f [ELF][test] Fix ppc32-gnu-ifunc.s and remove XFAIL: * 2020-06-30 22:05:51 -07:00
Fangrui Song 345f59667d [ELF] Rename .plt to .iplt and decrease EM_PPC{,64} alignment of .glink to 4
GNU ld creates the synthetic section .iplt, and has a built-in linker
script that assigns .iplt to the output section .plt . There is no
output section named .iplt .

Making .iplt an output section actually has a benefit that makes the
tricky toolchain feature stand out. Symbolizers don't have to deal with
mixed PLT entries (e.g. llvm-objdump -d incorrectly annotates such jump
targets).

On EM_PPC{,64}, .glink contains a PLT resolver and a series of jump
instructions. The 4-byte entry size makes it unnecessary to have an
alignment of 16.

Mark ppc32-gnu-ifunc.s and ppc32-gnu-ifunc-nonpreemptable.s as `XFAIL: *`.
They test IPLT on EM_PPC, which never works.

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D71520
2019-12-17 00:15:59 -08:00
Fangrui Song 12d83b4270 [ELF][PPC] Allow PT_LOAD to have overlapping p_offset ranges on EM_PPC
Ported the D64906 technique to EM_PPC.

Delete ppc-rela.s that is covered by ppc32-abs-pic.s

llvm-svn: 369351
2019-08-20 09:20:05 +00:00
Fangrui Song 25ab1c6471 [ELF] Move R_*_IRELATIVE from .rel[a].plt to .rel[a].dyn unless --pack-dyn-relocs=android[+relr]
An R_*_IRELATIVE represents the address of a STT_GNU_IFUNC symbol
(redirected at runtime) which is non-preemptable and is not associated
with a canonical PLT (associated with a symbol with a section index of
SHN_UNDEF but a non-zero st_value).

.rel[a].plt [DT_JMPREL, DT_JMPREL+DT_JMPRELSZ) contains relocations that
can be lazily resolved. R_*_IRELATIVE are always eagerly resolved, so
conceptually they do not belong to .rela.plt. "iplt" is mostly a misnomer.

glibc powerpc and powerpc64 do not resolve R_*_IRELATIVE if they are in .rela.plt.

    // a.o - synthesized PLT call stub has an R_*_IRELATIVE
    void ifunc(); int main() { ifunc(); }
    // b.o
    static void real() {}
    asm (".type ifunc, %gnu_indirect_function");
    void *ifunc() { return ℜ }

The lld-linked executable crashes. ld.bfd places R_*_IRELATIVE in
.rela.dyn and the executable works.

glibc i386, x86_64, and aarch64 have logic
(glibc/sysdeps/*/dl-machine.h:elf_machine_lazy_rel) to eagerly resolve
R_*_IRELATIVE in .rel[a].plt so the lld-linked executable works.

Move R_*_IRELATIVE from .rel[a].plt to .rel[a].dyn to fix the crashes on
glibc powerpc/powerpc64. This also helps simplifying ifunc
implementation in FreeBSD rtld-elf powerpc64.

If --pack-dyn-relocs=android[+relr] is specified, the Android packed
dynamic relocation format is used for .rela.dyn. We cannot name
in.relaIplt ".rela.dyn" because the output section will have mixed
formats. This can be improved in the future.

Reviewed By: pcc

Differential Revision: https://reviews.llvm.org/D65651

llvm-svn: 367745
2019-08-03 02:26:52 +00:00
Fangrui Song 82442adfc0 [PPC32] Improve the 32-bit PowerPC port
Many -static/-no-pie/-shared/-pie applications linked against glibc or musl
should work with this patch. This also helps FreeBSD PowerPC64 to migrate
their lib32 (PR40888).

* Fix default image base and max page size.
* Support new-style Secure PLT (see below). Old-style BSS PLT is not
  implemented, so it is not suitable for FreeBSD rtld now because it doesn't
  support Secure PLT yet.
* Support more initial relocation types:
  R_PPC_ADDR32, R_PPC_REL16*, R_PPC_LOCAL24PC, R_PPC_PLTREL24, and R_PPC_GOT16.
  The addend of R_PPC_PLTREL24 is special: it decides the call stub PLT type
  but it should be ignored for the computation of target symbol VA.
* Support GNU ifunc
* Support .glink used for lazy PLT resolution in glibc
* Add a new thunk type: PPC32PltCallStub that is similar to PPC64PltCallStub.
  It is used by R_PPC_REL24 and R_PPC_PLTREL24.

A PLT stub used in -fPIE/-fPIC usually loads an address relative to
.got2+0x8000 (-fpie/-fpic code uses _GLOBAL_OFFSET_TABLE_ relative
addresses).
Two .got2 sections in two object files have different addresses, thus a PLT stub
can't be shared by two object files. To handle this incompatibility,
change the parameters of Thunk::isCompatibleWith to
`const InputSection &, const Relocation &`.

PowerPC psABI specified an old-style .plt (BSS PLT) that is both
writable and executable. Linkers don't make separate RW- and RWE segments,
which causes all initially writable memory (think .data) executable.
This is a big security concern so a new PLT scheme (secure PLT) was developed to
address the security issue.

TLS will be implemented in D62940.

glibc older than ~2012 requires .rela.dyn to include .rela.plt, it can
not handle the DT_RELA+DT_RELASZ == DT_JMPREL case correctly. A hack
(not included in this patch) in LinkerScript.cpp addOrphanSections() to
work around the issue:

    if (Config->EMachine == EM_PPC) {
      // Older glibc assumes .rela.dyn includes .rela.plt
      Add(In.RelaDyn);
      if (In.RelaPlt->isLive() && !In.RelaPlt->Parent)
        In.RelaDyn->getParent()->addSection(In.RelaPlt);
    }

Reviewed By: ruiu

Differential Revision: https://reviews.llvm.org/D62464

llvm-svn: 362721
2019-06-06 17:03:00 +00:00