[llvm] 3bbe7a6 - [XCOFF][AIX] Support basic relocation type on AIX

via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 30 08:00:09 PST 2020


Author: jasonliu
Date: 2020-01-30T15:59:09Z
New Revision: 3bbe7a681e0f98182daf268a314d1372073ea019

URL: https://github.com/llvm/llvm-project/commit/3bbe7a681e0f98182daf268a314d1372073ea019
DIFF: https://github.com/llvm/llvm-project/commit/3bbe7a681e0f98182daf268a314d1372073ea019.diff

LOG: [XCOFF][AIX] Support basic relocation type on AIX

Summary:

This patch intends to support three most common relocation type
on AIX: R_POS, R_TOC, R_RBR.
These three relocation type will be needed for object file generation
on AIX for small code model.
We will have follow up patches to bring relocation support for
large code model on AIX.

Reviewers: hubert.reinterpretcast, daltenty, DiggerLin

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

Added: 
    llvm/test/CodeGen/PowerPC/aix-xcoff-reloc.ll

Modified: 
    llvm/include/llvm/BinaryFormat/XCOFF.h
    llvm/include/llvm/MC/MCXCOFFObjectWriter.h
    llvm/lib/MC/MCXCOFFStreamer.cpp
    llvm/lib/MC/XCOFFObjectWriter.cpp
    llvm/lib/Object/XCOFFObjectFile.cpp
    llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp
    llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
    llvm/test/CodeGen/PowerPC/aix-user-defined-memcpy.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/BinaryFormat/XCOFF.h b/llvm/include/llvm/BinaryFormat/XCOFF.h
index b6c3aaa51fc4..b58bcdc48822 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 fe4087f70614..faad2ceb2691 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<uint8_t, uint8_t>
+  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 6efa167ced42..50f31876ca55 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 e584c6222a5a..acb0e77807d6 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<Symbol, 1> Syms;
+  SmallVector<XCOFFRelocation, 1> 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<ControlSection>;
-
 using CsectGroups = std::deque<CsectGroup *>;
 
 // 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<MCXCOFFObjectTargetWriter> 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<const MCSectionXCOFF *, ControlSection *> SectionMap;
+
+  // Maps the MCSymbol representation to its corrresponding symbol table index.
+  // Needed for relocation.
+  DenseMap<const MCSymbol *, uint32_t> SymbolIndexMap;
+
   // CsectGroups. These store the csects which make up 
diff erent 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<const MCSectionXCOFF *, ControlSection *> WrapperMap;
-
   for (const auto &S : Asm) {
     const auto *MCSec = cast<const MCSectionXCOFF>(&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<MCSymbolXCOFF>(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<MCSectionXCOFF>(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<uint32_t>(Sec->Size);
     W.write<uint32_t>(Sec->FileOffsetToData);
+    W.write<uint32_t>(Sec->FileOffsetToRelocations);
 
-    // Relocation pointer and Lineno pointer. Not supported yet.
-    W.write<uint32_t>(0);
+    // Line number pointer. Not supported yet.
     W.write<uint32_t>(0);
 
-    // Relocation and line-number counts. Not supported yet.
-    W.write<uint16_t>(0);
+    W.write<uint16_t>(Sec->RelocationCount);
+
+    // Line number counts. Not supported yet.
     W.write<uint16_t>(0);
 
     W.write<int32_t>(Sec->Flags);
   }
 }
 
+void XCOFFObjectWriter::writeRelocation(XCOFFRelocation Reloc,
+                                        const ControlSection &CSection) {
+  W.write<uint32_t>(CSection.Address + Reloc.FixupOffsetInCsect);
+  W.write<uint32_t>(Reloc.SymbolTableIndex);
+  W.write<uint8_t>(Reloc.SignAndSize);
+  W.write<uint8_t>(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 f98cd69a0d37..51fc66101646 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<XCOFFRelocation32>(Data, reinterpret_cast<void *>(RelocAddr),
                                    NumRelocEntries * sizeof(XCOFFRelocation32));

diff  --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp
index 7fdbb8990b55..d672d54772e0 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<uint8_t, uint8_t>
+  getRelocTypeAndSignSize(const MCValue &Target, const MCFixup &Fixup,
+                          bool IsPCRel) const override;
 };
 } // end anonymous namespace
 
@@ -27,3 +37,40 @@ std::unique_ptr<MCObjectTargetWriter>
 llvm::createPPCXCOFFObjectWriter(bool Is64Bit) {
   return std::make_unique<PPCXCOFFObjectWriter>(Is64Bit);
 }
+
+std::pair<uint8_t, uint8_t> 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 fa5b13317c7e..6b708cad07f9 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<PPCTargetStreamer &>(*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<MCSectionXCOFF>(

diff  --git a/llvm/test/CodeGen/PowerPC/aix-user-defined-memcpy.ll b/llvm/test/CodeGen/PowerPC/aix-user-defined-memcpy.ll
index 0b892a3ded61..9116ea4e8d9d 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 000000000000..8b7032af6600
--- /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.
+
+ at globalA = global i32 1, align 4
+ at globalB = global i32 2, align 4
+ at arr = global <{ i32, [9 x i32] }> <{ i32 3, [9 x i32] zeroinitializer }>, align 4
+ at 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                   <unknown>
+; DIS:      00000044 globalB:
+; DIS-NEXT:       44: 00 00 00 02                   <unknown>
+; DIS:      00000048 arr:
+; DIS-NEXT:       48: 00 00 00 03                   <unknown>
+; DIS-NEXT:                 ...
+; DIS:      00000070 p:
+; DIS-NEXT:       70: 00 00 00 58                   <unknown>
+; DIS:      00000074 foo:
+; DIS-NEXT:       74: 00 00 00 00                   <unknown>
+; DIS-NEXT:       78: 00 00 00 80                   <unknown>
+; DIS-NEXT:       7c: 00 00 00 00                   <unknown>
+; DIS:      00000080 globalA:
+; DIS-NEXT:       80: 00 00 00 40                   <unknown>
+; DIS:      00000084 globalB:
+; DIS-NEXT:       84: 00 00 00 44                   <unknown>


        


More information about the llvm-commits mailing list