[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