[lld] r327871 - [ELF] Add basic support for PPC LE
Rafael Avila de Espindola via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 19 12:26:59 PDT 2018
Zaara Syeda via llvm-commits <llvm-commits at lists.llvm.org> writes:
> Author: syzaara
> Date: Mon Mar 19 10:40:14 2018
> New Revision: 327871
>
> URL: http://llvm.org/viewvc/llvm-project?rev=327871&view=rev
> Log:
> [ELF] Add basic support for PPC LE
>
> This patch adds changes to start supporting the Power 64-Bit ELF V2 ABI.
> This includes:
> - Changing the ElfSym::GlobalOffsetTable to be named .TOC.
> - Creating a GotHeader so the first entry in the .got is .TOC.
> - Setting the e_flags to be 1 for ELF V1 and 2 for ELF V2
>
> Differential Revision: https://reviews.llvm.org/D44483
>
> Added:
> lld/trunk/test/ELF/basic-ppc64.s
> Modified:
> lld/trunk/ELF/Arch/PPC64.cpp
> lld/trunk/ELF/SyntheticSections.cpp
> lld/trunk/ELF/Target.h
> lld/trunk/ELF/Writer.cpp
> lld/trunk/test/ELF/basic64be.s
> lld/trunk/test/ELF/emulation.s
>
> Modified: lld/trunk/ELF/Arch/PPC64.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/PPC64.cpp?rev=327871&r1=327870&r2=327871&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Arch/PPC64.cpp (original)
> +++ lld/trunk/ELF/Arch/PPC64.cpp Mon Mar 19 10:40:14 2018
> @@ -14,6 +14,8 @@
> #include "llvm/Support/Endian.h"
>
> using namespace llvm;
> +using namespace llvm::object;
> +using namespace llvm::support::endian;
> using namespace llvm::ELF;
> using namespace lld;
> using namespace lld::elf;
> @@ -38,11 +40,13 @@ namespace {
> class PPC64 final : public TargetInfo {
> public:
> PPC64();
> + uint32_t calcEFlags() const override;
> RelExpr getRelExpr(RelType Type, const Symbol &S,
> const uint8_t *Loc) const override;
> void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
> int32_t Index, unsigned RelOff) const override;
> void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
> + void writeGotHeader(uint8_t *Buf) const override;
> };
> } // namespace
>
> @@ -65,6 +69,10 @@ PPC64::PPC64() {
> GotPltEntrySize = 8;
> PltEntrySize = 32;
> PltHeaderSize = 0;
> + GotBaseSymInGotPlt = false;
> + GotBaseSymOff = 0x8000;
> + if (Config->EKind == ELF64LEKind)
> + GotHeaderEntriesNum = 1;
>
> // We need 64K pages (at least under glibc/Linux, the loader won't
> // set different permissions on a finer granularity than that).
> @@ -81,6 +89,42 @@ PPC64::PPC64() {
> DefaultImageBase = 0x10000000;
> }
>
> +static uint32_t getEFlags(InputFile *File) {
> + // Get the e_flag from the input file and if it is unspecified, then set it to
> + // the e_flag appropriate for the ABI.
> +
> + // We are currently handling both ELF64LE and ELF64BE but eventually will
> + // remove BE support once v2 ABI support is complete.
> + switch (Config->EKind) {
> + case ELF64BEKind:
> + if (uint32_t EFlags =
> + cast<ObjFile<ELF64BE>>(File)->getObj().getHeader()->e_flags)
> + return EFlags;
> + return 1;
> + case ELF64LEKind:
> + if (uint32_t EFlags =
> + cast<ObjFile<ELF64LE>>(File)->getObj().getHeader()->e_flags)
> + return EFlags;
> + return 2;
> + default:
> + llvm_unreachable("unknown Config->EKind");
> + }
> +}
> +
> +uint32_t PPC64::calcEFlags() const {
> + assert(!ObjectFiles.empty());
> + uint32_t Ret = getEFlags(ObjectFiles[0]);
> +
> + // Verify that all input files have the same e_flags.
> + for (InputFile *F : makeArrayRef(ObjectFiles).slice(1)) {
> + if (Ret == getEFlags(F))
> + continue;
> + error("incompatible e_flags: " + toString(F));
> + return 0;
> + }
> + return Ret;
> +}
> +
> RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,
> const uint8_t *Loc) const {
> switch (Type) {
> @@ -100,6 +144,11 @@ RelExpr PPC64::getRelExpr(RelType Type,
> }
> }
>
> +void PPC64::writeGotHeader(uint8_t *Buf) const {
> + if (Config->EKind == ELF64LEKind)
> + write64(Buf, getPPC64TocBase());
> +}
> +
> void PPC64::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
> uint64_t PltEntryAddr, int32_t Index,
> unsigned RelOff) const {
>
> Modified: lld/trunk/ELF/SyntheticSections.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=327871&r1=327870&r2=327871&view=diff
> ==============================================================================
> --- lld/trunk/ELF/SyntheticSections.cpp (original)
> +++ lld/trunk/ELF/SyntheticSections.cpp Mon Mar 19 10:40:14 2018
> @@ -590,7 +590,7 @@ GotSection::GotSection()
> Target->GotEntrySize, ".got") {}
>
> void GotSection::addEntry(Symbol &Sym) {
> - Sym.GotIndex = NumEntries;
> + Sym.GotIndex = Target->GotHeaderEntriesNum + NumEntries;
Not all uses of NumEntries were updated. For example, we still have
Sym.GlobalDynIndex = NumEntries;
Maybe it is better to initialize NumEntries with
Target->GotHeaderEntriesNum instead?
Cheers,
Rafael
More information about the llvm-commits
mailing list