Index: ELF/Arch/PPC64.cpp =================================================================== --- ELF/Arch/PPC64.cpp +++ ELF/Arch/PPC64.cpp @@ -22,6 +22,8 @@ static uint64_t PPC64TocOffset = 0x8000; +enum { AbiV1 = 1, AbiV2 = 2 }; + uint64_t elf::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 @@ -36,6 +38,12 @@ return TocVA + PPC64TocOffset; } +bool elf::isPPC64ElfV2() { + assert(Config->EMachine == EM_PPC64 && + "Should only be called when targeting PPC64!"); + return (Config->EFlags & EF_PPC64_ABI) == AbiV2; +} + namespace { class PPC64 final : public TargetInfo { public: @@ -109,12 +117,12 @@ if (uint32_t EFlags = cast>(File)->getObj().getHeader()->e_flags) return EFlags; - return 1; + return AbiV1; case ELF64LEKind: if (uint32_t EFlags = cast>(File)->getObj().getHeader()->e_flags) return EFlags; - return 2; + return AbiV2; default: llvm_unreachable("unknown Config->EKind"); } @@ -157,7 +165,7 @@ } void PPC64::writeGotHeader(uint8_t *Buf) const { - if (Config->EKind == ELF64LEKind) + if (isPPC64ElfV2()) write64(Buf, getPPC64TocBase()); } @@ -166,7 +174,7 @@ unsigned RelOff) const { uint64_t Off = GotPltEntryAddr - getPPC64TocBase(); - if (Config->EKind == ELF64LEKind) { + if (isPPC64ElfV2()) { // The most-common form of the plt stub. This assumes that the toc-pointer // register is properly initalized, and that the stub must save the toc // pointer value to the stack-save slot reserved for it (sp + 24). Index: ELF/Target.h =================================================================== --- ELF/Target.h +++ ELF/Target.h @@ -154,6 +154,9 @@ return getErrorPlace(Loc).Loc; } +// Checks for abi version 2 when targeting PPC64. +bool isPPC64ElfV2(); + uint64_t getPPC64TocBase(); uint64_t getAArch64Page(uint64_t Expr);