[PPC64] Remove support for ELF V1 ABI in LLD

The current support for V1 ABI in LLD is incomplete.
This patch removes V1 ABI support and changes the default behavior to V2 ABI,
issuing an error when using the V1 ABI. It also updates the testcases to V2
and removes any V1 specific tests.

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

llvm-svn: 331529
This commit is contained in:
Zaara Syeda 2018-05-04 15:09:49 +00:00
parent 5291562acd
commit f61b0733a8
29 changed files with 401 additions and 467 deletions

View File

@ -72,13 +72,9 @@ PPC64::PPC64() {
GotBaseSymInGotPlt = false;
GotBaseSymOff = 0x8000;
if (Config->EKind == ELF64LEKind) {
GotHeaderEntriesNum = 1;
GotPltHeaderEntriesNum = 2;
PltRel = R_PPC64_JMP_SLOT;
} else {
PltRel = R_PPC64_GLOB_DAT;
}
GotHeaderEntriesNum = 1;
GotPltHeaderEntriesNum = 2;
PltRel = R_PPC64_JMP_SLOT;
// We need 64K pages (at least under glibc/Linux, the loader won't
// set different permissions on a finer granularity than that).
@ -99,39 +95,46 @@ PPC64::PPC64() {
}
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.
// Get the e_flag from the input file and issue an error if incompatible
// e_flag encountered.
// 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 EFlags = Config->IsLE ?
cast<ObjFile<ELF64LE>>(File)->getObj().getHeader()->e_flags :
cast<ObjFile<ELF64BE>>(File)->getObj().getHeader()->e_flags;
if (EFlags > 2) {
error("incompatible e_flags: " + toString(File));
return 0;
}
return EFlags;
}
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))
uint32_t NonZeroFlag;
for (InputFile *F : makeArrayRef(ObjectFiles)) {
NonZeroFlag = getEFlags(F);
if (NonZeroFlag)
break;
}
// Verify that all input files have either the same e_flags, or zero.
for (InputFile *F : makeArrayRef(ObjectFiles)) {
uint32_t Flag = getEFlags(F);
if (Flag == 0 || Flag == NonZeroFlag)
continue;
error("incompatible e_flags: " + toString(F));
error(toString(F) + ": ABI version " + Twine(Flag) +
" is not compatible with ABI version " + Twine(NonZeroFlag) +
" output");
return 0;
}
return Ret;
if (NonZeroFlag == 1) {
error("PPC64 V1 ABI not supported");
return 0;
}
return 2;
}
RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,
@ -147,7 +150,7 @@ RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,
case R_PPC64_TOC:
return R_PPC_TOC;
case R_PPC64_REL24:
return R_PPC_PLT_OPD;
return R_PPC_CALL_PLT;
case R_PPC64_REL16_LO:
case R_PPC64_REL16_HA:
return R_PC;
@ -157,8 +160,7 @@ RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,
}
void PPC64::writeGotHeader(uint8_t *Buf) const {
if (Config->EKind == ELF64LEKind)
write64(Buf, getPPC64TocBase());
write64(Buf, getPPC64TocBase());
}
void PPC64::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
@ -166,37 +168,21 @@ void PPC64::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
unsigned RelOff) const {
uint64_t Off = GotPltEntryAddr - getPPC64TocBase();
if (Config->EKind == ELF64LEKind) {
// 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).
// There are 2 other variants but we don't have to emit those until we add
// support for R_PPC64_REL24_NOTOC and R_PPC64_TOCSAVE relocations.
// We are missing a super simple optimization, where if the upper 16 bits of
// the offset are zero, then we can omit the addis instruction, and load
// r2 + lo-offset directly into r12. I decided to leave this out in the
// spirit of keeping it simple until we can link actual non-trivial
// programs.
write32(Buf + 0, 0xf8410018); // std r2,24(r1)
write32(Buf + 4, 0x3d820000 | applyPPCHa(Off)); // addis r12,r2, X@plt@to@ha
write32(Buf + 8, 0xe98c0000 | applyPPCLo(Off)); // ld r12,X@plt@toc@l(r12)
write32(Buf + 12, 0x7d8903a6); // mtctr r12
write32(Buf + 16, 0x4e800420); // bctr
} else {
// 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.
write32(Buf, 0xf8410028); // std %r2, 40(%r1)
write32(Buf + 4, 0x3d620000 | applyPPCHa(Off)); // addis %r11, %r2, X@ha
write32(Buf + 8, 0xe98b0000 | applyPPCLo(Off)); // ld %r12, X@l(%r11)
write32(Buf + 12, 0xe96c0000); // ld %r11,0(%r12)
write32(Buf + 16, 0x7d6903a6); // mtctr %r11
write32(Buf + 20, 0xe84c0008); // ld %r2,8(%r12)
write32(Buf + 24, 0xe96c0010); // ld %r11,16(%r12)
write32(Buf + 28, 0x4e800420); // bctr
}
// 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).
// There are 2 other variants but we don't have to emit those until we add
// support for R_PPC64_REL24_NOTOC and R_PPC64_TOCSAVE relocations.
// We are missing a super simple optimization, where if the upper 16 bits of
// the offset are zero, then we can omit the addis instruction, and load
// r2 + lo-offset directly into r12. I decided to leave this out in the
// spirit of keeping it simple until we can link actual non-trivial
// programs.
write32(Buf + 0, 0xf8410018); // std r2,24(r1)
write32(Buf + 4, 0x3d820000 | applyPPCHa(Off)); // addis r12,r2, X@plt@to@ha
write32(Buf + 8, 0xe98c0000 | applyPPCLo(Off)); // ld r12,X@plt@toc@l(r12)
write32(Buf + 12, 0x7d8903a6); // mtctr r12
write32(Buf + 16, 0x4e800420); // bctr
}
static std::pair<RelType, uint64_t> toAddr16Rel(RelType Type, uint64_t Val) {

View File

@ -566,24 +566,15 @@ static uint64_t getRelocTargetVA(RelType Type, int64_t A, uint64_t P,
case R_PLT:
return Sym.getPltVA() + A;
case R_PLT_PC:
case R_PPC_PLT_OPD:
case R_PPC_CALL_PLT:
return Sym.getPltVA() + A - P;
case R_PPC_OPD: {
case R_PPC_CALL: {
uint64_t SymVA = Sym.getVA(A);
// If we have an undefined weak symbol, we might get here with a symbol
// address of zero. That could overflow, but the code must be unreachable,
// so don't bother doing anything at all.
if (!SymVA)
return 0;
if (Out::Opd) {
// If this is a local call, and we currently have the address of a
// function-descriptor, get the underlying code address instead.
uint64_t OpdStart = Out::Opd->Addr;
uint64_t OpdEnd = OpdStart + Out::Opd->Size;
bool InOpd = OpdStart <= SymVA && SymVA < OpdEnd;
if (InOpd)
SymVA = read64be(&Out::OpdBuf[SymVA - OpdStart]);
}
// PPC64 V2 ABI describes two entry points to a function. The global entry
// point sets up the TOC base pointer. When calling a local function, the
@ -749,7 +740,7 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) {
case R_RELAX_TLS_GD_TO_IE_END:
Target->relaxTlsGdToIe(BufLoc, Type, TargetVA);
break;
case R_PPC_PLT_OPD:
case R_PPC_CALL_PLT:
// Patch a nop (0x60000000) to a ld.
if (BufLoc + 8 > BufEnd || read32(BufLoc + 4) != 0x60000000) {
error(getErrorLocation(BufLoc) + "call lacks nop, can't restore toc");

View File

@ -31,8 +31,6 @@ using namespace lld;
using namespace lld::elf;
uint8_t Out::First;
OutputSection *Out::Opd;
uint8_t *Out::OpdBuf;
PhdrEntry *Out::TlsPhdr;
OutputSection *Out::DebugInfo;
OutputSection *Out::ElfHeader;

View File

@ -128,8 +128,6 @@ std::vector<InputSection *> getInputSections(OutputSection* OS);
// until Writer is initialized.
struct Out {
static uint8_t First;
static OutputSection *Opd;
static uint8_t *OpdBuf;
static PhdrEntry *TlsPhdr;
static OutputSection *DebugInfo;
static OutputSection *ElfHeader;

View File

@ -312,7 +312,7 @@ static bool isAbsoluteValue(const Symbol &Sym) {
// Returns true if Expr refers a PLT entry.
static bool needsPlt(RelExpr Expr) {
return isRelExprOneOf<R_PLT_PC, R_PPC_PLT_OPD, R_PLT, R_PLT_PAGE_PC>(Expr);
return isRelExprOneOf<R_PLT_PC, R_PPC_CALL_PLT, R_PLT, R_PLT_PAGE_PC>(Expr);
}
// Returns true if Expr refers a GOT entry. Note that this function
@ -347,7 +347,7 @@ static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym,
R_MIPS_GOTREL, R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32,
R_MIPS_GOT_GP_PC, R_MIPS_TLSGD, R_GOT_PAGE_PC, R_GOT_PC,
R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_PLT_PC, R_TLSGD_PC,
R_TLSGD, R_PPC_PLT_OPD, R_TLSDESC_CALL, R_TLSDESC_PAGE,
R_TLSGD, R_PPC_CALL_PLT, R_TLSDESC_CALL, R_TLSDESC_PAGE,
R_HINT>(E))
return true;
@ -395,8 +395,8 @@ static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym,
static RelExpr toPlt(RelExpr Expr) {
switch (Expr) {
case R_PPC_OPD:
return R_PPC_PLT_OPD;
case R_PPC_CALL:
return R_PPC_CALL_PLT;
case R_PC:
return R_PLT_PC;
case R_PAGE_PC:
@ -414,8 +414,8 @@ static RelExpr fromPlt(RelExpr Expr) {
switch (Expr) {
case R_PLT_PC:
return R_PC;
case R_PPC_PLT_OPD:
return R_PPC_OPD;
case R_PPC_CALL_PLT:
return R_PPC_CALL;
case R_PLT:
return R_ABS;
default:

View File

@ -59,8 +59,8 @@ enum RelExpr {
R_PLT,
R_PLT_PAGE_PC,
R_PLT_PC,
R_PPC_OPD,
R_PPC_PLT_OPD,
R_PPC_CALL,
R_PPC_CALL_PLT,
R_PPC_TOC,
R_RELAX_GOT_PC,
R_RELAX_GOT_PC_NOPIC,

View File

@ -689,7 +689,6 @@ enum RankFlags {
RF_BSS = 1 << 8,
RF_NOTE = 1 << 7,
RF_PPC_NOT_TOCBSS = 1 << 6,
RF_PPC_OPD = 1 << 5,
RF_PPC_TOCL = 1 << 4,
RF_PPC_TOC = 1 << 3,
RF_PPC_BRANCH_LT = 1 << 2,
@ -794,9 +793,6 @@ static unsigned getSectionRank(const OutputSection *Sec) {
if (Name != ".tocbss")
Rank |= RF_PPC_NOT_TOCBSS;
if (Name == ".opd")
Rank |= RF_PPC_OPD;
if (Name == ".toc1")
Rank |= RF_PPC_TOCL;
@ -2295,14 +2291,6 @@ template <class ELFT> void Writer<ELFT>::writeTrapInstr() {
template <class ELFT> void Writer<ELFT>::writeSections() {
uint8_t *Buf = Buffer->getBufferStart();
// PPC64 needs to process relocations in the .opd section
// before processing relocations in code-containing sections.
if (auto *OpdCmd = findSection(".opd")) {
Out::Opd = OpdCmd;
Out::OpdBuf = Buf + Out::Opd->Offset;
OpdCmd->template writeTo<ELFT>(Buf + Out::Opd->Offset);
}
OutputSection *EhFrameHdr = nullptr;
if (InX::EhFrameHdr && !InX::EhFrameHdr->empty())
EhFrameHdr = InX::EhFrameHdr->getParent();
@ -2315,8 +2303,7 @@ template <class ELFT> void Writer<ELFT>::writeSections() {
Sec->writeTo<ELFT>(Buf + Sec->Offset);
for (OutputSection *Sec : OutputSections)
if (Sec != Out::Opd && Sec != EhFrameHdr && Sec->Type != SHT_REL &&
Sec->Type != SHT_RELA)
if (Sec != EhFrameHdr && Sec->Type != SHT_REL && Sec->Type != SHT_RELA)
Sec->writeTo<ELFT>(Buf + Sec->Offset);
// The .eh_frame_hdr depends on .eh_frame section contents, therefore

View File

@ -1,9 +1,14 @@
.section ".opd","aw"
.global bar
bar:
.quad .Lbar,.TOC.@tocbase,0
.quad .Lbar,0,0
.text
.abiversion 2
.globl foo
.p2align 4
.type foo,@function
.text
.Lbar:
blr
foo:
.Lfunc_begin0:
li 3, 55
blr
.long 0
.quad 0
.Lfunc_end0:
.size foo, .Lfunc_end0-.Lfunc_begin0

View File

@ -1,14 +0,0 @@
.text
.abiversion 2
.globl foo
.p2align 4
.type foo,@function
foo:
.Lfunc_begin0:
li 3, 55
blr
.long 0
.quad 0
.Lfunc_end0:
.size foo, .Lfunc_end0-.Lfunc_begin0

View File

@ -4,26 +4,11 @@
# REQUIRES: ppc
# exits with return code 42 on linux
.section ".opd","aw"
.global _start
_start:
.quad .Lfoo,.TOC.@tocbase,0
# generate .toc and .toc1 sections to make sure that the ordering is as
# intended (.toc before .toc1, and both before .opd).
.section ".toc1","aw"
.quad 22, 37, 89, 47
.section ".toc","aw"
.quad 45, 86, 72, 24
.text
.Lfoo:
li 0,1
li 3,42
sc
# CHECK: ElfHeader {
# CHECK: ElfHeader {
# CHECK-NEXT: Ident {
# CHECK-NEXT: Magic: (7F 45 4C 46)
# CHECK-NEXT: Class: 64-bit (0x2)
@ -36,18 +21,18 @@ _start:
# CHECK-NEXT: Type: Executable (0x2)
# CHECK-NEXT: Machine: EM_PPC64 (0x15)
# CHECK-NEXT: Version: 1
# CHECK-NEXT: Entry: 0x10020040
# CHECK-NEXT: Entry: 0x10010000
# CHECK-NEXT: ProgramHeaderOffset: 0x40
# CHECK-NEXT: SectionHeaderOffset: 0x30080
# CHECK-NEXT: Flags [ (0x1)
# CHECK-NEXT: 0x1
# CHECK-NEXT: SectionHeaderOffset: 0x11050
# CHECK-NEXT: Flags [ (0x2)
# CHECK-NEXT: 0x2
# CHECK-NEXT: ]
# CHECK-NEXT: HeaderSize: 64
# CHECK-NEXT: ProgramHeaderEntrySize: 56
# CHECK-NEXT: ProgramHeaderCount: 6
# CHECK-NEXT: ProgramHeaderCount: 4
# CHECK-NEXT: SectionHeaderEntrySize: 64
# CHECK-NEXT: SectionHeaderCount: 10
# CHECK-NEXT: StringTableSectionIndex: 8
# CHECK-NEXT: SectionHeaderCount: 6
# CHECK-NEXT: StringTableSectionIndex: 4
# CHECK-NEXT: }
# CHECK-NEXT: Sections [
# CHECK-NEXT: Section {
@ -68,7 +53,7 @@ _start:
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 1
# CHECK-NEXT: Name: .text
# CHECK-NEXT: Name: .text (1)
# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
# CHECK-NEXT: Flags [ (0x6)
# CHECK-NEXT: SHF_ALLOC (0x2)
@ -82,152 +67,80 @@ _start:
# CHECK-NEXT: AddressAlignment: 4
# CHECK-NEXT: EntrySize: 0
# CHECK-NEXT: SectionData (
# CHECK: )
# CHECK-NEXT: 0000: 38000001 3860002A 44000002 |8...8`.*D...|
# CHECK-NEXT: )
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 2
# CHECK-NEXT: Name: .toc
# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
# CHECK-NEXT: Flags [ (0x3)
# CHECK-NEXT: SHF_ALLOC (0x2)
# CHECK-NEXT: SHF_WRITE (0x1)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x10020000
# CHECK-NEXT: Offset: 0x20000
# CHECK-NEXT: Size: 32
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
# CHECK-NEXT: AddressAlignment: 1
# CHECK-NEXT: EntrySize: 0
# CHECK-NEXT: SectionData (
# CHECK-NEXT: 0000: 00000000 0000002D 00000000 00000056 |.......-.......V|
# CHECK-NEXT: 0010: 00000000 00000048 00000000 00000018 |.......H........|
# CHECK-NEXT: )
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 3
# CHECK-NEXT: Name: .toc1
# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
# CHECK-NEXT: Flags [ (0x3)
# CHECK-NEXT: SHF_ALLOC (0x2)
# CHECK-NEXT: SHF_WRITE (0x1)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x10020020
# CHECK-NEXT: Offset: 0x20020
# CHECK-NEXT: Size: 32
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
# CHECK-NEXT: AddressAlignment: 1
# CHECK-NEXT: EntrySize: 0
# CHECK-NEXT: SectionData (
# CHECK-NEXT: 0000: 00000000 00000016 00000000 00000025 |...............%|
# CHECK-NEXT: 0010: 00000000 00000059 00000000 0000002F |.......Y......./|
# CHECK-NEXT: )
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 4
# CHECK-NEXT: Name: .opd
# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
# CHECK-NEXT: Flags [ (0x3)
# CHECK-NEXT: SHF_ALLOC (0x2)
# CHECK-NEXT: SHF_WRITE (0x1)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x10020040
# CHECK-NEXT: Offset: 0x20040
# CHECK-NEXT: Size: 24
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
# CHECK-NEXT: AddressAlignment: 1
# CHECK-NEXT: EntrySize: 0
# CHECK-NEXT: SectionData (
# CHECK-NEXT: 0000: 00000000 10010000 00000000 10038000 |................|
# CHECK-NEXT: 0010: 00000000 00000000 |........|
# CHECK-NEXT: )
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 5
# CHECK-NEXT: Name: .got
# CHECK-NEXT: Type: SHT_PROGBITS
# CHECK-NEXT: Flags [
# CHECK-NEXT: SHF_ALLOC
# CHECK-NEXT: SHF_WRITE
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x10030000
# CHECK-NEXT: Offset: 0x30000
# CHECK-NEXT: Size: 0
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
# CHECK-NEXT: AddressAlignment: 8
# CHECK-NEXT: EntrySize: 0
# CHECK-NEXT: SectionData (
# CHECK-NEXT: )
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 6
# CHECK-NEXT: Name: .comment
# CHECK-NEXT: Name: .comment (7)
# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
# CHECK-NEXT: Flags [ (0x30)
# CHECK-NEXT: SHF_MERGE (0x10)
# CHECK-NEXT: SHF_STRINGS (0x20)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x0
# CHECK-NEXT: Offset: 0x30000
# CHECK-NEXT: Offset: 0x11000
# CHECK-NEXT: Size: 8
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
# CHECK-NEXT: AddressAlignment: 1
# CHECK-NEXT: EntrySize: 1
# CHECK-NEXT: SectionData (
# CHECK-NEXT: 0000: 4C4C4420 312E3000 |LLD 1.0.|
# CHECK-NEXT: 0000: 4C4C4420 312E3000 |LLD 1.0.|
# CHECK-NEXT: )
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 7
# CHECK-NEXT: Name: .symtab
# CHECK-NEXT: Index: 3
# CHECK-NEXT: Name: .symtab (16)
# CHECK-NEXT: Type: SHT_SYMTAB (0x2)
# CHECK-NEXT: Flags [ (0x0)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x0
# CHECK-NEXT: Offset: 0x30008
# CHECK-NEXT: Size: 48
# CHECK-NEXT: Link: 9
# CHECK-NEXT: Offset: 0x11008
# CHECK-NEXT: Size: 24
# CHECK-NEXT: Link: 5
# CHECK-NEXT: Info: 1
# CHECK-NEXT: AddressAlignment: 8
# CHECK-NEXT: EntrySize: 24
# CHECK-NEXT: SectionData (
# CHECK: )
# CHECK-NEXT: 0000: 00000000 00000000 00000000 00000000 |................|
# CHECK-NEXT: 0010: 00000000 00000000 |........|
# CHECK-NEXT: )
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 8
# CHECK-NEXT: Name: .shstrtab
# CHECK-NEXT: Type: SHT_STRTAB
# CHECK-NEXT: Flags [
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x0
# CHECK-NEXT: Offset: 0x30038
# CHECK-NEXT: Size: 63
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
# CHECK-NEXT: AddressAlignment: 1
# CHECK-NEXT: EntrySize: 0
# CHECK-NEXT: SectionData (
# CHECK: )
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 9
# CHECK-NEXT: Name: .strtab
# CHECK-NEXT: Type: SHT_STRTAB
# CHECK-NEXT: Index: 4
# CHECK-NEXT: Name: .shstrtab (24)
# CHECK-NEXT: Type: SHT_STRTAB (0x3)
# CHECK-NEXT: Flags [ (0x0)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x0
# CHECK-NEXT: Offset: 0x30077
# CHECK-NEXT: Size: 8
# CHECK-NEXT: Offset: 0x11020
# CHECK-NEXT: Size: 42
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
# CHECK-NEXT: AddressAlignment: 1
# CHECK-NEXT: EntrySize: 0
# CHECK-NEXT: SectionData (
# CHECK-NEXT: 0000: 005F7374 61727400 |._start.|
# CHECK-NEXT: 0000: 002E7465 7874002E 636F6D6D 656E7400 |..text..comment.|
# CHECK-NEXT: 0010: 2E73796D 74616200 2E736873 74727461 |.symtab..shstrta|
# CHECK-NEXT: 0020: 62002E73 74727461 6200 |b..strtab.|
# CHECK-NEXT: )
# CHECK-NEXT: }
# CHECK-NEXT: Section {
# CHECK-NEXT: Index: 5
# CHECK-NEXT: Name: .strtab (34)
# CHECK-NEXT: Type: SHT_STRTAB (0x3)
# CHECK-NEXT: Flags [ (0x0)
# CHECK-NEXT: ]
# CHECK-NEXT: Address: 0x0
# CHECK-NEXT: Offset: 0x1104A
# CHECK-NEXT: Size: 1
# CHECK-NEXT: Link: 0
# CHECK-NEXT: Info: 0
# CHECK-NEXT: AddressAlignment: 1
# CHECK-NEXT: EntrySize: 0
# CHECK-NEXT: SectionData (
# CHECK-NEXT: 0000: 00 |.|
# CHECK-NEXT: )
# CHECK-NEXT: }
# CHECK-NEXT: ]
@ -237,74 +150,49 @@ _start:
# CHECK-NEXT: Offset: 0x40
# CHECK-NEXT: VirtualAddress: 0x10000040
# CHECK-NEXT: PhysicalAddress: 0x10000040
# CHECK-NEXT: FileSize: 336
# CHECK-NEXT: MemSize: 336
# CHECK-NEXT: Flags [
# CHECK-NEXT: PF_R
# CHECK-NEXT: FileSize: 224
# CHECK-NEXT: MemSize: 224
# CHECK-NEXT: Flags [ (0x4)
# CHECK-NEXT: PF_R (0x4)
# CHECK-NEXT: ]
# CHECK-NEXT: Alignment: 8
# CHECK-NEXT: }
# CHECK-NEXT: ProgramHeader {
# CHECK-NEXT: Type: PT_LOAD (0x1)
# CHECK-NEXT: Offset: 0x0
# CHECK-NEXT: VirtualAddress: 0x10000000
# CHECK-NEXT: PhysicalAddress: 0x10000000
# CHECK-NEXT: FileSize: 400
# CHECK-NEXT: MemSize: 400
# CHECK-NEXT: Flags [
# CHECK-NEXT: PF_R
# CHECK-NEXT: ]
# CHECK-NEXT: Alignment: 65536
# CHECK-NEXT: }
# CHECK-NEXT: ProgramHeader {
# CHECK-NEXT: Type: PT_LOAD (0x1)
# CHECK-NEXT: Offset: 0x10000
# CHECK-NEXT: VirtualAddress: 0x10010000
# CHECK-NEXT: PhysicalAddress: 0x10010000
# CHECK-NEXT: FileSize: 12
# CHECK-NEXT: MemSize: 12
# CHECK-NEXT: Flags [ (0x5)
# CHECK-NEXT: PF_R (0x4)
# CHECK-NEXT: PF_X (0x1)
# CHECK-NEXT: ]
# CHECK-NEXT: Alignment: 65536
# CHECK-NEXT: }
# CHECK-NEXT: ProgramHeader {
# CHECK-NEXT: Type: PT_LOAD (0x1)
# CHECK-NEXT: Offset: 0x20000
# CHECK-NEXT: VirtualAddress: 0x10020000
# CHECK-NEXT: PhysicalAddress: 0x10020000
# CHECK-NEXT: FileSize: 65536
# CHECK-NEXT: MemSize: 65536
# CHECK-NEXT: Flags [ (0x6)
# CHECK-NEXT: PF_R (0x4)
# CHECK-NEXT: PF_W (0x2)
# CHECK-NEXT: ]
# CHECK-NEXT: Alignment: 65536
# CHECK-NEXT: }
# CHECK-NEXT: ProgramHeader {
# CHECK-NEXT: Type: PT_GNU_RELRO
# CHECK-NEXT: Offset: 0x30000
# CHECK-NEXT: VirtualAddress: 0x10030000
# CHECK-NEXT: PhysicalAddress: 0x10030000
# CHECK-NEXT: FileSize: 0
# CHECK-NEXT: MemSize: 0
# CHECK-NEXT: Flags [ (0x4)
# CHECK-NEXT: PF_R (0x4)
# CHECK-NEXT: ]
# CHECK-NEXT: Alignment: 1
# CHECK-NEXT: }
# CHECK-NEXT: ProgramHeader {
# CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551)
# CHECK-NEXT: Offset: 0x0
# CHECK-NEXT: VirtualAddress: 0x0
# CHECK-NEXT: PhysicalAddress: 0x0
# CHECK-NEXT: FileSize: 0
# CHECK-NEXT: MemSize: 0
# CHECK-NEXT: Flags [ (0x6)
# CHECK-NEXT: PF_R (0x4)
# CHECK-NEXT: PF_W (0x2)
# CHECK-NEXT: ]
# CHECK-NEXT: Alignment: 0
# CHECK-NEXT: }
# CHECK-NEXT: ProgramHeader {
# CHECK-NEXT: Type: PT_LOAD (0x1)
# CHECK-NEXT: Offset: 0x0
# CHECK-NEXT: VirtualAddress: 0x10000000
# CHECK-NEXT: PhysicalAddress: 0x10000000
# CHECK-NEXT: FileSize: 288
# CHECK-NEXT: MemSize: 288
# CHECK-NEXT: Flags [ (0x4)
# CHECK-NEXT: PF_R (0x4)
# CHECK-NEXT: ]
# CHECK-NEXT: Alignment: 65536
# CHECK-NEXT: }
# CHECK-NEXT: ProgramHeader {
# CHECK-NEXT: Type: PT_LOAD (0x1)
# CHECK-NEXT: Offset: 0x10000
# CHECK-NEXT: VirtualAddress: 0x10010000
# CHECK-NEXT: PhysicalAddress: 0x10010000
# CHECK-NEXT: FileSize: 4096
# CHECK-NEXT: MemSize: 4096
# CHECK-NEXT: Flags [ (0x5)
# CHECK-NEXT: PF_R (0x4)
# CHECK-NEXT: PF_X (0x1)
# CHECK-NEXT: ]
# CHECK-NEXT: Alignment: 65536
# CHECK-NEXT: }
# CHECK-NEXT: ProgramHeader {
# CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551)
# CHECK-NEXT: Offset: 0x0
# CHECK-NEXT: VirtualAddress: 0x0
# CHECK-NEXT: PhysicalAddress: 0x0
# CHECK-NEXT: FileSize: 0
# CHECK-NEXT: MemSize: 0
# CHECK-NEXT: Flags [ (0x6)
# CHECK-NEXT: PF_R (0x4)
# CHECK-NEXT: PF_W (0x2)
# CHECK-NEXT: ]
# CHECK-NEXT: Alignment: 0
# CHECK-NEXT: }
# CHECK-NEXT: ]

View File

@ -208,8 +208,8 @@
# PPC64-NEXT: Entry:
# PPC64-NEXT: ProgramHeaderOffset: 0x40
# PPC64-NEXT: SectionHeaderOffset:
# PPC64-NEXT: Flags [ (0x1)
# PPC64-NEXT: 0x1
# PPC64-NEXT: Flags [ (0x2)
# PPC64-NEXT: 0x2
# PPC64-NEXT: ]
# PPC64-NEXT: HeaderSize: 64
# PPC64-NEXT: ProgramHeaderEntrySize: 56

View File

@ -4,30 +4,36 @@
# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %te.s -o %te-i386.o
# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t-i386.o
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t-x86_64.o
# RUN: llvm-mc -filetype=obj -triple=powerpc64-pc-linux %s -o %t-ppc64.o
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t-ppc64le.o
# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t-ppc64.o
# RUN: echo ".global zed; zed:" > %t2.s
# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %t2.s -o %t2-i386.o
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t2.s -o %t2-x86_64.o
# RUN: llvm-mc -filetype=obj -triple=powerpc64-pc-linux %t2.s -o %t2-ppc64.o
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %t2.s -o %t2-ppc64le.o
# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %t2.s -o %t2-ppc64.o
# RUN: rm -f %t2-i386.a %t2-x86_64.a %t2-ppc64.a
# RUN: llvm-ar rc %t2-i386.a %t2-i386.o
# RUN: llvm-ar rc %t2-x86_64.a %t2-x86_64.o
# RUN: llvm-ar rc %t2-ppc64le.a %t2-ppc64le.o
# RUN: llvm-ar rc %t2-ppc64.a %t2-ppc64.o
# RUN: echo ".global xyz; xyz:" > %t3.s
# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %t3.s -o %t3-i386.o
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t3.s -o %t3-x86_64.o
# RUN: llvm-mc -filetype=obj -triple=powerpc64-pc-linux %t3.s -o %t3-ppc64.o
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %t3.s -o %t3-ppc64le.o
# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %t3.s -o %t3-ppc64.o
# RUN: ld.lld -shared %t3-i386.o -o %t3-i386.so
# RUN: ld.lld -shared %t3-x86_64.o -o %t3-x86_64.so
# RUN: ld.lld -shared %t3-ppc64le.o -o %t3-ppc64le.so
# RUN: ld.lld -shared %t3-ppc64.o -o %t3-ppc64.so
# RUN: ld.lld -shared --hash-style=gnu -o %te-i386.so %te-i386.o
# RUN: ld.lld -shared -hash-style=gnu -o %t-i386.so %t-i386.o %t2-i386.a %t3-i386.so
# RUN: ld.lld -shared -hash-style=gnu -o %t-x86_64.so %t-x86_64.o %t2-x86_64.a %t3-x86_64.so
# RUN: ld.lld -shared --hash-style both -o %t-ppc64le.so %t-ppc64le.o %t2-ppc64le.a %t3-ppc64le.so
# RUN: ld.lld -shared --hash-style both -o %t-ppc64.so %t-ppc64.o %t2-ppc64.a %t3-ppc64.so
# RUN: llvm-readobj -dyn-symbols -gnu-hash-table %te-i386.so \
@ -36,6 +42,8 @@
# RUN: | FileCheck %s -check-prefix=I386
# RUN: llvm-readobj -sections -dyn-symbols -gnu-hash-table %t-x86_64.so \
# RUN: | FileCheck %s -check-prefix=X86_64
# RUN: llvm-readobj -sections -dyn-symbols -gnu-hash-table %t-ppc64le.so \
# RUN: | FileCheck %s -check-prefix=PPC64
# RUN: llvm-readobj -sections -dyn-symbols -gnu-hash-table %t-ppc64.so \
# RUN: | FileCheck %s -check-prefix=PPC64

View File

@ -1,7 +1,12 @@
// REQUIRES: ppc
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-addr16-error.s -o %t2
// RUN: not ld.lld -shared %t %t2 -o %t3 2>&1 | FileCheck %s
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-addr16-error.s -o %t2
// RUN: not ld.lld -shared %t %t2 -o %t3 2>&1 | FileCheck %s
// REQUIRES: ppc
.short sym+65539

View File

@ -1,12 +1,22 @@
// REQUIRES: ppc
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64le.s -o %t2.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
// RUN: ld.lld -shared %t2.o -o %t2.so
// RUN: ld.lld %t.o %t2.so -o %t
// RUN: llvm-readobj -dyn-relocations %t | FileCheck %s
// RUN: llvm-objdump -D %t | FileCheck --check-prefix=DIS %s
// RUN: llvm-readelf -dynamic-table %t | FileCheck --check-prefix=DT %s
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
// RUN: ld.lld -shared %t2.o -o %t2.so
// RUN: ld.lld %t.o %t2.so -o %t
// RUN: llvm-readobj -dyn-relocations %t | FileCheck %s
// RUN: llvm-objdump -D %t | FileCheck --check-prefix=DIS %s
// RUN: llvm-readelf -dynamic-table %t | FileCheck --check-prefix=DT %s
// The dynamic relocation for foo should point to 16 bytes past the start of
// the .got.plt section.
// CHECK: Dynamic Relocations {

View File

@ -1,8 +1,14 @@
// REQUIRES: ppc
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64le.s -o %t2.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
// RUN: ld.lld -shared %t2.o -o %t2.so
// RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
// RUN: ld.lld -shared %t2.o -o %t2.so
// RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s
// REQUIRES: ppc
# Calling external function bar needs a nop
// CHECK: call lacks nop, can't restore toc

View File

@ -1,8 +1,14 @@
// REQUIRES: ppc
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64le.s -o %t2.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
// RUN: ld.lld -shared %t2.o -o %t2.so
// RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
// RUN: ld.lld -shared %t2.o -o %t2.so
// RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s
// REQUIRES: ppc
# A tail call to an external function without a nop should issue an error.
// CHECK: call lacks nop, can't restore toc

View File

@ -1,9 +1,17 @@
// REQUIRES: ppc
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-func-global-entry.s -o %t2.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-func-local-entry.s -o %t3.o
// RUN: ld.lld -dynamic-linker /lib64/ld64.so.2 %t.o %t2.o %t3.o -o %t
// RUN: llvm-objdump -d %t | FileCheck %s
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-func-global-entry.s -o %t2.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-func-local-entry.s -o %t3.o
// RUN: ld.lld -dynamic-linker /lib64/ld64.so.2 %t.o %t2.o %t3.o -o %t
// RUN: llvm-objdump -d %t | FileCheck %s
.text
.abiversion 2
.globl _start # -- Begin function _start
@ -62,11 +70,11 @@ glob:
# point and we branch to start of foo_external_same.
// CHECK: _start:
// CHECK: 10010020: 91 00 00 48 bl .+144
// CHECK: 10010034: 55 00 00 48 bl .+84
// CHECK: 10010020: {{.*}} bl .+144
// CHECK: 10010034: {{.*}} bl .+84
// CHECK: foo_external_diff:
// CHECK-NEXT: 10010080: 02 00 4c 3c addis 2, 12, 2
// CHECK-NEXT: 10010084: 80 7f 42 38 addi 2, 2, 32640
// CHECK-NEXT: 10010088: ff ff a2 3c addis 5, 2, -1
// CHECK-NEXT: 10010080: {{.*}} addis 2, 12, 2
// CHECK-NEXT: 10010084: {{.*}} addi 2, 2, 32640
// CHECK-NEXT: 10010088: {{.*}} addis 5, 2, -1
// CHECK: foo_external_same:
// CHECK-NEXT: 100100b0: 14 1a 64 7c add 3, 4, 3
// CHECK-NEXT: 100100b0: {{.*}} add 3, 4, 3

View File

@ -1,33 +1,40 @@
# REQUIRES: ppc
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64le.s -o %t2.o
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
# RUN: ld.lld -shared %t2.o -o %t2.so
# RUN: ld.lld %t.o %t2.so -o %t
# RUN: llvm-objdump -d %t | FileCheck %s
# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
# RUN: ld.lld -shared %t2.o -o %t2.so
# RUN: ld.lld %t.o %t2.so -o %t
# RUN: llvm-objdump -d %t | FileCheck %s
# CHECK: _start:
# CHECK-NEXT: 10010004: 1d 00 00 48 bl .+28
# CHECK-NEXT: 10010008: 18 00 41 e8 ld 2, 24(1)
# CHECK-NEXT: 1001000c: 35 00 00 48 bl .+52
# CHECK-NEXT: 10010010: 18 00 41 e8 ld 2, 24(1)
# CHECK-NEXT: 10010004: {{.*}} bl .+28
# CHECK-NEXT: 10010008: {{.*}} ld 2, 24(1)
# CHECK-NEXT: 1001000c: {{.*}} bl .+52
# CHECK-NEXT: 10010010: {{.*}} ld 2, 24(1)
# 0x10010004 + 28 = 0x10010020 (PLT entry 0)
# 0x1001000c + 52 = 0x10010040 (PLT entry 1)
# CHECK: Disassembly of section .plt:
# CHECK-NEXT: .plt:
# CHECK-NEXT: 10010020: 18 00 41 f8 std 2, 24(1)
# CHECK-NEXT: 10010024: 02 10 82 3d addis 12, 2, 4098
# CHECK-NEXT: 10010028: 10 80 8c e9 ld 12, -32752(12)
# CHECK-NEXT: 1001002c: a6 03 89 7d mtctr 12
# CHECK-NEXT: 10010030: 20 04 80 4e bctr
# CHECK-NEXT: 10010034: 08 00 e0 7f trap
# CHECK-NEXT: 10010038: 08 00 e0 7f trap
# CHECK-NEXT: 1001003c: 08 00 e0 7f trap
# CHECK-NEXT: 10010040: 18 00 41 f8 std 2, 24(1)
# CHECK-NEXT: 10010044: 02 10 82 3d addis 12, 2, 4098
# CHECK-NEXT: 10010048: 18 80 8c e9 ld 12, -32744(12)
# CHECK-NEXT: 1001004c: a6 03 89 7d mtctr 12
# CHECK-NEXT: 10010020: {{.*}} std 2, 24(1)
# CHECK-NEXT: 10010024: {{.*}} addis 12, 2, 4098
# CHECK-NEXT: 10010028: {{.*}} ld 12, -32752(12)
# CHECK-NEXT: 1001002c: {{.*}} mtctr 12
# CHECK-NEXT: 10010030: {{.*}} bctr
# CHECK-NEXT: 10010034: {{.*}} trap
# CHECK-NEXT: 10010038: {{.*}} trap
# CHECK-NEXT: 1001003c: {{.*}} trap
# CHECK-NEXT: 10010040: {{.*}} std 2, 24(1)
# CHECK-NEXT: 10010044: {{.*}} addis 12, 2, 4098
# CHECK-NEXT: 10010048: {{.*}} ld 12, -32744(12)
# CHECK-NEXT: 1001004c: {{.*}} mtctr 12
.text
.abiversion 2

View File

@ -1,6 +1,13 @@
// REQUIRES: ppc
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64le.s -o %t2.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
// RUN: ld.lld -shared %t2.o -o %t2.so
// RUN: ld.lld %t.o %t2.so -o %t
// RUN: llvm-objdump -d %t | FileCheck %s
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
// RUN: ld.lld -shared %t2.o -o %t2.so
// RUN: ld.lld %t.o %t2.so -o %t
// RUN: llvm-objdump -d %t | FileCheck %s
@ -30,8 +37,8 @@ _start:
// CHECK: Disassembly of section .plt:
// CHECK: .plt:
// CHECK-NEXT: 18 00 41 f8 std 2, 24(1)
// CHECK-NEXT: fe ff 82 3d addis 12, 2, -2
// CHECK-NEXT: 40 7f 8c e9 ld 12, 32576(12)
// CHECK-NEXT: a6 03 89 7d mtctr 12
// CHECK: 20 04 80 4e bctr
// CHECK-NEXT: {{.*}} std 2, 24(1)
// CHECK-NEXT: {{.*}} addis 12, 2, -2
// CHECK-NEXT: {{.*}} ld 12, 32576(12)
// CHECK-NEXT: {{.*}} mtctr 12
// CHECK: {{.*}} bctr

View File

@ -1,32 +1,29 @@
# REQUIRES: ppc
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t
# RUN: ld.lld %t -o %t2
# RUN: llvm-objdump -d %t2 | FileCheck %s
# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
# RUN: ld.lld %t -o %t2
# RUN: llvm-objdump -d %t2 | FileCheck %s
# REQUIRES: ppc
# CHECK: Disassembly of section .text:
.section ".opd","aw"
.text
.global _start
_start:
.quad .Lfoo,.TOC.@tocbase,0
.text
.Lfoo:
li 0,1
li 3,42
sc
# CHECK: 10010000: 38 00 00 01 li 0, 1
# CHECK: 10010004: 38 60 00 2a li 3, 42
# CHECK: 10010008: 44 00 00 02 sc
# CHECK: 10010000: {{.*}} li 0, 1
# CHECK: 10010004: {{.*}} li 3, 42
# CHECK: 10010008: {{.*}} sc
.section ".opd","aw"
.global bar
bar:
.quad .Lbar,.TOC.@tocbase,0
.text
.Lbar:
bl _start
nop
bl .Lfoo
@ -34,9 +31,8 @@ bar:
blr
# FIXME: The printing here is misleading, the branch offset here is negative.
# CHECK: 1001000c: 4b ff ff f5 bl .+67108852
# CHECK: 10010010: 60 00 00 00 nop
# CHECK: 10010014: 4b ff ff ed bl .+67108844
# CHECK: 10010018: 60 00 00 00 nop
# CHECK: 1001001c: 4e 80 00 20 blr
# CHECK: 1001000c: {{.*}} bl .+67108852
# CHECK: 10010010: {{.*}} nop
# CHECK: 10010014: {{.*}} bl .+67108844
# CHECK: 10010018: {{.*}} nop
# CHECK: 1001001c: {{.*}} blr

View File

@ -1,14 +1,16 @@
# REQUIRES: ppc
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t
# RUN: ld.lld %t -o %t2
# RUN: llvm-objdump -d %t2 | FileCheck %s
# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
# RUN: ld.lld %t -o %t2
# RUN: llvm-objdump -d %t2 | FileCheck %s
# REQUIRES: ppc
.section ".opd","aw"
.global _start
_start:
.quad .Lfoo,.TOC.@tocbase,0
.text
.global _start
_start:
.Lfoo:
li 0,1
li 3,42
@ -25,7 +27,7 @@ _start:
# CHECK: Disassembly of section .R_PPC64_TOC16_LO_DS:
# CHECK: .FR_PPC64_TOC16_LO_DS:
# CHECK: 1001000c: e8 22 80 00 ld 1, -32768(2)
# CHECK: 1001000c: {{.*}} ld 1, -32768(2)
.section .R_PPC64_TOC16_LO,"ax",@progbits
.globl .FR_PPC64_TOC16_LO
@ -34,7 +36,7 @@ _start:
# CHECK: Disassembly of section .R_PPC64_TOC16_LO:
# CHECK: .FR_PPC64_TOC16_LO:
# CHECK: 10010010: 38 22 80 00 addi 1, 2, -32768
# CHECK: 10010010: {{.*}} addi 1, 2, -32768
.section .R_PPC64_TOC16_HI,"ax",@progbits
.globl .FR_PPC64_TOC16_HI
@ -43,7 +45,7 @@ _start:
# CHECK: Disassembly of section .R_PPC64_TOC16_HI:
# CHECK: .FR_PPC64_TOC16_HI:
# CHECK: 10010014: 3c 22 ff fe addis 1, 2, -2
# CHECK: 10010014: {{.*}} addis 1, 2, -2
.section .R_PPC64_TOC16_HA,"ax",@progbits
.globl .FR_PPC64_TOC16_HA
@ -52,7 +54,7 @@ _start:
# CHECK: Disassembly of section .R_PPC64_TOC16_HA:
# CHECK: .FR_PPC64_TOC16_HA:
# CHECK: 10010018: 3c 22 ff ff addis 1, 2, -1
# CHECK: 10010018: {{.*}} addis 1, 2, -1
.section .R_PPC64_REL24,"ax",@progbits
.globl .FR_PPC64_REL24
@ -63,7 +65,7 @@ _start:
# CHECK: Disassembly of section .R_PPC64_REL24:
# CHECK: .FR_PPC64_REL24:
# CHECK: 1001001c: 48 00 00 04 b .+4
# CHECK: 1001001c: {{.*}} b .+4
.section .R_PPC64_ADDR16_LO,"ax",@progbits
.globl .FR_PPC64_ADDR16_LO
@ -72,7 +74,7 @@ _start:
# CHECK: Disassembly of section .R_PPC64_ADDR16_LO:
# CHECK: .FR_PPC64_ADDR16_LO:
# CHECK: 10010020: 38 20 00 00 li 1, 0
# CHECK: 10010020: {{.*}} li 1, 0
.section .R_PPC64_ADDR16_HI,"ax",@progbits
.globl .FR_PPC64_ADDR16_HI
@ -81,7 +83,7 @@ _start:
# CHECK: Disassembly of section .R_PPC64_ADDR16_HI:
# CHECK: .FR_PPC64_ADDR16_HI:
# CHECK: 10010024: 38 20 10 01 li 1, 4097
# CHECK: 10010024: {{.*}} li 1, 4097
.section .R_PPC64_ADDR16_HA,"ax",@progbits
.globl .FR_PPC64_ADDR16_HA
@ -90,7 +92,7 @@ _start:
# CHECK: Disassembly of section .R_PPC64_ADDR16_HA:
# CHECK: .FR_PPC64_ADDR16_HA:
# CHECK: 10010028: 38 20 10 01 li 1, 4097
# CHECK: 10010028: {{.*}} li 1, 4097
.section .R_PPC64_ADDR16_HIGHER,"ax",@progbits
.globl .FR_PPC64_ADDR16_HIGHER
@ -99,7 +101,7 @@ _start:
# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHER:
# CHECK: .FR_PPC64_ADDR16_HIGHER:
# CHECK: 1001002c: 38 20 00 00 li 1, 0
# CHECK: 1001002c: {{.*}} li 1, 0
.section .R_PPC64_ADDR16_HIGHERA,"ax",@progbits
.globl .FR_PPC64_ADDR16_HIGHERA
@ -108,7 +110,7 @@ _start:
# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHERA:
# CHECK: .FR_PPC64_ADDR16_HIGHERA:
# CHECK: 10010030: 38 20 00 00 li 1, 0
# CHECK: 10010030: {{.*}} li 1, 0
.section .R_PPC64_ADDR16_HIGHEST,"ax",@progbits
.globl .FR_PPC64_ADDR16_HIGHEST
@ -117,7 +119,7 @@ _start:
# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHEST:
# CHECK: .FR_PPC64_ADDR16_HIGHEST:
# CHECK: 10010034: 38 20 00 00 li 1, 0
# CHECK: 10010034: {{.*}} li 1, 0
.section .R_PPC64_ADDR16_HIGHESTA,"ax",@progbits
.globl .FR_PPC64_ADDR16_HIGHESTA
@ -126,5 +128,5 @@ _start:
# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHESTA:
# CHECK: .FR_PPC64_ADDR16_HIGHESTA:
# CHECK: 10010038: 38 20 00 00 li 1, 0
# CHECK: 10010038: {{.*}} li 1, 0

View File

@ -1,27 +0,0 @@
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
// RUN: ld.lld -shared %t.o -o %t.so
// RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s
// REQUIRES: ppc
// When we create the TOC reference in the shared library, make sure that the
// R_PPC64_RELATIVE relocation uses the correct (non-zero) offset.
.globl foo
.align 2
.type foo,@function
.section .opd,"aw",@progbits
foo: # @foo
.align 3
.quad .Lfunc_begin0
.quad .TOC.@tocbase
.quad 0
.text
.Lfunc_begin0:
blr
// CHECK: 0x20000 R_PPC64_RELATIVE - 0x10000
// CHECK: 0x20008 R_PPC64_RELATIVE - 0x8000
// CHECK: Name: foo
// CHECK-NEXT: Value: 0x20000

View File

@ -1,9 +1,15 @@
# REQUIRES: ppc
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
# RUN: llvm-readobj -relocations %t.o | FileCheck -check-prefix=RELOCS %s
# RUN: ld.lld %t.o -o %t2
# RUN: llvm-objdump -D %t2 | FileCheck %s
# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
# RUN: llvm-readobj -relocations %t.o | FileCheck -check-prefix=RELOCS-BE %s
# RUN: ld.lld %t.o -o %t2
# RUN: llvm-objdump -D %t2 | FileCheck -check-prefix=CHECK-BE %s
# Make sure we calculate the offset correctly for a toc-relative access to a
# global variable as described by the PPC64 Elf V2 abi.
.abiversion 2
@ -44,6 +50,11 @@ _start:
# RELOCS: 0x8 R_PPC64_TOC16_HA global_a 0x0
# RELOCS: 0xC R_PPC64_TOC16_LO global_a 0x0
# RELOCS-BE: Relocations [
# RELOCS-BE-NEXT: .rela.text {
# RELOCS-BE: 0xA R_PPC64_TOC16_HA global_a 0x0
# RELOCS-NE: 0xE R_PPC64_TOC16_LO global_a 0x0
# Want to check _start for the values used to build the offset from the TOC base
# to global_a. The .TOC. symbol is expected at address 0x10030000, and the
# TOC base is address-of(.TOC.) + 0x8000. The expected offset is:
@ -52,13 +63,28 @@ _start:
# CHECK: Disassembly of section .text:
# CHECK-NEXT: _start:
# CHECK: 10010008: ff ff 62 3c addis 3, 2, -1
# CHECK-NEXT: 1001000c: 00 80 63 38 addi 3, 3, -32768
# CHECK: 10010008: {{.*}} addis 3, 2, -1
# CHECK-NEXT: 1001000c: {{.*}} addi 3, 3, -32768
# CHECK: Disassembly of section .data:
# CHECK-NEXT: global_a:
# CHECK-NEXT: 10020000: 29 00 00 00
# CHECK-NEXT: 10020000: {{.*}}
# CHECK: Disassembly of section .got:
# CHECK-NEXT: .got:
# CHECK-NEXT: 10030000: 00 80 03 10
# CHECK-BE: Disassembly of section .text:
# CHECK-BE-NEXT: _start:
# CHECK-BE: 10010008: {{.*}} addis 3, 2, -1
# CHECK-BE-NEXT: 1001000c: {{.*}} addi 3, 3, -32768
# CHECK-BE: Disassembly of section .data:
# CHECK-BE-NEXT: global_a:
# CHECK-BE-NEXT: 10020000: {{.*}}
# CHECK-BE: Disassembly of section .got:
# CHECK-BE-NEXT: .got:
# CHECK-BE-NEXT: 10030000: 00 00 00 00
# CHECK-BE-NEXT: 10030004: 10 03 80 00

View File

@ -1,10 +1,19 @@
// REQUIRES: ppc
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64le.s -o %t2.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-func.s -o %t3.o
// RUN: ld.lld -shared %t2.o -o %t2.so
// RUN: ld.lld %t.o %t2.so %t3.o -o %t
// RUN: llvm-objdump -d %t | FileCheck %s
// REQUIRES: ppc
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-func.s -o %t3.o
// RUN: ld.lld -shared %t2.o -o %t2.so
// RUN: ld.lld %t.o %t2.so %t3.o -o %t
// RUN: llvm-objdump -d %t | FileCheck %s
.text
.abiversion 2
.global bar_local
@ -22,12 +31,12 @@ _start:
bl bar_local
// CHECK: _start:
// CHECK: 10010008: 49 00 00 48 bl .+72
// CHECK-NOT: 1001000c: 00 00 00 60 nop
// CHECK: 1001000c: 18 00 41 e8 ld 2, 24(1)
// CHECK: 10010010: f1 ff ff 4b bl .+67108848
// CHECK-NOT: 10010014: 00 00 00 60 nop
// CHECK-NOT: 10010014: 18 00 41 e8 ld 2, 24(1)
// CHECK: 10010008: {{.*}} bl .+72
// CHECK-NOT: 1001000c: {{.*}} nop
// CHECK: 1001000c: {{.*}} ld 2, 24(1)
// CHECK: 10010010: {{.*}} bl .+67108848
// CHECK-NOT: 10010014: {{.*}} nop
// CHECK-NOT: 10010014: {{.*}} ld 2, 24(1)
# Calling a function in another object file which will have same
# TOC base does not need a nop. If nop present, do not rewrite to
@ -39,18 +48,18 @@ _diff_object:
nop
// CHECK: _diff_object:
// CHECK-NEXT: 10010014: 1d 00 00 48 bl .+28
// CHECK-NEXT: 10010018: 19 00 00 48 bl .+24
// CHECK-NEXT: 1001001c: 00 00 00 60 nop
// CHECK-NEXT: 10010014: {{.*}} bl .+28
// CHECK-NEXT: 10010018: {{.*}} bl .+24
// CHECK-NEXT: 1001001c: {{.*}} nop
# Branching to a local function does not need a nop
.global noretbranch
noretbranch:
b bar_local
// CHECK: noretbranch:
// CHECK: 10010020: e0 ff ff 4b b .+67108832
// CHECK-NOT: 10010024: 00 00 00 60 nop
// CHECK-NOT: 10010024: 18 00 41 e8 ld 2, 24(1)
// CHECK: 10010020: {{.*}} b .+67108832
// CHECK-NOT: 10010024: {{.*}} nop
// CHECK-NOT: 10010024: {{.*}} ld 2, 24(1)
// This should come last to check the end-of-buffer condition.
.global last
@ -58,12 +67,12 @@ last:
bl foo
nop
// CHECK: last:
// CHECK: 10010024: 2d 00 00 48 bl .+44
// CHECK-NEXT: 10010028: 18 00 41 e8 ld 2, 24(1)
// CHECK: 10010024: {{.*}} bl .+44
// CHECK-NEXT: 10010028: {{.*}} ld 2, 24(1)
// CHECK: Disassembly of section .plt:
// CHECK: .plt:
// CHECK-NEXT: 10010050: 18 00 41 f8 std 2, 24(1)
// CHECK-NEXT: 10010054: 02 10 82 3d addis 12, 2, 4098
// CHECK-NEXT: 10010058: 10 80 8c e9 ld 12, -32752(12)
// CHECK-NEXT: 1001005c: a6 03 89 7d mtctr 12
// CHECK-NEXT: 10010050: {{.*}} std 2, 24(1)
// CHECK-NEXT: 10010054: {{.*}} addis 12, 2, 4098
// CHECK-NEXT: 10010058: {{.*}} ld 12, -32752(12)
// CHECK-NEXT: 1001005c: {{.*}} mtctr 12

View File

@ -1,7 +1,12 @@
# REQUIRES: ppc
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
# RUN: ld.lld -shared %t.o -o %t.so
# RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s
# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
# RUN: ld.lld -shared %t.o -o %t.so
# RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s
# REQUIRES: ppc
.section ".toc","aw"
.quad weakfunc

View File

@ -1,17 +1,18 @@
# REQUIRES: ppc
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t
# RUN: ld.lld %t -o %t2
# RUN: llvm-objdump -d %t2 | FileCheck %s
# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
# RUN: ld.lld %t -o %t2
# RUN: llvm-objdump -d %t2 | FileCheck %s
# REQUIRES: ppc
# CHECK: Disassembly of section .text:
.section ".opd","aw"
.text
.global _start
_start:
.quad .Lfoo,.TOC.@tocbase,0
.text
.Lfoo:
bl weakfunc
nop
blr
@ -22,6 +23,6 @@ _start:
# be unreachable. But, we should link successfully. We should not, however,
# generate a .plt entry (this would be wasted space). For now, we do nothing
# (leaving the zero relative offset present in the input).
# CHECK: 10010000: 48 00 00 01 bl .+0
# CHECK: 10010004: 60 00 00 00 nop
# CHECK: 10010008: 4e 80 00 20 blr
# CHECK: 10010000: {{.*}} bl .+0
# CHECK: 10010004: {{.*}} nop
# CHECK: 10010008: {{.*}} blr

View File

@ -1,8 +1,13 @@
# REQUIRES: ppc
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t
# RUN: ld.lld %t -o %t2
# RUN: llvm-objdump -D %t2 | FileCheck %s
# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
# RUN: ld.lld %t -o %t2
# RUN: llvm-objdump -D %t2 | FileCheck -check-prefix=CHECK-BE %s
.text
.abiversion 2
.globl _start
@ -27,10 +32,19 @@ _start:
.Lfunc_end0:
.size _start, .Lfunc_end0-.Lfunc_begin0
// CHECK: 10010000: 01 10 80 3c lis 4, 4097
// CHECK-NEXT: 10010004: 00 00 84 38 addi 4, 4, 0
// CHECK-NEXT: 10010008: 02 00 a0 3c lis 5, 2
// CHECK-NEXT: 1001000c: 00 80 a5 38 addi 5, 5, -32768
// CHECK: 10010000: {{.*}} lis 4, 4097
// CHECK-NEXT: 10010004: {{.*}} addi 4, 4, 0
// CHECK-NEXT: 10010008: {{.*}} lis 5, 2
// CHECK-NEXT: 1001000c: {{.*}} addi 5, 5, -32768
// CHECK: Disassembly of section .got:
// CHECK-NEXT: .got:
// CHECK-NEXT: 10020000: 00 80 02 10
// CHECK-BE: 10010000: {{.*}} lis 4, 4097
// CHECK-BE-NEXT: 10010004: {{.*}} addi 4, 4, 0
// CHECK-BE-NEXT: 10010008: {{.*}} lis 5, 2
// CHECK-BE-NEXT: 1001000c: {{.*}} addi 5, 5, -32768
// CHECK-BE: Disassembly of section .got:
// CHECK-BE-NEXT: .got:
// CHECK-BE-NEXT: 10020000: 00 00 00 00 {{.*}}
// CHECK-BE-NEXT: 10020004: 10 02 80 00 {{.*}}

View File

@ -1,6 +1,11 @@
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
// RUN: ld.lld -shared %t.o -o %t.so
// RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
// RUN: ld.lld -shared %t.o -o %t.so
// RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s
// REQUIRES: ppc
// Test that we create R_PPC64_RELATIVE relocations but don't put any

View File

@ -1,9 +1,16 @@
// REQUIRES: ppc
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared.s -o %t2.o
// RUN: ld.lld -shared %t2.o -o %t2.so
// RUN: ld.lld -dynamic-linker /lib64/ld64.so.1 -rpath foo -rpath bar --export-dynamic %t.o %t2.so -o %t
// RUN: llvm-readobj --dynamic-table -s %t | FileCheck %s
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared.s -o %t2.o
// RUN: ld.lld -shared %t2.o -o %t2.so
// RUN: ld.lld -dynamic-linker /lib64/ld64.so.1 -rpath foo -rpath bar --export-dynamic %t.o %t2.so -o %t
// RUN: llvm-readobj --dynamic-table -s %t | FileCheck %s
// REQUIRES: ppc
// CHECK: Name: .rela.dyn
// CHECK-NEXT: Type: SHT_REL