diff --git a/llvm/include/llvm/BinaryFormat/XCOFF.h b/llvm/include/llvm/BinaryFormat/XCOFF.h index b6c3aaa51fc4f2..b58bcdc488223b 100644 --- a/llvm/include/llvm/BinaryFormat/XCOFF.h +++ b/llvm/include/llvm/BinaryFormat/XCOFF.h @@ -20,7 +20,12 @@ namespace llvm { namespace XCOFF { // Constants used in the XCOFF definition. -enum { FileNamePadSize = 6, NameSize = 8, SymbolTableEntrySize = 18 }; +enum { + FileNamePadSize = 6, + NameSize = 8, + SymbolTableEntrySize = 18, + RelocationSerializationSize32 = 10 +}; enum ReservedSectionNum { N_DEBUG = -2, N_ABS = -1, N_UNDEF = 0 }; diff --git a/llvm/include/llvm/MC/MCXCOFFObjectWriter.h b/llvm/include/llvm/MC/MCXCOFFObjectWriter.h index fe4087f70614c5..faad2ceb26910d 100644 --- a/llvm/include/llvm/MC/MCXCOFFObjectWriter.h +++ b/llvm/include/llvm/MC/MCXCOFFObjectWriter.h @@ -28,6 +28,13 @@ class MCXCOFFObjectTargetWriter : public MCObjectTargetWriter { } bool is64Bit() const { return Is64Bit; } + // Returns relocation info such as type, sign and size. + // First element of the pair contains type, + // second element contains sign and size. + virtual std::pair + getRelocTypeAndSignSize(const MCValue &Target, const MCFixup &Fixup, + bool IsPCRel) const = 0; + private: bool Is64Bit; }; diff --git a/llvm/lib/MC/MCXCOFFStreamer.cpp b/llvm/lib/MC/MCXCOFFStreamer.cpp index 6efa167ced42ac..50f31876ca55a2 100644 --- a/llvm/lib/MC/MCXCOFFStreamer.cpp +++ b/llvm/lib/MC/MCXCOFFStreamer.cpp @@ -69,9 +69,15 @@ void MCXCOFFStreamer::EmitInstToData(const MCInst &Inst, raw_svector_ostream VecOS(Code); Assembler.getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI); - // TODO: Handle Fixups later - + // Add the fixups and data. MCDataFragment *DF = getOrCreateDataFragment(&STI); + const size_t ContentsSize = DF->getContents().size(); + auto &DataFragmentFixups = DF->getFixups(); + for (auto &Fixup : Fixups) { + Fixup.setOffset(Fixup.getOffset() + ContentsSize); + DataFragmentFixups.push_back(Fixup); + } + DF->setHasInstructions(STI); DF->getContents().append(Code.begin(), Code.end()); } diff --git a/llvm/lib/MC/XCOFFObjectWriter.cpp b/llvm/lib/MC/XCOFFObjectWriter.cpp index e584c6222a5a2d..acb0e77807d69d 100644 --- a/llvm/lib/MC/XCOFFObjectWriter.cpp +++ b/llvm/lib/MC/XCOFFObjectWriter.cpp @@ -11,8 +11,11 @@ //===----------------------------------------------------------------------===// #include "llvm/BinaryFormat/XCOFF.h" +#include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCFixup.h" +#include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSectionXCOFF.h" #include "llvm/MC/MCSymbolXCOFF.h" @@ -49,6 +52,13 @@ constexpr int16_t MaxSectionIndex = INT16_MAX; // Packs the csect's alignment and type into a byte. uint8_t getEncodedType(const MCSectionXCOFF *); +struct XCOFFRelocation { + uint32_t SymbolTableIndex; + uint32_t FixupOffsetInCsect; + uint8_t SignAndSize; + uint8_t Type; +}; + // Wrapper around an MCSymbolXCOFF. struct Symbol { const MCSymbolXCOFF *const MCSym; @@ -69,6 +79,7 @@ struct ControlSection { uint32_t Size; SmallVector Syms; + SmallVector Relocations; StringRef getName() const { return MCCsect->getSectionName(); } ControlSection(const MCSectionXCOFF *MCSec) : MCCsect(MCSec), SymbolTableIndex(-1), Address(-1), Size(0) {} @@ -79,7 +90,6 @@ struct ControlSection { // with a storage mapping class of `xmc_pr` will get placed into the same // container. using CsectGroup = std::deque; - using CsectGroups = std::deque; // Represents the data related to a section excluding the csects that make up @@ -141,11 +151,21 @@ class XCOFFObjectWriter : public MCObjectWriter { uint32_t SymbolTableEntryCount = 0; uint32_t SymbolTableOffset = 0; uint16_t SectionCount = 0; + uint32_t RelocationEntryOffset = 0; support::endian::Writer W; std::unique_ptr TargetObjectWriter; StringTableBuilder Strings; + // Maps the MCSection representation to its corresponding ControlSection + // wrapper. Needed for finding the ControlSection to insert an MCSymbol into + // from its containing MCSectionXCOFF. + DenseMap SectionMap; + + // Maps the MCSymbol representation to its corrresponding symbol table index. + // Needed for relocation. + DenseMap SymbolIndexMap; + // CsectGroups. These store the csects which make up different parts of // the sections. Should have one for each set of csects that get mapped into // the same section and get handled in a 'similar' way. @@ -188,6 +208,8 @@ class XCOFFObjectWriter : public MCObjectWriter { void writeSectionHeaderTable(); void writeSections(const MCAssembler &Asm, const MCAsmLayout &Layout); void writeSymbolTable(const MCAsmLayout &Layout); + void writeRelocations(); + void writeRelocation(XCOFFRelocation Reloc, const ControlSection &CSection); // Called after all the csects and symbols have been processed by // `executePostLayoutBinding`, this function handles building up the majority @@ -198,6 +220,7 @@ class XCOFFObjectWriter : public MCObjectWriter { // *) Builds up the section header table by adding any non-empty sections to // `Sections`. void assignAddressesAndIndices(const MCAsmLayout &); + void finalizeSectionInfo(); bool needsAuxiliaryHeader() const { /* TODO aux header support not implemented. */ @@ -228,16 +251,20 @@ XCOFFObjectWriter::XCOFFObjectWriter( CsectGroups{&BSSCsects}) {} void XCOFFObjectWriter::reset() { - UndefinedCsects.clear(); + // Clear the mappings we created. + SymbolIndexMap.clear(); + SectionMap.clear(); + UndefinedCsects.clear(); // Reset any sections we have written to, and empty the section header table. for (auto *Sec : Sections) Sec->reset(); - // Reset the symbol table and string table. + // Reset states in XCOFFObjectWriter. SymbolTableEntryCount = 0; SymbolTableOffset = 0; SectionCount = 0; + RelocationEntryOffset = 0; Strings.clear(); MCObjectWriter::reset(); @@ -291,14 +318,9 @@ void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm, if (TargetObjectWriter->is64Bit()) report_fatal_error("64-bit XCOFF object files are not supported yet."); - // Maps the MC Section representation to its corresponding ControlSection - // wrapper. Needed for finding the ControlSection to insert an MCSymbol into - // from its containing MCSectionXCOFF. - DenseMap WrapperMap; - for (const auto &S : Asm) { const auto *MCSec = cast(&S); - assert(WrapperMap.find(MCSec) == WrapperMap.end() && + assert(SectionMap.find(MCSec) == SectionMap.end() && "Cannot add a csect twice."); assert(XCOFF::XTY_ER != MCSec->getCSectType() && "An undefined csect should not get registered."); @@ -310,7 +332,7 @@ void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm, CsectGroup &Group = getCsectGroup(MCSec); Group.emplace_back(MCSec); - WrapperMap[MCSec] = &Group.back(); + SectionMap[MCSec] = &Group.back(); } for (const MCSymbol &S : Asm.symbols()) { @@ -324,6 +346,7 @@ void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm, // Handle undefined symbol. if (ContainingCsect->getCSectType() == XCOFF::XTY_ER) { UndefinedCsects.emplace_back(ContainingCsect); + SectionMap[ContainingCsect] = &UndefinedCsects.back(); continue; } @@ -332,11 +355,11 @@ void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm, if (XSym == ContainingCsect->getQualNameSymbol()) continue; - assert(WrapperMap.find(ContainingCsect) != WrapperMap.end() && + assert(SectionMap.find(ContainingCsect) != SectionMap.end() && "Expected containing csect to exist in map"); // Lookup the containing csect and add the symbol to it. - WrapperMap[ContainingCsect]->Syms.emplace_back(XSym); + SectionMap[ContainingCsect]->Syms.emplace_back(XSym); // If the name does not fit in the storage provided in the symbol table // entry, add it to the string table. @@ -348,10 +371,62 @@ void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm, assignAddressesAndIndices(Layout); } -void XCOFFObjectWriter::recordRelocation(MCAssembler &, const MCAsmLayout &, - const MCFragment *, const MCFixup &, - MCValue, uint64_t &) { - // TODO: recordRelocation is not yet implemented. +void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCFragment *Fragment, + const MCFixup &Fixup, MCValue Target, + uint64_t &FixedValue) { + + if (Target.getSymB()) + report_fatal_error("Handling Target.SymB for relocation is unimplemented."); + + const MCSymbol &SymA = Target.getSymA()->getSymbol(); + + MCAsmBackend &Backend = Asm.getBackend(); + bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags & + MCFixupKindInfo::FKF_IsPCRel; + + uint8_t Type; + uint8_t SignAndSize; + std::tie(Type, SignAndSize) = + TargetObjectWriter->getRelocTypeAndSignSize(Target, Fixup, IsPCRel); + + const MCSectionXCOFF *SymASec = + cast(SymA).getContainingCsect(); + assert(SectionMap.find(SymASec) != SectionMap.end() && + "Expected containing csect to exist in map."); + + // If we could not find SymA directly in SymbolIndexMap, this symbol could + // either be a temporary symbol or an undefined symbol. In this case, we + // would need to have the relocation reference its csect instead. + uint32_t Index = SymbolIndexMap.find(&SymA) != SymbolIndexMap.end() + ? SymbolIndexMap[&SymA] + : SymbolIndexMap[SymASec->getQualNameSymbol()]; + + if (Type == XCOFF::RelocationType::R_POS) + // The FixedValue should be symbol's virtual address in this object file + // plus any constant value that we might get. + // Notice that SymA.isDefined() could return false, but SymASec could still + // be a defined csect. One of the example is the TOC-base symbol. + FixedValue = SectionMap[SymASec]->Address + + (SymA.isDefined() ? Layout.getSymbolOffset(SymA) : 0) + + Target.getConstant(); + else if (Type == XCOFF::RelocationType::R_TOC) + // The FixedValue should be the TC entry offset from TOC-base. + FixedValue = SectionMap[SymASec]->Address - TOCCsects.front().Address; + + assert( + (TargetObjectWriter->is64Bit() || + Fixup.getOffset() <= UINT32_MAX - Layout.getFragmentOffset(Fragment)) && + "Fragment offset + fixup offset is overflowed in 32-bit mode."); + uint32_t FixupOffsetInCsect = + Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); + + XCOFFRelocation Reloc = {Index, FixupOffsetInCsect, SignAndSize, Type}; + MCSectionXCOFF *RelocationSec = cast(Fragment->getParent()); + assert(SectionMap.find(RelocationSec) != SectionMap.end() && + "Expected containing csect to exist in map."); + SectionMap[RelocationSec]->Relocations.push_back(Reloc); } void XCOFFObjectWriter::writeSections(const MCAssembler &Asm, @@ -396,12 +471,13 @@ uint64_t XCOFFObjectWriter::writeObject(MCAssembler &Asm, if (TargetObjectWriter->is64Bit()) report_fatal_error("64-bit XCOFF object files are not supported yet."); + finalizeSectionInfo(); uint64_t StartOffset = W.OS.tell(); writeFileHeader(); writeSectionHeaderTable(); writeSections(Asm, Layout); - // TODO writeRelocations(); + writeRelocations(); writeSymbolTable(Layout); // Write the string table. @@ -536,19 +612,46 @@ void XCOFFObjectWriter::writeSectionHeaderTable() { W.write(Sec->Size); W.write(Sec->FileOffsetToData); + W.write(Sec->FileOffsetToRelocations); - // Relocation pointer and Lineno pointer. Not supported yet. - W.write(0); + // Line number pointer. Not supported yet. W.write(0); - // Relocation and line-number counts. Not supported yet. - W.write(0); + W.write(Sec->RelocationCount); + + // Line number counts. Not supported yet. W.write(0); W.write(Sec->Flags); } } +void XCOFFObjectWriter::writeRelocation(XCOFFRelocation Reloc, + const ControlSection &CSection) { + W.write(CSection.Address + Reloc.FixupOffsetInCsect); + W.write(Reloc.SymbolTableIndex); + W.write(Reloc.SignAndSize); + W.write(Reloc.Type); +} + +void XCOFFObjectWriter::writeRelocations() { + for (const auto *Section : Sections) { + if (Section->Index == Section::UninitializedIndex) + // Nothing to write for this Section. + continue; + + for (const auto *Group : Section->Groups) { + if (Group->empty()) + continue; + + for (const auto &Csect : *Group) { + for (const auto Reloc : Csect.Relocations) + writeRelocation(Reloc, Csect); + } + } + } +} + void XCOFFObjectWriter::writeSymbolTable(const MCAsmLayout &Layout) { for (const auto &Csect : UndefinedCsects) { writeSymbolTableEntryForControlSection( @@ -556,8 +659,8 @@ void XCOFFObjectWriter::writeSymbolTable(const MCAsmLayout &Layout) { } for (const auto *Section : Sections) { - // Nothing to write for this Section. if (Section->Index == Section::UninitializedIndex) + // Nothing to write for this Section. continue; for (const auto *Group : Section->Groups) { @@ -578,6 +681,41 @@ void XCOFFObjectWriter::writeSymbolTable(const MCAsmLayout &Layout) { } } +void XCOFFObjectWriter::finalizeSectionInfo() { + for (auto *Section : Sections) { + if (Section->Index == Section::UninitializedIndex) + // Nothing to record for this Section. + continue; + + for (const auto *Group : Section->Groups) { + if (Group->empty()) + continue; + + for (auto &Csect : *Group) + Section->RelocationCount += Csect.Relocations.size(); + } + } + + // Calculate the file offset to the relocation entries. + uint64_t RawPointer = RelocationEntryOffset; + for (auto Sec : Sections) { + if (Sec->Index == Section::UninitializedIndex || !Sec->RelocationCount) + continue; + + Sec->FileOffsetToRelocations = RawPointer; + const uint32_t RelocationSizeInSec = + Sec->RelocationCount * XCOFF::RelocationSerializationSize32; + RawPointer += RelocationSizeInSec; + if (RawPointer > UINT32_MAX) + report_fatal_error("Relocation data overflowed this object file."); + } + + // TODO Error check that the number of symbol table entries fits in 32-bits + // signed ... + if (SymbolTableEntryCount) + SymbolTableOffset = RawPointer; +} + void XCOFFObjectWriter::assignAddressesAndIndices(const MCAsmLayout &Layout) { // The first symbol table entry is for the file name. We are not emitting it // yet, so start at index 0. @@ -588,6 +726,7 @@ void XCOFFObjectWriter::assignAddressesAndIndices(const MCAsmLayout &Layout) { Csect.Size = 0; Csect.Address = 0; Csect.SymbolTableIndex = SymbolTableIndex; + SymbolIndexMap[Csect.MCCsect->getQualNameSymbol()] = Csect.SymbolTableIndex; // 1 main and 1 auxiliary symbol table entry for each contained symbol. SymbolTableIndex += 2; } @@ -622,11 +761,13 @@ void XCOFFObjectWriter::assignAddressesAndIndices(const MCAsmLayout &Layout) { Csect.Size = Layout.getSectionAddressSize(MCSec); Address = Csect.Address + Csect.Size; Csect.SymbolTableIndex = SymbolTableIndex; + SymbolIndexMap[MCSec->getQualNameSymbol()] = Csect.SymbolTableIndex; // 1 main and 1 auxiliary symbol table entry for the csect. SymbolTableIndex += 2; for (auto &Sym : Csect.Syms) { Sym.SymbolTableIndex = SymbolTableIndex; + SymbolIndexMap[Sym.MCSym] = Sym.SymbolTableIndex; // 1 main and 1 auxiliary symbol table entry for each contained // symbol. SymbolTableIndex += 2; @@ -656,14 +797,11 @@ void XCOFFObjectWriter::assignAddressesAndIndices(const MCAsmLayout &Layout) { Sec->FileOffsetToData = RawPointer; RawPointer += Sec->Size; + if (RawPointer > UINT32_MAX) + report_fatal_error("Section raw data overflowed this object file."); } - // TODO Add in Relocation storage to the RawPointer Calculation. - // TODO What to align the SymbolTable to? - // TODO Error check that the number of symbol table entries fits in 32-bits - // signed ... - if (SymbolTableEntryCount) - SymbolTableOffset = RawPointer; + RelocationEntryOffset = RawPointer; } // Takes the log base 2 of the alignment and shifts the result into the 5 most diff --git a/llvm/lib/Object/XCOFFObjectFile.cpp b/llvm/lib/Object/XCOFFObjectFile.cpp index f98cd69a0d379d..51fc661016469d 100644 --- a/llvm/lib/Object/XCOFFObjectFile.cpp +++ b/llvm/lib/Object/XCOFFObjectFile.cpp @@ -608,6 +608,7 @@ XCOFFObjectFile::relocations(const XCOFFSectionHeader32 &Sec) const { uint32_t NumRelocEntries = NumRelocEntriesOrErr.get(); + assert(sizeof(XCOFFRelocation32) == XCOFF::RelocationSerializationSize32); auto RelocationOrErr = getObject(Data, reinterpret_cast(RelocAddr), NumRelocEntries * sizeof(XCOFFRelocation32)); diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp index 7fdbb8990b5536..d672d54772e0a1 100644 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp @@ -7,16 +7,26 @@ // //===----------------------------------------------------------------------===// -#include "PPCMCTargetDesc.h" +#include "MCTargetDesc/PPCFixupKinds.h" +#include "MCTargetDesc/PPCMCTargetDesc.h" +#include "llvm/BinaryFormat/XCOFF.h" +#include "llvm/MC/MCFixup.h" +#include "llvm/MC/MCFixupKindInfo.h" +#include "llvm/MC/MCValue.h" #include "llvm/MC/MCXCOFFObjectWriter.h" using namespace llvm; namespace { class PPCXCOFFObjectWriter : public MCXCOFFObjectTargetWriter { + static constexpr uint8_t SignBitMask = 0x80; public: PPCXCOFFObjectWriter(bool Is64Bit); + + std::pair + getRelocTypeAndSignSize(const MCValue &Target, const MCFixup &Fixup, + bool IsPCRel) const override; }; } // end anonymous namespace @@ -27,3 +37,40 @@ std::unique_ptr llvm::createPPCXCOFFObjectWriter(bool Is64Bit) { return std::make_unique(Is64Bit); } + +std::pair PPCXCOFFObjectWriter::getRelocTypeAndSignSize( + const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const { + const MCSymbolRefExpr::VariantKind Modifier = + Target.isAbsolute() ? MCSymbolRefExpr::VK_None + : Target.getSymA()->getKind(); + // People from AIX OS team says AIX link editor does not care about + // the sign bit in the relocation entry "most" of the time. + // The system assembler seems to set the sign bit on relocation entry + // based on similar property of IsPCRel. So we will do the same here. + // TODO: More investigation on how assembler decides to set the sign + // bit, and we might want to match that. + const uint8_t EncodedSignednessIndicator = IsPCRel ? SignBitMask : 0u; + + // The magic number we use in SignAndSize has a strong relationship with + // the corresponding MCFixupKind. In most cases, it's the MCFixupKind + // number - 1, because SignAndSize encodes the bit length being + // relocated minus 1. + switch ((unsigned)Fixup.getKind()) { + default: + report_fatal_error("Unimplemented fixup kind."); + case PPC::fixup_ppc_half16: + switch (Modifier) { + default: + report_fatal_error("Unsupported modifier for half16 fixup."); + case MCSymbolRefExpr::VK_None: + return {XCOFF::RelocationType::R_TOC, EncodedSignednessIndicator | 15}; + } + break; + case PPC::fixup_ppc_br24: + // Branches are 4 byte aligned, so the 24 bits we encode in + // the instruction actually represents a 26 bit offset. + return {XCOFF::RelocationType::R_RBR, EncodedSignednessIndicator | 25}; + case FK_Data_4: + return {XCOFF::RelocationType::R_POS, EncodedSignednessIndicator | 31}; + } +} diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp index fa5b13317c7e6f..6b708cad07f90e 100644 --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -1674,6 +1674,16 @@ void PPCAIXAsmPrinter::EmitEndOfAsmFile(Module &M) { PPCTargetStreamer &TS = static_cast(*OutStreamer->getTargetStreamer()); + const unsigned EntryByteSize = Subtarget->isPPC64() ? 8 : 4; + const unsigned TOCEntriesByteSize = TOC.size() * EntryByteSize; + // TODO: If TOC entries' size is larger than 32768, then we run out of + // positive displacement to reach the TOC entry. We need to decide how to + // handle entries' size larger than that later. + if (TOCEntriesByteSize > 32767) { + report_fatal_error("Handling of TOC entry displacement larger than 32767 " + "is not yet implemented."); + } + for (auto &I : TOC) { // Setup the csect for the current TC entry. MCSectionXCOFF *TCEntry = cast( diff --git a/llvm/test/CodeGen/PowerPC/aix-user-defined-memcpy.ll b/llvm/test/CodeGen/PowerPC/aix-user-defined-memcpy.ll index 0b892a3ded615b..9116ea4e8d9d78 100644 --- a/llvm/test/CodeGen/PowerPC/aix-user-defined-memcpy.ll +++ b/llvm/test/CodeGen/PowerPC/aix-user-defined-memcpy.ll @@ -6,6 +6,8 @@ ; RUN: llvm-readobj --relocs --expand-relocs %t.o | FileCheck \ ; RUN: --check-prefix=32-REL %s +; RUN: llvm-objdump -D %t.o | FileCheck --check-prefix=32-DIS %s + ; RUN: not llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff \ ; RUN: -mcpu=pwr4 -mattr=-altivec -filetype=obj < %s 2>&1 | FileCheck \ ; RUN: --check-prefix=64-CHECK %s @@ -28,8 +30,10 @@ entry: declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture writeonly, i8* nocapture readonly, i32, i1) -; TODO: This test should preferably check the symbol table for .o file and -; the relocation associated with the call. +; This test check +; 1. The symbol table for .o file to verify .memcpy is a defined external label. +; 2. There is no relocation associated with the call, since callee is defined. +; 3. Branch instruction in raw data is branching back to the right callee location. ; 32-SYM: Symbol {{[{][[:space:]] *}}Index: [[#Index:]]{{[[:space:]] *}}Name: .memcpy ; 32-SYM-NEXT: Value (RelocatableAddress): 0x0 @@ -52,7 +56,60 @@ declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture writeonly, i8* nocapture r ; 32-SYM-NOT: .memcpy -; We are expecting to have the test fail when the support for relocations land. -; 32-REL-NOT: Relocation{{[[:space:]]}} +; 32-REL: Relocations [ +; 32-REL-NEXT: Section (index: 2) .data { +; 32-REL-NEXT: Relocation { +; 32-REL-NEXT: Virtual Address: 0x34 +; 32-REL-NEXT: Symbol: .memcpy (2) +; 32-REL-NEXT: IsSigned: No +; 32-REL-NEXT: FixupBitValue: 0 +; 32-REL-NEXT: Length: 32 +; 32-REL-NEXT: Type: R_POS (0x0) +; 32-REL-NEXT: } +; 32-REL-NEXT: Relocation { +; 32-REL-NEXT: Virtual Address: 0x38 +; 32-REL-NEXT: Symbol: TOC (14) +; 32-REL-NEXT: IsSigned: No +; 32-REL-NEXT: FixupBitValue: 0 +; 32-REL-NEXT: Length: 32 +; 32-REL-NEXT: Type: R_POS (0x0) +; 32-REL-NEXT: } +; 32-REL-NEXT: Relocation { +; 32-REL-NEXT: Virtual Address: 0x40 +; 32-REL-NEXT: Symbol: .call_memcpy (4) +; 32-REL-NEXT: IsSigned: No +; 32-REL-NEXT: FixupBitValue: 0 +; 32-REL-NEXT: Length: 32 +; 32-REL-NEXT: Type: R_POS (0x0) +; 32-REL-NEXT: } +; 32-REL-NEXT: Relocation { +; 32-REL-NEXT: Virtual Address: 0x44 +; 32-REL-NEXT: Symbol: TOC (14) +; 32-REL-NEXT: IsSigned: No +; 32-REL-NEXT: FixupBitValue: 0 +; 32-REL-NEXT: Length: 32 +; 32-REL-NEXT: Type: R_POS (0x0) +; 32-REL-NEXT: } +; 32-REL-NEXT: } +; 32-REL-NEXT: ] + +; 32-REL-NOT: Type: R_RBR (0x1A) + +; 32-DIS: Disassembly of section .text: +; 32-DIS: 00000000 .text: +; 32-DIS-NEXT: 0: 38 60 00 03 li 3, 3 +; 32-DIS-NEXT: 4: 4e 80 00 20 blr +; 32-DIS-NEXT: 8: 60 00 00 00 nop +; 32-DIS-NEXT: c: 60 00 00 00 nop +; 32-DIS: 00000010 .call_memcpy: +; 32-DIS-NEXT: 10: 7c 08 02 a6 mflr 0 +; 32-DIS-NEXT: 14: 90 01 00 08 stw 0, 8(1) +; 32-DIS-NEXT: 18: 94 21 ff c0 stwu 1, -64(1) +; 32-DIS-NEXT: 1c: 4b ff ff e5 bl .-28 +; 32-DIS-NEXT: 20: 60 00 00 00 nop +; 32-DIS-NEXT: 24: 38 21 00 40 addi 1, 1, 64 +; 32-DIS-NEXT: 28: 80 01 00 08 lwz 0, 8(1) +; 32-DIS-NEXT: 2c: 7c 08 03 a6 mtlr 0 +; 32-DIS-NEXT: 30: 4e 80 00 20 blr ; 64-CHECK: LLVM ERROR: 64-bit XCOFF object files are not supported yet. diff --git a/llvm/test/CodeGen/PowerPC/aix-xcoff-reloc.ll b/llvm/test/CodeGen/PowerPC/aix-xcoff-reloc.ll new file mode 100644 index 00000000000000..8b7032af660008 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-xcoff-reloc.ll @@ -0,0 +1,448 @@ +; RUN: llc -verify-machineinstrs -mcpu=pwr4 -mtriple powerpc-ibm-aix-xcoff -mattr=-altivec -filetype=obj -o %t.o < %s +; RUN: llvm-readobj --section-headers --file-header %t.o | \ +; RUN: FileCheck --check-prefix=OBJ %s +; RUN: llvm-readobj --relocs --expand-relocs %t.o | FileCheck --check-prefix=RELOC %s +; RUN: llvm-readobj -t %t.o | FileCheck --check-prefix=SYM %s +; RUN: llvm-objdump -D %t.o | FileCheck --check-prefix=DIS %s + +; RUN: not llc -verify-machineinstrs -mcpu=pwr4 -mtriple powerpc64-ibm-aix-xcoff -mattr=-altivec -filetype=obj < %s 2>&1 | \ +; RUN: FileCheck --check-prefix=XCOFF64 %s +; XCOFF64: LLVM ERROR: 64-bit XCOFF object files are not supported yet. + +@globalA = global i32 1, align 4 +@globalB = global i32 2, align 4 +@arr = global <{ i32, [9 x i32] }> <{ i32 3, [9 x i32] zeroinitializer }>, align 4 +@p = global i32* bitcast (i8* getelementptr (i8, i8* bitcast (<{ i32, [9 x i32] }>* @arr to i8*), i64 16) to i32*), align 4 + +define i32 @foo() { +entry: + %call = call i32 @bar(i32 1) + %0 = load i32, i32* @globalA, align 4 + %add = add nsw i32 %call, %0 + %1 = load i32, i32* @globalB, align 4 + %add1 = add nsw i32 %add, %1 + ret i32 %add1 +} + +declare i32 @bar(i32) + +; OBJ: File: {{.*}}aix-xcoff-reloc.ll.tmp.o +; OBJ-NEXT: Format: aixcoff-rs6000 +; OBJ-NEXT: Arch: powerpc +; OBJ-NEXT: AddressSize: 32bit +; OBJ-NEXT: FileHeader { +; OBJ-NEXT: Magic: 0x1DF +; OBJ-NEXT: NumberOfSections: 2 +; OBJ-NEXT: TimeStamp: None (0x0) +; OBJ-NEXT: SymbolTableOffset: 0x13C +; OBJ-NEXT: SymbolTableEntries: 26 +; OBJ-NEXT: OptionalHeaderSize: 0x0 +; OBJ-NEXT: Flags: 0x0 +; OBJ-NEXT: } +; OBJ-NEXT: Sections [ +; OBJ-NEXT: Section { +; OBJ-NEXT: Index: 1 +; OBJ-NEXT: Name: .text +; OBJ-NEXT: PhysicalAddress: 0x0 +; OBJ-NEXT: VirtualAddress: 0x0 +; OBJ-NEXT: Size: 0x40 +; OBJ-NEXT: RawDataOffset: 0x64 +; OBJ-NEXT: RelocationPointer: 0xEC +; OBJ-NEXT: LineNumberPointer: 0x0 +; OBJ-NEXT: NumberOfRelocations: 3 +; OBJ-NEXT: NumberOfLineNumbers: 0 +; OBJ-NEXT: Type: STYP_TEXT (0x20) +; OBJ-NEXT: } +; OBJ-NEXT: Section { +; OBJ-NEXT: Index: 2 +; OBJ-NEXT: Name: .data +; OBJ-NEXT: PhysicalAddress: 0x40 +; OBJ-NEXT: VirtualAddress: 0x40 +; OBJ-NEXT: Size: 0x48 +; OBJ-NEXT: RawDataOffset: 0xA4 +; OBJ-NEXT: RelocationPointer: 0x10A +; OBJ-NEXT: LineNumberPointer: 0x0 +; OBJ-NEXT: NumberOfRelocations: 5 +; OBJ-NEXT: NumberOfLineNumbers: 0 +; OBJ-NEXT: Type: STYP_DATA (0x40) +; OBJ-NEXT: } +; OBJ-NEXT: ] + + +; RELOC: File: {{.*}}aix-xcoff-reloc.ll.tmp.o +; RELOC-NEXT: Format: aixcoff-rs6000 +; RELOC-NEXT: Arch: powerpc +; RELOC-NEXT: AddressSize: 32bit +; RELOC-NEXT: Relocations [ +; RELOC-NEXT: Section (index: 1) .text { +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x10 +; RELOC-NEXT: Symbol: .bar (0) +; RELOC-NEXT: IsSigned: Yes +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 26 +; RELOC-NEXT: Type: R_RBR (0x1A) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x1A +; RELOC-NEXT: Symbol: globalA (22) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 16 +; RELOC-NEXT: Type: R_TOC (0x3) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x1E +; RELOC-NEXT: Symbol: globalB (24) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 16 +; RELOC-NEXT: Type: R_TOC (0x3) +; RELOC-NEXT: } +; RELOC-NEXT: } +; RELOC-NEXT: Section (index: 2) .data { +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x70 +; RELOC-NEXT: Symbol: arr (12) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 32 +; RELOC-NEXT: Type: R_POS (0x0) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x74 +; RELOC-NEXT: Symbol: .foo (4) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 32 +; RELOC-NEXT: Type: R_POS (0x0) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x78 +; RELOC-NEXT: Symbol: TOC (20) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 32 +; RELOC-NEXT: Type: R_POS (0x0) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x80 +; RELOC-NEXT: Symbol: globalA (8) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 32 +; RELOC-NEXT: Type: R_POS (0x0) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x84 +; RELOC-NEXT: Symbol: globalB (10) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 32 +; RELOC-NEXT: Type: R_POS (0x0) +; RELOC-NEXT: } +; RELOC-NEXT: } +; RELOC-NEXT: ] + +; SYM: Symbols [ +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 0 +; SYM-NEXT: Name: .bar +; SYM-NEXT: Value (RelocatableAddress): 0x0 +; SYM-NEXT: Section: N_UNDEF +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_EXT (0x2) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 1 +; SYM-NEXT: SectionLen: 0 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 0 +; SYM-NEXT: SymbolType: XTY_ER (0x0) +; SYM-NEXT: StorageMappingClass: XMC_PR (0x0) +; SYM-NEXT: StabInfoIndex: 0x0 +; SYM-NEXT: StabSectNum: 0x0 +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 2 +; SYM-NEXT: Name: .text +; SYM-NEXT: Value (RelocatableAddress): 0x0 +; SYM-NEXT: Section: .text +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 3 +; SYM-NEXT: SectionLen: 64 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 4 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_PR (0x0) +; SYM-NEXT: StabInfoIndex: 0x0 +; SYM-NEXT: StabSectNum: 0x0 +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 4 +; SYM-NEXT: Name: .foo +; SYM-NEXT: Value (RelocatableAddress): 0x0 +; SYM-NEXT: Section: .text +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_EXT (0x2) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 5 +; SYM-NEXT: ContainingCsectSymbolIndex: 2 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 0 +; SYM-NEXT: SymbolType: XTY_LD (0x2) +; SYM-NEXT: StorageMappingClass: XMC_PR (0x0) +; SYM-NEXT: StabInfoIndex: 0x0 +; SYM-NEXT: StabSectNum: 0x0 +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 6 +; SYM-NEXT: Name: .data +; SYM-NEXT: Value (RelocatableAddress): 0x40 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 7 +; SYM-NEXT: SectionLen: 52 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 2 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_RW (0x5) +; SYM-NEXT: StabInfoIndex: 0x0 +; SYM-NEXT: StabSectNum: 0x0 +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 8 +; SYM-NEXT: Name: globalA +; SYM-NEXT: Value (RelocatableAddress): 0x40 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_EXT (0x2) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 9 +; SYM-NEXT: ContainingCsectSymbolIndex: 6 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 0 +; SYM-NEXT: SymbolType: XTY_LD (0x2) +; SYM-NEXT: StorageMappingClass: XMC_RW (0x5) +; SYM-NEXT: StabInfoIndex: 0x0 +; SYM-NEXT: StabSectNum: 0x0 +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 10 +; SYM-NEXT: Name: globalB +; SYM-NEXT: Value (RelocatableAddress): 0x44 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_EXT (0x2) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 11 +; SYM-NEXT: ContainingCsectSymbolIndex: 6 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 0 +; SYM-NEXT: SymbolType: XTY_LD (0x2) +; SYM-NEXT: StorageMappingClass: XMC_RW (0x5) +; SYM-NEXT: StabInfoIndex: 0x0 +; SYM-NEXT: StabSectNum: 0x0 +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 12 +; SYM-NEXT: Name: arr +; SYM-NEXT: Value (RelocatableAddress): 0x48 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_EXT (0x2) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 13 +; SYM-NEXT: ContainingCsectSymbolIndex: 6 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 0 +; SYM-NEXT: SymbolType: XTY_LD (0x2) +; SYM-NEXT: StorageMappingClass: XMC_RW (0x5) +; SYM-NEXT: StabInfoIndex: 0x0 +; SYM-NEXT: StabSectNum: 0x0 +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 14 +; SYM-NEXT: Name: p +; SYM-NEXT: Value (RelocatableAddress): 0x70 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_EXT (0x2) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 15 +; SYM-NEXT: ContainingCsectSymbolIndex: 6 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 0 +; SYM-NEXT: SymbolType: XTY_LD (0x2) +; SYM-NEXT: StorageMappingClass: XMC_RW (0x5) +; SYM-NEXT: StabInfoIndex: 0x0 +; SYM-NEXT: StabSectNum: 0x0 +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 16 +; SYM-NEXT: Name: foo +; SYM-NEXT: Value (RelocatableAddress): 0x74 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 17 +; SYM-NEXT: SectionLen: 12 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 0 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_DS (0xA) +; SYM-NEXT: StabInfoIndex: 0x0 +; SYM-NEXT: StabSectNum: 0x0 +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 18 +; SYM-NEXT: Name: foo +; SYM-NEXT: Value (RelocatableAddress): 0x74 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_EXT (0x2) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 19 +; SYM-NEXT: ContainingCsectSymbolIndex: 16 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 0 +; SYM-NEXT: SymbolType: XTY_LD (0x2) +; SYM-NEXT: StorageMappingClass: XMC_DS (0xA) +; SYM-NEXT: StabInfoIndex: 0x0 +; SYM-NEXT: StabSectNum: 0x0 +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 20 +; SYM-NEXT: Name: TOC +; SYM-NEXT: Value (RelocatableAddress): 0x80 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 21 +; SYM-NEXT: SectionLen: 0 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 2 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_TC0 (0xF) +; SYM-NEXT: StabInfoIndex: 0x0 +; SYM-NEXT: StabSectNum: 0x0 +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 22 +; SYM-NEXT: Name: globalA +; SYM-NEXT: Value (RelocatableAddress): 0x80 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 23 +; SYM-NEXT: SectionLen: 4 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 2 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_TC (0x3) +; SYM-NEXT: StabInfoIndex: 0x0 +; SYM-NEXT: StabSectNum: 0x0 +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 24 +; SYM-NEXT: Name: globalB +; SYM-NEXT: Value (RelocatableAddress): 0x84 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 25 +; SYM-NEXT: SectionLen: 4 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 2 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_TC (0x3) +; SYM-NEXT: StabInfoIndex: 0x0 +; SYM-NEXT: StabSectNum: 0x0 +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: ] + + +; DIS: {{.*}}aix-xcoff-reloc.ll.tmp.o: file format aixcoff-rs6000 +; DIS: Disassembly of section .text: +; DIS: 00000000 .text: +; DIS-NEXT: 0: 7c 08 02 a6 mflr 0 +; DIS-NEXT: 4: 90 01 00 08 stw 0, 8(1) +; DIS-NEXT: 8: 94 21 ff c0 stwu 1, -64(1) +; DIS-NEXT: c: 38 60 00 01 li 3, 1 +; DIS-NEXT: 10: 4b ff ff f1 bl .-16 +; DIS-NEXT: 14: 60 00 00 00 nop +; DIS-NEXT: 18: 80 82 00 00 lwz 4, 0(2) +; DIS-NEXT: 1c: 80 a2 00 04 lwz 5, 4(2) +; DIS-NEXT: 20: 80 84 00 00 lwz 4, 0(4) +; DIS-NEXT: 24: 80 a5 00 00 lwz 5, 0(5) +; DIS-NEXT: 28: 7c 63 22 14 add 3, 3, 4 +; DIS-NEXT: 2c: 7c 63 2a 14 add 3, 3, 5 +; DIS-NEXT: 30: 38 21 00 40 addi 1, 1, 64 +; DIS-NEXT: 34: 80 01 00 08 lwz 0, 8(1) +; DIS-NEXT: 38: 7c 08 03 a6 mtlr 0 +; DIS-NEXT: 3c: 4e 80 00 20 blr + +; DIS: Disassembly of section .data: +; DIS: 00000040 globalA: +; DIS-NEXT: 40: 00 00 00 01 +; DIS: 00000044 globalB: +; DIS-NEXT: 44: 00 00 00 02 +; DIS: 00000048 arr: +; DIS-NEXT: 48: 00 00 00 03 +; DIS-NEXT: ... +; DIS: 00000070 p: +; DIS-NEXT: 70: 00 00 00 58 +; DIS: 00000074 foo: +; DIS-NEXT: 74: 00 00 00 00 +; DIS-NEXT: 78: 00 00 00 80 +; DIS-NEXT: 7c: 00 00 00 00 +; DIS: 00000080 globalA: +; DIS-NEXT: 80: 00 00 00 40 +; DIS: 00000084 globalB: +; DIS-NEXT: 84: 00 00 00 44