[llvm] 8e84311 - [XCOFF][AIX] Enable tooling support for 64 bit symbol table parsing

via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 7 10:25:34 PDT 2021


Author: jasonliu
Date: 2021-06-07T17:24:13Z
New Revision: 8e84311a84b35ced5c18c3af8a802f7d2aa5c8a0

URL: https://github.com/llvm/llvm-project/commit/8e84311a84b35ced5c18c3af8a802f7d2aa5c8a0
DIFF: https://github.com/llvm/llvm-project/commit/8e84311a84b35ced5c18c3af8a802f7d2aa5c8a0.diff

LOG: [XCOFF][AIX] Enable tooling support for 64 bit symbol table parsing

Add in the ability of parsing symbol table for 64 bit object.

Reviewed By: jhenderson, DiggerLin

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

Added: 
    llvm/test/tools/llvm-objdump/XCOFF/Inputs/xcoff-section-headers64.o
    llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbol-description64.test
    llvm/test/tools/llvm-readobj/XCOFF/Inputs/file-aux-wrong64.o
    llvm/test/tools/llvm-readobj/XCOFF/Inputs/symbol64.o
    llvm/test/tools/llvm-readobj/XCOFF/file-aux-wrong64.test
    llvm/test/tools/llvm-readobj/XCOFF/symbols64.test

Modified: 
    llvm/include/llvm/BinaryFormat/XCOFF.h
    llvm/include/llvm/Object/XCOFFObjectFile.h
    llvm/lib/Object/XCOFFObjectFile.cpp
    llvm/tools/llvm-objdump/XCOFFDump.cpp
    llvm/tools/llvm-readobj/XCOFFDumper.cpp
    llvm/tools/obj2yaml/xcoff2yaml.cpp
    llvm/unittests/Object/XCOFFObjectFileTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/BinaryFormat/XCOFF.h b/llvm/include/llvm/BinaryFormat/XCOFF.h
index 3fcf302366abb..bfd0baf7cf4fa 100644
--- a/llvm/include/llvm/BinaryFormat/XCOFF.h
+++ b/llvm/include/llvm/BinaryFormat/XCOFF.h
@@ -296,6 +296,15 @@ enum CFileCpuId : uint8_t {
   TCPU_970 = 19   ///< PPC970 - PowerPC 64-bit architecture.
 };
 
+enum SymbolAuxType : uint8_t {
+  AUX_EXCEPT = 255, ///< Identifies an exception auxiliary entry.
+  AUX_FCN = 254,    ///< Identifies a function auxiliary entry.
+  AUX_SYM = 253,    ///< Identifies a symbol auxiliary entry.
+  AUX_FILE = 252,   ///< Identifies a file auxiliary entry.
+  AUX_CSECT = 251,  ///< Identifies a csect auxiliary entry.
+  AUX_SECT = 250    ///< Identifies a SECT auxiliary entry.
+};                  // 64-bit XCOFF file only.
+
 StringRef getMappingClassString(XCOFF::StorageMappingClass SMC);
 StringRef getRelocationTypeString(XCOFF::RelocationType Type);
 SmallString<32> parseParmsType(uint32_t Value, unsigned ParmsNum);

diff  --git a/llvm/include/llvm/Object/XCOFFObjectFile.h b/llvm/include/llvm/Object/XCOFFObjectFile.h
index dbc40c4ea8804..7bd02fa4a2d25 100644
--- a/llvm/include/llvm/Object/XCOFFObjectFile.h
+++ b/llvm/include/llvm/Object/XCOFFObjectFile.h
@@ -97,68 +97,113 @@ struct XCOFFSectionHeader64 : XCOFFSectionHeader<XCOFFSectionHeader64> {
   char Padding[4];
 };
 
-struct XCOFFSymbolEntry {
-  enum { NAME_IN_STR_TBL_MAGIC = 0x0 };
-  typedef struct {
-    support::big32_t Magic; // Zero indicates name in string table.
-    support::ubig32_t Offset;
-  } NameInStrTblType;
-
-  typedef struct {
-    uint8_t LanguageId;
-    uint8_t CpuTypeId;
-  } CFileLanguageIdAndTypeIdType;
-
-  union {
-    char SymbolName[XCOFF::NameSize];
-    NameInStrTblType NameInStrTbl;
-  };
-
-  support::ubig32_t Value; // Symbol value; storage class-dependent.
-  support::big16_t SectionNumber;
-
-  union {
-    support::ubig16_t SymbolType;
-    CFileLanguageIdAndTypeIdType CFileLanguageIdAndTypeId;
-  };
-
-  XCOFF::StorageClass StorageClass;
-  uint8_t NumberOfAuxEntries;
-};
-
 struct XCOFFStringTable {
   uint32_t Size;
   const char *Data;
 };
 
 struct XCOFFCsectAuxEnt32 {
-  static constexpr uint8_t SymbolTypeMask = 0x07;
-  static constexpr uint8_t SymbolAlignmentMask = 0xF8;
-  static constexpr size_t SymbolAlignmentBitOffset = 3;
-
-  support::ubig32_t
-      SectionOrLength; // If the symbol type is XTY_SD or XTY_CM, the csect
-                       // length.
-                       // If the symbol type is XTY_LD, the symbol table
-                       // index of the containing csect.
-                       // If the symbol type is XTY_ER, 0.
+  support::ubig32_t SectionOrLength;
   support::ubig32_t ParameterHashIndex;
   support::ubig16_t TypeChkSectNum;
   uint8_t SymbolAlignmentAndType;
   XCOFF::StorageMappingClass StorageMappingClass;
   support::ubig32_t StabInfoIndex;
   support::ubig16_t StabSectNum;
+};
+
+struct XCOFFCsectAuxEnt64 {
+  support::ubig32_t SectionOrLengthLowByte;
+  support::ubig32_t ParameterHashIndex;
+  support::ubig16_t TypeChkSectNum;
+  uint8_t SymbolAlignmentAndType;
+  XCOFF::StorageMappingClass StorageMappingClass;
+  support::ubig32_t SectionOrLengthHighByte;
+  uint8_t Pad;
+  XCOFF::SymbolAuxType AuxType;
+};
+
+class XCOFFCsectAuxRef {
+public:
+  static constexpr uint8_t SymbolTypeMask = 0x07;
+  static constexpr uint8_t SymbolAlignmentMask = 0xF8;
+  static constexpr size_t SymbolAlignmentBitOffset = 3;
+
+  XCOFFCsectAuxRef(const XCOFFCsectAuxEnt32 *Entry32) : Entry32(Entry32) {}
+  XCOFFCsectAuxRef(const XCOFFCsectAuxEnt64 *Entry64) : Entry64(Entry64) {}
+
+  // For getSectionOrLength(),
+  // If the symbol type is XTY_SD or XTY_CM, the csect length.
+  // If the symbol type is XTY_LD, the symbol table
+  // index of the containing csect.
+  // If the symbol type is XTY_ER, 0.
+  uint64_t getSectionOrLength() const {
+    return Entry32 ? getSectionOrLength32() : getSectionOrLength64();
+  }
+
+  uint32_t getSectionOrLength32() const {
+    assert(Entry32 && "32-bit interface called on 64-bit object file.");
+    return Entry32->SectionOrLength;
+  }
+
+  uint64_t getSectionOrLength64() const {
+    assert(Entry64 && "64-bit interface called on 32-bit object file.");
+    return (static_cast<uint64_t>(Entry64->SectionOrLengthHighByte) << 32) |
+           Entry64->SectionOrLengthLowByte;
+  }
+
+#define GETVALUE(X) Entry32 ? Entry32->X : Entry64->X
+
+  uint32_t getParameterHashIndex() const {
+    return GETVALUE(ParameterHashIndex);
+  }
+
+  uint16_t getTypeChkSectNum() const { return GETVALUE(TypeChkSectNum); }
+
+  XCOFF::StorageMappingClass getStorageMappingClass() const {
+    return GETVALUE(StorageMappingClass);
+  }
+
+  uintptr_t getEntryAddress() const {
+    return Entry32 ? reinterpret_cast<uintptr_t>(Entry32)
+                   : reinterpret_cast<uintptr_t>(Entry64);
+  }
 
   uint16_t getAlignmentLog2() const {
-    return (SymbolAlignmentAndType & SymbolAlignmentMask) >>
+    return (getSymbolAlignmentAndType() & SymbolAlignmentMask) >>
            SymbolAlignmentBitOffset;
   }
 
   uint8_t getSymbolType() const {
-    return SymbolAlignmentAndType & SymbolTypeMask;
+    return getSymbolAlignmentAndType() & SymbolTypeMask;
   }
 
   bool isLabel() const { return getSymbolType() == XCOFF::XTY_LD; }
+
+  uint32_t getStabInfoIndex32() const {
+    assert(Entry32 && "32-bit interface called on 64-bit object file.");
+    return Entry32->StabInfoIndex;
+  }
+
+  uint16_t getStabSectNum32() const {
+    assert(Entry32 && "32-bit interface called on 64-bit object file.");
+    return Entry32->StabSectNum;
+  }
+
+  XCOFF::SymbolAuxType getAuxType64() const {
+    assert(Entry64 && "64-bit interface called on 32-bit object file.");
+    return Entry64->AuxType;
+  }
+
+private:
+  uint8_t getSymbolAlignmentAndType() const {
+    return GETVALUE(SymbolAlignmentAndType);
+  }
+
+#undef GETVALUE
+
+  const XCOFFCsectAuxEnt32 *Entry32 = nullptr;
+  const XCOFFCsectAuxEnt64 *Entry64 = nullptr;
 };
 
 struct XCOFFFileAuxEnt {
@@ -173,7 +218,7 @@ struct XCOFFFileAuxEnt {
   };
   XCOFF::CFileStringType Type;
   uint8_t ReservedZeros[2];
-  uint8_t AuxType; // 64-bit XCOFF file only.
+  XCOFF::SymbolAuxType AuxType; // 64-bit XCOFF file only.
 };
 
 struct XCOFFSectAuxEntForStat {
@@ -181,7 +226,7 @@ struct XCOFFSectAuxEntForStat {
   support::ubig16_t NumberOfRelocEnt;
   support::ubig16_t NumberOfLineNum;
   uint8_t Pad[10];
-};
+}; // 32-bit XCOFF file only.
 
 struct XCOFFRelocation32 {
   // Masks for packing/unpacking the r_rsize field of relocations.
@@ -215,12 +260,14 @@ struct XCOFFRelocation32 {
   uint8_t getRelocatedLength() const;
 };
 
+class XCOFFSymbolRef;
+
 class XCOFFObjectFile : public ObjectFile {
 private:
   const void *FileHeader = nullptr;
   const void *SectionHeaderTable = nullptr;
 
-  const XCOFFSymbolEntry *SymbolTblPtr = nullptr;
+  const void *SymbolTblPtr = nullptr;
   XCOFFStringTable StringTable = {0, nullptr};
 
   const XCOFFFileHeader32 *fileHeader32() const;
@@ -242,9 +289,6 @@ class XCOFFObjectFile : public ObjectFile {
   // null-terminated.
   const char *getSectionNameInternal(DataRefImpl Sec) const;
 
-  // This function returns string table entry.
-  Expected<StringRef> getStringTableEntry(uint32_t Offset) const;
-
   static bool isReservedSectionNumber(int16_t SectionNumber);
 
   // Constructor and "create" factory function. The constructor is only a thin
@@ -323,15 +367,11 @@ class XCOFFObjectFile : public ObjectFile {
   // Below here is the non-inherited interface.
   bool is64Bit() const;
 
-  const XCOFFSymbolEntry *getPointerToSymbolTable() const {
-    assert(!is64Bit() && "Symbol table handling not supported yet.");
-    return SymbolTblPtr;
-  }
+  const void *getPointerToSymbolTable() const { return SymbolTblPtr; }
 
-  Expected<StringRef>
-  getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const;
+  Expected<StringRef> getSymbolSectionName(XCOFFSymbolRef Ref) const;
 
-  const XCOFFSymbolEntry *toSymbolEntry(DataRefImpl Ref) const;
+  XCOFFSymbolRef toSymbolRef(DataRefImpl Ref) const;
 
   // File header related interfaces.
   uint16_t getMagic() const;
@@ -351,7 +391,13 @@ class XCOFFObjectFile : public ObjectFile {
   uint32_t getLogicalNumberOfSymbolTableEntries32() const;
 
   uint32_t getNumberOfSymbolTableEntries64() const;
+
+  // Return getLogicalNumberOfSymbolTableEntries32 or
+  // getNumberOfSymbolTableEntries64 depending on the object mode.
+  uint32_t getNumberOfSymbolTableEntries() const;
+
   uint32_t getSymbolIndex(uintptr_t SymEntPtr) const;
+  uintptr_t getSymbolEntryAddressByIndex(uint32_t SymbolTableIndex) const;
   Expected<StringRef> getSymbolNameByIndex(uint32_t SymbolTableIndex) const;
 
   Expected<StringRef> getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const;
@@ -374,26 +420,120 @@ class XCOFFObjectFile : public ObjectFile {
   Expected<ArrayRef<XCOFFRelocation32>>
   relocations(const XCOFFSectionHeader32 &) const;
 
+  // This function returns string table entry.
+  Expected<StringRef> getStringTableEntry(uint32_t Offset) const;
+
+  const XCOFF::SymbolAuxType *getSymbolAuxType(uintptr_t AuxEntryAddress) const;
+
+  static uintptr_t getAdvancedSymbolEntryAddress(uintptr_t CurrentAddress,
+                                                 uint32_t Distance);
+
   static bool classof(const Binary *B) { return B->isXCOFF(); }
 }; // XCOFFObjectFile
 
-class XCOFFSymbolRef {
-  const DataRefImpl SymEntDataRef;
-  const XCOFFObjectFile *const OwningObjectPtr;
+typedef struct {
+  uint8_t LanguageId;
+  uint8_t CpuTypeId;
+} CFileLanguageIdAndTypeIdType;
+
+struct XCOFFSymbolEntry32 {
+  typedef struct {
+    support::big32_t Magic; // Zero indicates name in string table.
+    support::ubig32_t Offset;
+  } NameInStrTblType;
 
+  union {
+    char SymbolName[XCOFF::NameSize];
+    NameInStrTblType NameInStrTbl;
+  };
+
+  support::ubig32_t Value; // Symbol value; storage class-dependent.
+  support::big16_t SectionNumber;
+
+  union {
+    support::ubig16_t SymbolType;
+    CFileLanguageIdAndTypeIdType CFileLanguageIdAndTypeId;
+  };
+
+  XCOFF::StorageClass StorageClass;
+  uint8_t NumberOfAuxEntries;
+};
+
+struct XCOFFSymbolEntry64 {
+  support::ubig64_t Value; // Symbol value; storage class-dependent.
+  support::ubig32_t Offset;
+  support::big16_t SectionNumber;
+
+  union {
+    support::ubig16_t SymbolType;
+    CFileLanguageIdAndTypeIdType CFileLanguageIdAndTypeId;
+  };
+
+  XCOFF::StorageClass StorageClass;
+  uint8_t NumberOfAuxEntries;
+};
+
+class XCOFFSymbolRef {
 public:
+  enum { NAME_IN_STR_TBL_MAGIC = 0x0 };
+
   XCOFFSymbolRef(DataRefImpl SymEntDataRef,
                  const XCOFFObjectFile *OwningObjectPtr)
-      : SymEntDataRef(SymEntDataRef), OwningObjectPtr(OwningObjectPtr){};
+      : OwningObjectPtr(OwningObjectPtr) {
+    assert(OwningObjectPtr && "OwningObjectPtr cannot be nullptr!");
+    assert(SymEntDataRef.p != 0 &&
+           "Symbol table entry pointer cannot be nullptr!");
+
+    if (OwningObjectPtr->is64Bit())
+      Entry64 = reinterpret_cast<const XCOFFSymbolEntry64 *>(SymEntDataRef.p);
+    else
+      Entry32 = reinterpret_cast<const XCOFFSymbolEntry32 *>(SymEntDataRef.p);
+  }
 
-  XCOFF::StorageClass getStorageClass() const;
-  uint8_t getNumberOfAuxEntries() const;
-  const XCOFFCsectAuxEnt32 *getXCOFFCsectAuxEnt32() const;
-  uint16_t getType() const;
-  int16_t getSectionNumber() const;
+  uint64_t getValue() const { return Entry32 ? getValue32() : getValue64(); }
 
-  bool hasCsectAuxEnt() const;
+  uint32_t getValue32() const { return Entry32->Value; }
+
+  uint64_t getValue64() const { return Entry64->Value; }
+
+#define GETVALUE(X) Entry32 ? Entry32->X : Entry64->X
+
+  int16_t getSectionNumber() const { return GETVALUE(SectionNumber); }
+
+  uint16_t getSymbolType() const { return GETVALUE(SymbolType); }
+
+  uint8_t getLanguageIdForCFile() const {
+    assert(getStorageClass() == XCOFF::C_FILE &&
+           "This interface is for C_FILE only.");
+    return GETVALUE(CFileLanguageIdAndTypeId.LanguageId);
+  }
+
+  uint8_t getCPUTypeIddForCFile() const {
+    assert(getStorageClass() == XCOFF::C_FILE &&
+           "This interface is for C_FILE only.");
+    return GETVALUE(CFileLanguageIdAndTypeId.CpuTypeId);
+  }
+
+  XCOFF::StorageClass getStorageClass() const { return GETVALUE(StorageClass); }
+
+  uint8_t getNumberOfAuxEntries() const { return GETVALUE(NumberOfAuxEntries); }
+
+#undef GETVALUE
+
+  uintptr_t getEntryAddress() const {
+    return Entry32 ? reinterpret_cast<uintptr_t>(Entry32)
+                   : reinterpret_cast<uintptr_t>(Entry64);
+  }
+
+  Expected<StringRef> getName() const;
   bool isFunction() const;
+  bool isCsectSymbol() const;
+  Expected<XCOFFCsectAuxRef> getXCOFFCsectAuxRef() const;
+
+private:
+  const XCOFFObjectFile *OwningObjectPtr;
+  const XCOFFSymbolEntry32 *Entry32 = nullptr;
+  const XCOFFSymbolEntry64 *Entry64 = nullptr;
 };
 
 class TBVectorExt {

diff  --git a/llvm/lib/Object/XCOFFObjectFile.cpp b/llvm/lib/Object/XCOFFObjectFile.cpp
index 74b10faad68f1..86815539a033d 100644
--- a/llvm/lib/Object/XCOFFObjectFile.cpp
+++ b/llvm/lib/Object/XCOFFObjectFile.cpp
@@ -24,8 +24,8 @@ using namespace XCOFF;
 namespace object {
 
 static const uint8_t FunctionSym = 0x20;
-static const uint8_t SymTypeMask = 0x07;
 static const uint16_t NoRelMask = 0x0001;
+static const size_t SymbolAuxTypeOffset = 17;
 
 // Checks that [Ptr, Ptr + Size) bytes fall inside the memory buffer
 // 'M'. Returns a pointer to the underlying object on success.
@@ -83,6 +83,19 @@ uint8_t XCOFFRelocation32::getRelocatedLength() const {
   return (Info & XR_BIASED_LENGTH_MASK) + 1;
 }
 
+uintptr_t
+XCOFFObjectFile::getAdvancedSymbolEntryAddress(uintptr_t CurrentAddress,
+                                               uint32_t Distance) {
+  return getWithOffset(CurrentAddress, Distance * XCOFF::SymbolTableEntrySize);
+}
+
+const XCOFF::SymbolAuxType *
+XCOFFObjectFile::getSymbolAuxType(uintptr_t AuxEntryAddress) const {
+  assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
+  return viewAs<XCOFF::SymbolAuxType>(
+      getWithOffset(AuxEntryAddress, SymbolAuxTypeOffset));
+}
+
 void XCOFFObjectFile::checkSectionAddress(uintptr_t Addr,
                                           uintptr_t TableAddress) const {
   if (Addr < TableAddress)
@@ -115,14 +128,12 @@ XCOFFObjectFile::toSection64(DataRefImpl Ref) const {
   return viewAs<XCOFFSectionHeader64>(Ref.p);
 }
 
-const XCOFFSymbolEntry *XCOFFObjectFile::toSymbolEntry(DataRefImpl Ref) const {
-  assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
+XCOFFSymbolRef XCOFFObjectFile::toSymbolRef(DataRefImpl Ref) const {
   assert(Ref.p != 0 && "Symbol table pointer can not be nullptr!");
 #ifndef NDEBUG
   checkSymbolEntryPointer(Ref.p);
 #endif
-  auto SymEntPtr = viewAs<XCOFFSymbolEntry>(Ref.p);
-  return SymEntPtr;
+  return XCOFFSymbolRef(Ref, this);
 }
 
 const XCOFFFileHeader32 *XCOFFObjectFile::fileHeader32() const {
@@ -148,15 +159,15 @@ XCOFFObjectFile::sectionHeaderTable64() const {
 }
 
 void XCOFFObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
-  const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
-  SymEntPtr += SymEntPtr->NumberOfAuxEntries + 1;
+  uintptr_t NextSymbolAddr = getAdvancedSymbolEntryAddress(
+      Symb.p, toSymbolRef(Symb).getNumberOfAuxEntries() + 1);
 #ifndef NDEBUG
   // This function is used by basic_symbol_iterator, which allows to
   // point to the end-of-symbol-table address.
-  if (reinterpret_cast<uintptr_t>(SymEntPtr) != getEndOfSymbolTableAddress())
-    checkSymbolEntryPointer(reinterpret_cast<uintptr_t>(SymEntPtr));
+  if (NextSymbolAddr != getEndOfSymbolTableAddress())
+    checkSymbolEntryPointer(NextSymbolAddr);
 #endif
-  Symb.p = reinterpret_cast<uintptr_t>(SymEntPtr);
+  Symb.p = NextSymbolAddr;
 }
 
 Expected<StringRef>
@@ -178,34 +189,21 @@ XCOFFObjectFile::getStringTableEntry(uint32_t Offset) const {
 
 Expected<StringRef>
 XCOFFObjectFile::getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const {
-  if (CFileEntPtr->NameInStrTbl.Magic !=
-      XCOFFSymbolEntry::NAME_IN_STR_TBL_MAGIC)
+  if (CFileEntPtr->NameInStrTbl.Magic != XCOFFSymbolRef::NAME_IN_STR_TBL_MAGIC)
     return generateXCOFFFixedNameStringRef(CFileEntPtr->Name);
   return getStringTableEntry(CFileEntPtr->NameInStrTbl.Offset);
 }
 
 Expected<StringRef> XCOFFObjectFile::getSymbolName(DataRefImpl Symb) const {
-  const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
-
-  // A storage class value with the high-order bit on indicates that the name is
-  // a symbolic debugger stabstring.
-  if (SymEntPtr->StorageClass & 0x80)
-    return StringRef("Unimplemented Debug Name");
-
-  if (SymEntPtr->NameInStrTbl.Magic != XCOFFSymbolEntry::NAME_IN_STR_TBL_MAGIC)
-    return generateXCOFFFixedNameStringRef(SymEntPtr->SymbolName);
-
-  return getStringTableEntry(SymEntPtr->NameInStrTbl.Offset);
+  return toSymbolRef(Symb).getName();
 }
 
 Expected<uint64_t> XCOFFObjectFile::getSymbolAddress(DataRefImpl Symb) const {
-  assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
-  return toSymbolEntry(Symb)->Value;
+  return toSymbolRef(Symb).getValue();
 }
 
 uint64_t XCOFFObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
-  assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
-  return toSymbolEntry(Symb)->Value;
+  return toSymbolRef(Symb).getValue();
 }
 
 uint64_t XCOFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
@@ -222,8 +220,7 @@ XCOFFObjectFile::getSymbolType(DataRefImpl Symb) const {
 
 Expected<section_iterator>
 XCOFFObjectFile::getSymbolSection(DataRefImpl Symb) const {
-  const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
-  int16_t SectNum = SymEntPtr->SectionNumber;
+  const int16_t SectNum = toSymbolRef(Symb).getSectionNumber();
 
   if (isReservedSectionNumber(SectNum))
     return section_end();
@@ -376,7 +373,7 @@ symbol_iterator XCOFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
     return symbol_end();
 
   DataRefImpl SymDRI;
-  SymDRI.p = reinterpret_cast<uintptr_t>(getPointerToSymbolTable() + Index);
+  SymDRI.p = getSymbolEntryAddressByIndex(Index);
   return symbol_iterator(SymbolRef(SymDRI, this));
 }
 
@@ -402,19 +399,15 @@ Expected<uint32_t> XCOFFObjectFile::getSymbolFlags(DataRefImpl Symb) const {
 }
 
 basic_symbol_iterator XCOFFObjectFile::symbol_begin() const {
-  if (is64Bit())
-    report_fatal_error("64-bit support not implemented yet");
   DataRefImpl SymDRI;
   SymDRI.p = reinterpret_cast<uintptr_t>(SymbolTblPtr);
   return basic_symbol_iterator(SymbolRef(SymDRI, this));
 }
 
 basic_symbol_iterator XCOFFObjectFile::symbol_end() const {
-  if (is64Bit())
-    report_fatal_error("64-bit support not implemented yet");
   DataRefImpl SymDRI;
-  SymDRI.p = reinterpret_cast<uintptr_t>(
-      SymbolTblPtr + getLogicalNumberOfSymbolTableEntries32());
+  const uint32_t NumberOfSymbolTableEntries = getNumberOfSymbolTableEntries();
+  SymDRI.p = getSymbolEntryAddressByIndex(NumberOfSymbolTableEntries);
   return basic_symbol_iterator(SymbolRef(SymDRI, this));
 }
 
@@ -501,9 +494,8 @@ Expected<DataRefImpl> XCOFFObjectFile::getSectionByNum(int16_t Num) const {
 }
 
 Expected<StringRef>
-XCOFFObjectFile::getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const {
-  assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
-  int16_t SectionNum = SymEntPtr->SectionNumber;
+XCOFFObjectFile::getSymbolSectionName(XCOFFSymbolRef SymEntPtr) const {
+  const int16_t SectionNum = SymEntPtr.getSectionNumber();
 
   switch (SectionNum) {
   case XCOFF::N_DEBUG:
@@ -564,10 +556,13 @@ uint32_t XCOFFObjectFile::getNumberOfSymbolTableEntries64() const {
   return fileHeader64()->NumberOfSymTableEntries;
 }
 
+uint32_t XCOFFObjectFile::getNumberOfSymbolTableEntries() const {
+  return is64Bit() ? getNumberOfSymbolTableEntries64()
+                   : getLogicalNumberOfSymbolTableEntries32();
+}
+
 uintptr_t XCOFFObjectFile::getEndOfSymbolTableAddress() const {
-  uint32_t NumberOfSymTableEntries =
-      is64Bit() ? getNumberOfSymbolTableEntries64()
-                : getLogicalNumberOfSymbolTableEntries32();
+  const uint32_t NumberOfSymTableEntries = getNumberOfSymbolTableEntries();
   return getWithOffset(reinterpret_cast<uintptr_t>(SymbolTblPtr),
                        XCOFF::SymbolTableEntrySize * NumberOfSymTableEntries);
 }
@@ -593,16 +588,20 @@ uint32_t XCOFFObjectFile::getSymbolIndex(uintptr_t SymbolEntPtr) const {
          XCOFF::SymbolTableEntrySize;
 }
 
+uintptr_t XCOFFObjectFile::getSymbolEntryAddressByIndex(uint32_t Index) const {
+  return getAdvancedSymbolEntryAddress(
+      reinterpret_cast<uintptr_t>(getPointerToSymbolTable()), Index);
+}
+
 Expected<StringRef>
 XCOFFObjectFile::getSymbolNameByIndex(uint32_t Index) const {
-  if (is64Bit())
-    report_fatal_error("64-bit symbol table support not implemented yet.");
+  const uint32_t NumberOfSymTableEntries = getNumberOfSymbolTableEntries();
 
-  if (Index >= getLogicalNumberOfSymbolTableEntries32())
+  if (Index >= NumberOfSymTableEntries)
     return errorCodeToError(object_error::invalid_symbol_index);
 
   DataRefImpl SymDRI;
-  SymDRI.p = reinterpret_cast<uintptr_t>(getPointerToSymbolTable() + Index);
+  SymDRI.p = getSymbolEntryAddressByIndex(Index);
   return getSymbolName(SymDRI);
 }
 
@@ -745,20 +744,21 @@ XCOFFObjectFile::create(unsigned Type, MemoryBufferRef MBR) {
     Obj->SectionHeaderTable = SecHeadersOrErr.get();
   }
 
-  // 64-bit object supports only file header and section headers for now.
-  if (Obj->is64Bit())
-    return std::move(Obj);
+  const uint32_t NumberOfSymbolTableEntries =
+      Obj->getNumberOfSymbolTableEntries();
 
   // If there is no symbol table we are done parsing the memory buffer.
-  if (Obj->getLogicalNumberOfSymbolTableEntries32() == 0)
+  if (NumberOfSymbolTableEntries == 0)
     return std::move(Obj);
 
   // Parse symbol table.
-  CurOffset = Obj->fileHeader32()->SymbolTableOffset;
-  uint64_t SymbolTableSize = (uint64_t)(sizeof(XCOFFSymbolEntry)) *
-                             Obj->getLogicalNumberOfSymbolTableEntries32();
+  CurOffset = Obj->is64Bit() ? Obj->getSymbolTableOffset64()
+                             : Obj->getSymbolTableOffset32();
+  const uint64_t SymbolTableSize =
+      static_cast<uint64_t>(XCOFF::SymbolTableEntrySize) *
+      NumberOfSymbolTableEntries;
   auto SymTableOrErr =
-      getObject<XCOFFSymbolEntry>(Data, Base + CurOffset, SymbolTableSize);
+      getObject<void *>(Data, Base + CurOffset, SymbolTableSize);
   if (Error E = SymTableOrErr.takeError())
     return std::move(E);
   Obj->SymbolTblPtr = SymTableOrErr.get();
@@ -780,74 +780,103 @@ ObjectFile::createXCOFFObjectFile(MemoryBufferRef MemBufRef,
   return XCOFFObjectFile::create(FileType, MemBufRef);
 }
 
-XCOFF::StorageClass XCOFFSymbolRef::getStorageClass() const {
-  return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->StorageClass;
-}
+bool XCOFFSymbolRef::isFunction() const {
+  if (!isCsectSymbol())
+    return false;
 
-uint8_t XCOFFSymbolRef::getNumberOfAuxEntries() const {
-  return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->NumberOfAuxEntries;
-}
+  if (getSymbolType() & FunctionSym)
+    return true;
 
-// TODO: The function needs to return an error if there is no csect auxiliary
-// entry.
-const XCOFFCsectAuxEnt32 *XCOFFSymbolRef::getXCOFFCsectAuxEnt32() const {
-  assert(!OwningObjectPtr->is64Bit() &&
-         "32-bit interface called on 64-bit object file.");
-  assert(hasCsectAuxEnt() && "No Csect Auxiliary Entry is found.");
+  Expected<XCOFFCsectAuxRef> ExpCsectAuxEnt = getXCOFFCsectAuxRef();
+  if (!ExpCsectAuxEnt)
+    return false;
 
-  // In XCOFF32, the csect auxilliary entry is always the last auxiliary
-  // entry for the symbol.
-  uintptr_t AuxAddr = getWithOffset(
-      SymEntDataRef.p, XCOFF::SymbolTableEntrySize * getNumberOfAuxEntries());
+  const XCOFFCsectAuxRef CsectAuxRef = ExpCsectAuxEnt.get();
 
-#ifndef NDEBUG
-  OwningObjectPtr->checkSymbolEntryPointer(AuxAddr);
-#endif
+  // A function definition should be a label definition.
+  // FIXME: This is not necessarily the case when -ffunction-sections is
+  // enabled.
+  if (!CsectAuxRef.isLabel())
+    return false;
 
-  return reinterpret_cast<const XCOFFCsectAuxEnt32 *>(AuxAddr);
-}
+  if (CsectAuxRef.getStorageMappingClass() != XCOFF::XMC_PR)
+    return false;
 
-uint16_t XCOFFSymbolRef::getType() const {
-  return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->SymbolType;
-}
+  const int16_t SectNum = getSectionNumber();
+  Expected<DataRefImpl> SI = OwningObjectPtr->getSectionByNum(SectNum);
+  if (!SI) {
+    // If we could not get the section, then this symbol should not be
+    // a function. So consume the error and return `false` to move on.
+    consumeError(SI.takeError());
+    return false;
+  }
 
-int16_t XCOFFSymbolRef::getSectionNumber() const {
-  return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->SectionNumber;
+  return (OwningObjectPtr->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT);
 }
 
-// TODO: The function name needs to be changed to express the purpose of the
-// function.
-bool XCOFFSymbolRef::hasCsectAuxEnt() const {
+bool XCOFFSymbolRef::isCsectSymbol() const {
   XCOFF::StorageClass SC = getStorageClass();
   return (SC == XCOFF::C_EXT || SC == XCOFF::C_WEAKEXT ||
           SC == XCOFF::C_HIDEXT);
 }
 
-bool XCOFFSymbolRef::isFunction() const {
-  if (OwningObjectPtr->is64Bit())
-    report_fatal_error("64-bit support is unimplemented yet.");
+Expected<XCOFFCsectAuxRef> XCOFFSymbolRef::getXCOFFCsectAuxRef() const {
+  assert(isCsectSymbol() &&
+         "Calling csect symbol interface with a non-csect symbol.");
 
-  if (getType() & FunctionSym)
-    return true;
+  uint8_t NumberOfAuxEntries = getNumberOfAuxEntries();
 
-  if (!hasCsectAuxEnt())
-    return false;
+  Expected<StringRef> NameOrErr = getName();
+  if (auto Err = NameOrErr.takeError())
+    return std::move(Err);
 
-  const XCOFFCsectAuxEnt32 *CsectAuxEnt = getXCOFFCsectAuxEnt32();
+  if (!NumberOfAuxEntries) {
+    return createStringError(object_error::parse_failed,
+                             "csect symbol \"" + *NameOrErr +
+                                 "\" contains no auxiliary entry");
+  }
 
-  // A function definition should be a label definition.
-  if ((CsectAuxEnt->SymbolAlignmentAndType & SymTypeMask) != XCOFF::XTY_LD)
-    return false;
+  if (!OwningObjectPtr->is64Bit()) {
+    // In XCOFF32, the csect auxilliary entry is always the last auxiliary
+    // entry for the symbol.
+    uintptr_t AuxAddr = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
+        getEntryAddress(), NumberOfAuxEntries);
+    return XCOFFCsectAuxRef(viewAs<XCOFFCsectAuxEnt32>(AuxAddr));
+  }
 
-  if (CsectAuxEnt->StorageMappingClass != XCOFF::XMC_PR)
-    return false;
+  // XCOFF64 uses SymbolAuxType to identify the auxiliary entry type.
+  // We need to iterate through all the auxiliary entries to find it.
+  for (uint8_t Index = NumberOfAuxEntries; Index > 0; --Index) {
+    uintptr_t AuxAddr = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
+        getEntryAddress(), Index);
+    if (*OwningObjectPtr->getSymbolAuxType(AuxAddr) ==
+        XCOFF::SymbolAuxType::AUX_CSECT) {
+#ifndef NDEBUG
+      OwningObjectPtr->checkSymbolEntryPointer(AuxAddr);
+#endif
+      return XCOFFCsectAuxRef(viewAs<XCOFFCsectAuxEnt64>(AuxAddr));
+    }
+  }
 
-  int16_t SectNum = getSectionNumber();
-  Expected<DataRefImpl> SI = OwningObjectPtr->getSectionByNum(SectNum);
-  if (!SI)
-    return false;
+  return createStringError(
+      object_error::parse_failed,
+      "a csect auxiliary entry is not found for symbol \"" + *NameOrErr + "\"");
+}
 
-  return (OwningObjectPtr->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT);
+Expected<StringRef> XCOFFSymbolRef::getName() const {
+  // A storage class value with the high-order bit on indicates that the name is
+  // a symbolic debugger stabstring.
+  if (getStorageClass() & 0x80)
+    return StringRef("Unimplemented Debug Name");
+
+  if (Entry32) {
+    if (Entry32->NameInStrTbl.Magic != XCOFFSymbolRef::NAME_IN_STR_TBL_MAGIC)
+      return generateXCOFFFixedNameStringRef(Entry32->SymbolName);
+
+    return OwningObjectPtr->getStringTableEntry(Entry32->NameInStrTbl.Offset);
+  }
+
+  return OwningObjectPtr->getStringTableEntry(Entry64->Offset);
 }
 
 // Explictly instantiate template classes.

diff  --git a/llvm/test/tools/llvm-objdump/XCOFF/Inputs/xcoff-section-headers64.o b/llvm/test/tools/llvm-objdump/XCOFF/Inputs/xcoff-section-headers64.o
new file mode 100644
index 0000000000000..f65b962ca302d
Binary files /dev/null and b/llvm/test/tools/llvm-objdump/XCOFF/Inputs/xcoff-section-headers64.o 
diff er

diff  --git a/llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbol-description64.test b/llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbol-description64.test
new file mode 100644
index 0000000000000..fd3e2bb6b3119
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbol-description64.test
@@ -0,0 +1,96 @@
+# REQUIRES: powerpc-registered-target
+
+# RUN: llvm-objdump -D %p/Inputs/xcoff-section-headers64.o | \
+# RUN:   FileCheck --check-prefixes=COMMON,PLAIN %s
+
+# RUN: llvm-objdump -D --symbol-description %p/Inputs/xcoff-section-headers64.o | \
+# RUN:   FileCheck --check-prefixes=COMMON,DESC %s
+
+# RUN: not --crash llvm-objdump -D -r --symbol-description %p/Inputs/xcoff-section-headers64.o 2>&1 | \
+# RUN:   FileCheck --check-prefix=ERROR %s
+# ERROR: 64-bit support not implemented yet
+
+## xcoff-section-headers64.o Compiled with IBM XL C/C++ for AIX, V16.1.0
+## compiler command: xlc -q64 -qtls -o xcoff-section-headers64.o -c test.c
+
+## test.c:
+## int a;
+## int b = 12345;
+## __thread int c;
+## __thread double d = 3.14159;
+##
+## int func(void)  {
+##   return a;
+## }
+
+COMMON:       Inputs/xcoff-section-headers64.o:	file format aix5coff64-rs6000
+COMMON:       Disassembly of section .text:
+COMMON-EMPTY:
+PLAIN:        0000000000000000 <.func>:
+DESC:         0000000000000000 (idx: 6) .func:
+COMMON-NEXT:         0: e8 62 00 08   ld 3, 8(2)
+COMMON-NEXT:         4: e8 63 00 02   lwa 3, 0(3)
+COMMON-NEXT:         8: 4e 80 00 20   blr
+COMMON-NEXT:         c: 00 00 00 00   <unknown>
+COMMON-NEXT:        10: 00 00 20 40   <unknown>
+COMMON-NEXT:        14: 00 00 00 01   <unknown>
+COMMON-NEXT:        18: 00 00 00 0c   <unknown>
+COMMON-NEXT:        1c: 00 04 66 75   <unknown>
+COMMON-NEXT:        20: 6e 63 00 00   xoris 3, 19, 0
+COMMON-NEXT:                  ...
+COMMON-EMPTY:
+COMMON-NEXT:  Disassembly of section .data:
+COMMON-EMPTY:
+PLAIN:        0000000000000080 <func>:
+DESC:         0000000000000080 (idx: 12) func[TC]:
+COMMON-NEXT:        80: 00 00 00 00   <unknown>
+COMMON-NEXT:        84: 00 00 00 a8   <unknown>
+COMMON-EMPTY:
+PLAIN:        0000000000000088 <a>:
+DESC:         0000000000000088 (idx: 16) a[TC]:
+COMMON-NEXT:        88: 00 00 00 00   <unknown>
+COMMON-NEXT:        8c: 00 00 00 c8   <unknown>
+COMMON-EMPTY:
+PLAIN:        0000000000000090 <b>:
+DESC:         0000000000000090 (idx: 20) b[TC]:
+COMMON-NEXT:        90: 00 00 00 00   <unknown>
+COMMON-NEXT:        94: 00 00 00 c0   <unknown>
+COMMON-EMPTY:
+PLAIN:        0000000000000098 <c>:
+DESC:         0000000000000098 (idx: 24) c[TC]:
+COMMON-NEXT:        98: 00 00 00 00   <unknown>
+COMMON-NEXT:        9c: 00 00 00 08   <unknown>
+COMMON-EMPTY:
+PLAIN:        00000000000000a0 <d>:
+DESC:         00000000000000a0 (idx: 28) d[TC]:
+COMMON-NEXT:                  ...
+COMMON-EMPTY:
+PLAIN:        00000000000000a8 <func>:
+DESC:         00000000000000a8 (idx: 10) func[DS]:
+COMMON-NEXT:                  ...
+COMMON-NEXT:        b4: 00 00 00 80   <unknown>
+COMMON-NEXT:                  ...
+COMMON-EMPTY:
+PLAIN:        00000000000000c0 <b>:
+DESC:         00000000000000c0 (idx: 18) b[RW]:
+COMMON-NEXT:        c0: 00 00 30 39   <unknown>
+COMMON-NEXT:        c4: 00 00 00 00   <unknown>
+COMMON-EMPTY:
+COMMON-NEXT:  Disassembly of section .bss:
+COMMON-EMPTY:
+PLAIN:        00000000000000c8 <a>:
+DESC:         00000000000000c8 (idx: 14) a[RW]:
+COMMON-NEXT:  ...
+COMMON-EMPTY:
+COMMON-NEXT:  Disassembly of section .tdata:
+COMMON-EMPTY:
+PLAIN:        0000000000000000 <d>:
+DESC:         0000000000000000 (idx: 26) d[TL]:
+COMMON-NEXT:         0: 40 09 21 f9   bdnzfl  9, 0x21f8
+COMMON-NEXT:         4: f0 1b 86 6e   <unknown>
+COMMON-EMPTY:
+COMMON-NEXT:  Disassembly of section .tbss:
+COMMON-EMPTY:
+PLAIN:        0000000000000008 <c>:
+DESC:         0000000000000008 (idx: 22) c[UL]:
+COMMON-NEXT:  ...

diff  --git a/llvm/test/tools/llvm-readobj/XCOFF/Inputs/file-aux-wrong64.o b/llvm/test/tools/llvm-readobj/XCOFF/Inputs/file-aux-wrong64.o
new file mode 100644
index 0000000000000..dc5052f0b83d0
Binary files /dev/null and b/llvm/test/tools/llvm-readobj/XCOFF/Inputs/file-aux-wrong64.o 
diff er

diff  --git a/llvm/test/tools/llvm-readobj/XCOFF/Inputs/symbol64.o b/llvm/test/tools/llvm-readobj/XCOFF/Inputs/symbol64.o
new file mode 100644
index 0000000000000..60d4cd9e80934
Binary files /dev/null and b/llvm/test/tools/llvm-readobj/XCOFF/Inputs/symbol64.o 
diff er

diff  --git a/llvm/test/tools/llvm-readobj/XCOFF/file-aux-wrong64.test b/llvm/test/tools/llvm-readobj/XCOFF/file-aux-wrong64.test
new file mode 100644
index 0000000000000..f17e27a071d5a
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/XCOFF/file-aux-wrong64.test
@@ -0,0 +1,19 @@
+## This file tests the raw data output ability when a file auxiliary entry does
+## not have the matching auxiliary type.
+
+# RUN: llvm-readobj --symbols %p/Inputs/file-aux-wrong64.o | FileCheck %s
+
+#      CHECK: Symbols [
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Index: 0
+# CHECK-NEXT:     Name: .file
+# CHECK-NEXT:     Value (SymbolTableIndex): 0x0
+# CHECK-NEXT:     Section: N_DEBUG
+# CHECK-NEXT:     Source Language ID: 0xC
+# CHECK-NEXT:     CPU Version ID: TCPU_PPC64 (0x2)
+# CHECK-NEXT:     StorageClass: C_FILE (0x67)
+# CHECK-NEXT:     NumberOfAuxEntries: 1
+# CHECK-NEXT:     !Unexpected raw auxiliary entry data:
+# CHECK-NEXT:     612e7300 00000000 00000000 00000000 00fb
+# CHECK-NEXT:   }
+# CHECK-NEXT: ]

diff  --git a/llvm/test/tools/llvm-readobj/XCOFF/symbols64.test b/llvm/test/tools/llvm-readobj/XCOFF/symbols64.test
new file mode 100644
index 0000000000000..f3cfcda6a49e4
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/XCOFF/symbols64.test
@@ -0,0 +1,387 @@
+## This file tests the ability of llvm-readobj to display the symbol table for a
+## 64-bit XCOFF object file.
+## The object file used is generated by the following source file
+## and command on AIX:
+##
+## > cat test8.c
+##
+## extern int i;
+## extern int TestforXcoff;
+## extern int fun(int i);
+## static int static_i;
+## char* p="abcd";
+## int fun1(int j) {
+##   static_i++;
+##   j++;
+##   j=j+*p;
+##   return j;
+## }
+##
+## int main() {
+##   i++;
+##   fun(i);
+##   return fun1(i);
+## }
+##
+## > xlc -q64 -c test8.c -o symbol64.o
+
+# RUN: llvm-readobj --symbols %p/Inputs/symbol64.o | \
+# RUN:   FileCheck --check-prefix=SYMBOL64 %s
+
+# SYMBOL64:       File: {{.*}}symbol64.o
+# SYMBOL64-NEXT:  Format: aix5coff64-rs6000
+# SYMBOL64-NEXT:  Arch: powerpc64
+# SYMBOL64-NEXT:  AddressSize: 64bit
+# SYMBOL64-NEXT:  Symbols [
+# SYMBOL64-NEXT:    Symbol {
+# SYMBOL64-NEXT:      Index: 0
+# SYMBOL64-NEXT:      Name: .file
+# SYMBOL64-NEXT:      Value (SymbolTableIndex): 0x0
+# SYMBOL64-NEXT:      Section: N_DEBUG
+# SYMBOL64-NEXT:      Source Language ID: TB_C (0x0)
+# SYMBOL64-NEXT:      CPU Version ID: TCPU_PPC64 (0x2)
+# SYMBOL64-NEXT:      StorageClass: C_FILE (0x67)
+# SYMBOL64-NEXT:      NumberOfAuxEntries: 3
+# SYMBOL64-NEXT:      File Auxiliary Entry {
+# SYMBOL64-NEXT:        Index: 1
+# SYMBOL64-NEXT:        Name: test64.c
+# SYMBOL64-NEXT:        Type: XFT_FN (0x0)
+# SYMBOL64-NEXT:        Auxiliary Type: AUX_FILE (0xFC)
+# SYMBOL64-NEXT:      }
+# SYMBOL64-NEXT:      File Auxiliary Entry {
+# SYMBOL64-NEXT:        Index: 2
+# SYMBOL64-NEXT:        Name: Mon Aug 10 16:07:48 2020
+# SYMBOL64-NEXT:        Type: XFT_CT (0x1)
+# SYMBOL64-NEXT:        Auxiliary Type: AUX_FILE (0xFC)
+# SYMBOL64-NEXT:      }
+# SYMBOL64-NEXT:      File Auxiliary Entry {
+# SYMBOL64-NEXT:        Index: 3
+# SYMBOL64-NEXT:        Name: IBM XL C for AIX, Version 16.1.0.6
+# SYMBOL64-NEXT:        Type: XFT_CV (0x2)
+# SYMBOL64-NEXT:        Auxiliary Type: AUX_FILE (0xFC)
+# SYMBOL64-NEXT:      }
+# SYMBOL64-NEXT:    }
+# SYMBOL64-NEXT:    Symbol {
+# SYMBOL64-NEXT:      Index: 4
+# SYMBOL64-NEXT:      Name:
+# SYMBOL64-NEXT:      Value (RelocatableAddress): 0x0
+# SYMBOL64-NEXT:      Section: .text
+# SYMBOL64-NEXT:      Type: 0x0
+# SYMBOL64-NEXT:      StorageClass: C_HIDEXT (0x6B)
+# SYMBOL64-NEXT:      NumberOfAuxEntries: 1
+# SYMBOL64-NEXT:      CSECT Auxiliary Entry {
+# SYMBOL64-NEXT:        Index: 5
+# SYMBOL64-NEXT:        SectionLen: 256
+# SYMBOL64-NEXT:        ParameterHashIndex: 0x0
+# SYMBOL64-NEXT:        TypeChkSectNum: 0x0
+# SYMBOL64-NEXT:        SymbolAlignmentLog2: 7
+# SYMBOL64-NEXT:        SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT:        StorageMappingClass: XMC_PR (0x0)
+# SYMBOL64-NEXT:        Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT:      }
+# SYMBOL64-NEXT:    }
+# SYMBOL64-NEXT:    Symbol {
+# SYMBOL64-NEXT:      Index: 6
+# SYMBOL64-NEXT:      Name: .fun1
+# SYMBOL64-NEXT:      Value (RelocatableAddress): 0x0
+# SYMBOL64-NEXT:      Section: .text
+# SYMBOL64-NEXT:      Type: 0x20
+# SYMBOL64-NEXT:      StorageClass: C_EXT (0x2)
+# SYMBOL64-NEXT:      NumberOfAuxEntries: 1
+# SYMBOL64-NEXT:      CSECT Auxiliary Entry {
+# SYMBOL64-NEXT:        Index: 7
+# SYMBOL64-NEXT:        ContainingCsectSymbolIndex: 4
+# SYMBOL64-NEXT:        ParameterHashIndex: 0x0
+# SYMBOL64-NEXT:        TypeChkSectNum: 0x0
+# SYMBOL64-NEXT:        SymbolAlignmentLog2: 0
+# SYMBOL64-NEXT:        SymbolType: XTY_LD (0x2)
+# SYMBOL64-NEXT:        StorageMappingClass: XMC_PR (0x0)
+# SYMBOL64-NEXT:        Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT:      }
+# SYMBOL64-NEXT:    }
+# SYMBOL64-NEXT:    Symbol {
+# SYMBOL64-NEXT:      Index: 8
+# SYMBOL64-NEXT:      Name: .main
+# SYMBOL64-NEXT:      Value (RelocatableAddress): 0x80
+# SYMBOL64-NEXT:      Section: .text
+# SYMBOL64-NEXT:      Type: 0x20
+# SYMBOL64-NEXT:      StorageClass: C_EXT (0x2)
+# SYMBOL64-NEXT:      NumberOfAuxEntries: 1
+# SYMBOL64-NEXT:      CSECT Auxiliary Entry {
+# SYMBOL64-NEXT:        Index: 9
+# SYMBOL64-NEXT:        ContainingCsectSymbolIndex: 4
+# SYMBOL64-NEXT:        ParameterHashIndex: 0x0
+# SYMBOL64-NEXT:        TypeChkSectNum: 0x0
+# SYMBOL64-NEXT:        SymbolAlignmentLog2: 0
+# SYMBOL64-NEXT:        SymbolType: XTY_LD (0x2)
+# SYMBOL64-NEXT:        StorageMappingClass: XMC_PR (0x0)
+# SYMBOL64-NEXT:        Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT:      }
+# SYMBOL64-NEXT:    }
+# SYMBOL64-NEXT:    Symbol {
+# SYMBOL64-NEXT:      Index: 10
+# SYMBOL64-NEXT:      Name: TOC
+# SYMBOL64-NEXT:      Value (RelocatableAddress): 0x100
+# SYMBOL64-NEXT:      Section: .data
+# SYMBOL64-NEXT:      Type: 0x0
+# SYMBOL64-NEXT:      StorageClass: C_HIDEXT (0x6B)
+# SYMBOL64-NEXT:      NumberOfAuxEntries: 1
+# SYMBOL64-NEXT:      CSECT Auxiliary Entry {
+# SYMBOL64-NEXT:        Index: 11
+# SYMBOL64-NEXT:        SectionLen: 0
+# SYMBOL64-NEXT:        ParameterHashIndex: 0x0
+# SYMBOL64-NEXT:        TypeChkSectNum: 0x0
+# SYMBOL64-NEXT:        SymbolAlignmentLog2: 2
+# SYMBOL64-NEXT:        SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT:        StorageMappingClass: XMC_TC0 (0xF)
+# SYMBOL64-NEXT:        Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT:      }
+# SYMBOL64-NEXT:    }
+# SYMBOL64-NEXT:    Symbol {
+# SYMBOL64-NEXT:      Index: 12
+# SYMBOL64-NEXT:      Name:
+# SYMBOL64-NEXT:      Value (RelocatableAddress): 0x128
+# SYMBOL64-NEXT:      Section: .data
+# SYMBOL64-NEXT:      Type: 0x0
+# SYMBOL64-NEXT:      StorageClass: C_HIDEXT (0x6B)
+# SYMBOL64-NEXT:      NumberOfAuxEntries: 1
+# SYMBOL64-NEXT:      CSECT Auxiliary Entry {
+# SYMBOL64-NEXT:        Index: 13
+# SYMBOL64-NEXT:        SectionLen: 8
+# SYMBOL64-NEXT:        ParameterHashIndex: 0x0
+# SYMBOL64-NEXT:        TypeChkSectNum: 0x0
+# SYMBOL64-NEXT:        SymbolAlignmentLog2: 3
+# SYMBOL64-NEXT:        SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT:        StorageMappingClass: XMC_TC (0x3)
+# SYMBOL64-NEXT:        Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT:      }
+# SYMBOL64-NEXT:    }
+# SYMBOL64-NEXT:    Symbol {
+# SYMBOL64-NEXT:      Index: 14
+# SYMBOL64-NEXT:      Name:
+# SYMBOL64-NEXT:      Value (RelocatableAddress): 0x168
+# SYMBOL64-NEXT:      Section: .data
+# SYMBOL64-NEXT:      Type: 0x0
+# SYMBOL64-NEXT:      StorageClass: C_HIDEXT (0x6B)
+# SYMBOL64-NEXT:      NumberOfAuxEntries: 1
+# SYMBOL64-NEXT:      CSECT Auxiliary Entry {
+# SYMBOL64-NEXT:        Index: 15
+# SYMBOL64-NEXT:        SectionLen: 5
+# SYMBOL64-NEXT:        ParameterHashIndex: 0x0
+# SYMBOL64-NEXT:        TypeChkSectNum: 0x0
+# SYMBOL64-NEXT:        SymbolAlignmentLog2: 3
+# SYMBOL64-NEXT:        SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT:        StorageMappingClass: XMC_RO (0x1)
+# SYMBOL64-NEXT:        Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT:      }
+# SYMBOL64-NEXT:    }
+# SYMBOL64-NEXT:    Symbol {
+# SYMBOL64-NEXT:      Index: 16
+# SYMBOL64-NEXT:      Name: _$STATIC_BSS
+# SYMBOL64-NEXT:      Value (RelocatableAddress): 0x170
+# SYMBOL64-NEXT:      Section: .bss
+# SYMBOL64-NEXT:      Type: 0x0
+# SYMBOL64-NEXT:      StorageClass: C_HIDEXT (0x6B)
+# SYMBOL64-NEXT:      NumberOfAuxEntries: 1
+# SYMBOL64-NEXT:      CSECT Auxiliary Entry {
+# SYMBOL64-NEXT:        Index: 17
+# SYMBOL64-NEXT:        SectionLen: 4
+# SYMBOL64-NEXT:        ParameterHashIndex: 0x0
+# SYMBOL64-NEXT:        TypeChkSectNum: 0x0
+# SYMBOL64-NEXT:        SymbolAlignmentLog2: 2
+# SYMBOL64-NEXT:        SymbolType: XTY_CM (0x3)
+# SYMBOL64-NEXT:        StorageMappingClass: XMC_RW (0x5)
+# SYMBOL64-NEXT:        Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT:      }
+# SYMBOL64-NEXT:    }
+# SYMBOL64-NEXT:    Symbol {
+# SYMBOL64-NEXT:      Index: 18
+# SYMBOL64-NEXT:      Name: _$STATIC_BSS
+# SYMBOL64-NEXT:      Value (RelocatableAddress): 0x108
+# SYMBOL64-NEXT:      Section: .data
+# SYMBOL64-NEXT:      Type: 0x0
+# SYMBOL64-NEXT:      StorageClass: C_HIDEXT (0x6B)
+# SYMBOL64-NEXT:      NumberOfAuxEntries: 1
+# SYMBOL64-NEXT:      CSECT Auxiliary Entry {
+# SYMBOL64-NEXT:        Index: 19
+# SYMBOL64-NEXT:        SectionLen: 8
+# SYMBOL64-NEXT:        ParameterHashIndex: 0x0
+# SYMBOL64-NEXT:        TypeChkSectNum: 0x0
+# SYMBOL64-NEXT:        SymbolAlignmentLog2: 3
+# SYMBOL64-NEXT:        SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT:        StorageMappingClass: XMC_TC (0x3)
+# SYMBOL64-NEXT:        Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT:      }
+# SYMBOL64-NEXT:    }
+# SYMBOL64-NEXT:    Symbol {
+# SYMBOL64-NEXT:      Index: 20
+# SYMBOL64-NEXT:      Name: fun1
+# SYMBOL64-NEXT:      Value (RelocatableAddress): 0x130
+# SYMBOL64-NEXT:      Section: .data
+# SYMBOL64-NEXT:      Type: 0x0
+# SYMBOL64-NEXT:      StorageClass: C_EXT (0x2)
+# SYMBOL64-NEXT:      NumberOfAuxEntries: 1
+# SYMBOL64-NEXT:      CSECT Auxiliary Entry {
+# SYMBOL64-NEXT:        Index: 21
+# SYMBOL64-NEXT:        SectionLen: 24
+# SYMBOL64-NEXT:        ParameterHashIndex: 0x0
+# SYMBOL64-NEXT:        TypeChkSectNum: 0x0
+# SYMBOL64-NEXT:        SymbolAlignmentLog2: 3
+# SYMBOL64-NEXT:        SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT:        StorageMappingClass: XMC_DS (0xA)
+# SYMBOL64-NEXT:        Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT:      }
+# SYMBOL64-NEXT:    }
+# SYMBOL64-NEXT:    Symbol {
+# SYMBOL64-NEXT:      Index: 22
+# SYMBOL64-NEXT:      Name: fun1
+# SYMBOL64-NEXT:      Value (RelocatableAddress): 0x100
+# SYMBOL64-NEXT:      Section: .data
+# SYMBOL64-NEXT:      Type: 0x0
+# SYMBOL64-NEXT:      StorageClass: C_HIDEXT (0x6B)
+# SYMBOL64-NEXT:      NumberOfAuxEntries: 1
+# SYMBOL64-NEXT:      CSECT Auxiliary Entry {
+# SYMBOL64-NEXT:        Index: 23
+# SYMBOL64-NEXT:        SectionLen: 8
+# SYMBOL64-NEXT:        ParameterHashIndex: 0x0
+# SYMBOL64-NEXT:        TypeChkSectNum: 0x0
+# SYMBOL64-NEXT:        SymbolAlignmentLog2: 3
+# SYMBOL64-NEXT:        SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT:        StorageMappingClass: XMC_TC (0x3)
+# SYMBOL64-NEXT:        Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT:      }
+# SYMBOL64-NEXT:    }
+# SYMBOL64-NEXT:    Symbol {
+# SYMBOL64-NEXT:      Index: 24
+# SYMBOL64-NEXT:      Name: p
+# SYMBOL64-NEXT:      Value (RelocatableAddress): 0x160
+# SYMBOL64-NEXT:      Section: .data
+# SYMBOL64-NEXT:      Type: 0x0
+# SYMBOL64-NEXT:      StorageClass: C_EXT (0x2)
+# SYMBOL64-NEXT:      NumberOfAuxEntries: 1
+# SYMBOL64-NEXT:      CSECT Auxiliary Entry {
+# SYMBOL64-NEXT:        Index: 25
+# SYMBOL64-NEXT:        SectionLen: 8
+# SYMBOL64-NEXT:        ParameterHashIndex: 0x0
+# SYMBOL64-NEXT:        TypeChkSectNum: 0x0
+# SYMBOL64-NEXT:        SymbolAlignmentLog2: 3
+# SYMBOL64-NEXT:        SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT:        StorageMappingClass: XMC_RW (0x5)
+# SYMBOL64-NEXT:        Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT:      }
+# SYMBOL64-NEXT:    }
+# SYMBOL64-NEXT:    Symbol {
+# SYMBOL64-NEXT:      Index: 26
+# SYMBOL64-NEXT:      Name: p
+# SYMBOL64-NEXT:      Value (RelocatableAddress): 0x110
+# SYMBOL64-NEXT:      Section: .data
+# SYMBOL64-NEXT:      Type: 0x0
+# SYMBOL64-NEXT:      StorageClass: C_HIDEXT (0x6B)
+# SYMBOL64-NEXT:      NumberOfAuxEntries: 1
+# SYMBOL64-NEXT:      CSECT Auxiliary Entry {
+# SYMBOL64-NEXT:        Index: 27
+# SYMBOL64-NEXT:        SectionLen: 8
+# SYMBOL64-NEXT:        ParameterHashIndex: 0x0
+# SYMBOL64-NEXT:        TypeChkSectNum: 0x0
+# SYMBOL64-NEXT:        SymbolAlignmentLog2: 3
+# SYMBOL64-NEXT:        SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT:        StorageMappingClass: XMC_TC (0x3)
+# SYMBOL64-NEXT:        Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT:      }
+# SYMBOL64-NEXT:    }
+# SYMBOL64-NEXT:    Symbol {
+# SYMBOL64-NEXT:      Index: 28
+# SYMBOL64-NEXT:      Name: main
+# SYMBOL64-NEXT:      Value (RelocatableAddress): 0x148
+# SYMBOL64-NEXT:      Section: .data
+# SYMBOL64-NEXT:      Type: 0x0
+# SYMBOL64-NEXT:      StorageClass: C_EXT (0x2)
+# SYMBOL64-NEXT:      NumberOfAuxEntries: 1
+# SYMBOL64-NEXT:      CSECT Auxiliary Entry {
+# SYMBOL64-NEXT:        Index: 29
+# SYMBOL64-NEXT:        SectionLen: 24
+# SYMBOL64-NEXT:        ParameterHashIndex: 0x0
+# SYMBOL64-NEXT:        TypeChkSectNum: 0x0
+# SYMBOL64-NEXT:        SymbolAlignmentLog2: 3
+# SYMBOL64-NEXT:        SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT:        StorageMappingClass: XMC_DS (0xA)
+# SYMBOL64-NEXT:        Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT:      }
+# SYMBOL64-NEXT:    }
+# SYMBOL64-NEXT:    Symbol {
+# SYMBOL64-NEXT:      Index: 30
+# SYMBOL64-NEXT:      Name: main
+# SYMBOL64-NEXT:      Value (RelocatableAddress): 0x118
+# SYMBOL64-NEXT:      Section: .data
+# SYMBOL64-NEXT:      Type: 0x0
+# SYMBOL64-NEXT:      StorageClass: C_HIDEXT (0x6B)
+# SYMBOL64-NEXT:      NumberOfAuxEntries: 1
+# SYMBOL64-NEXT:      CSECT Auxiliary Entry {
+# SYMBOL64-NEXT:        Index: 31
+# SYMBOL64-NEXT:        SectionLen: 8
+# SYMBOL64-NEXT:        ParameterHashIndex: 0x0
+# SYMBOL64-NEXT:        TypeChkSectNum: 0x0
+# SYMBOL64-NEXT:        SymbolAlignmentLog2: 3
+# SYMBOL64-NEXT:        SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT:        StorageMappingClass: XMC_TC (0x3)
+# SYMBOL64-NEXT:        Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT:      }
+# SYMBOL64-NEXT:    }
+# SYMBOL64-NEXT:    Symbol {
+# SYMBOL64-NEXT:      Index: 32
+# SYMBOL64-NEXT:      Name: i
+# SYMBOL64-NEXT:      Value (RelocatableAddress): 0x0
+# SYMBOL64-NEXT:      Section: N_UNDEF
+# SYMBOL64-NEXT:      Type: 0x0
+# SYMBOL64-NEXT:      StorageClass: C_EXT (0x2)
+# SYMBOL64-NEXT:      NumberOfAuxEntries: 1
+# SYMBOL64-NEXT:      CSECT Auxiliary Entry {
+# SYMBOL64-NEXT:        Index: 33
+# SYMBOL64-NEXT:        SectionLen: 0
+# SYMBOL64-NEXT:        ParameterHashIndex: 0x0
+# SYMBOL64-NEXT:        TypeChkSectNum: 0x0
+# SYMBOL64-NEXT:        SymbolAlignmentLog2: 0
+# SYMBOL64-NEXT:        SymbolType: XTY_ER (0x0)
+# SYMBOL64-NEXT:        StorageMappingClass: XMC_UA (0x4)
+# SYMBOL64-NEXT:        Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT:      }
+# SYMBOL64-NEXT:    }
+# SYMBOL64-NEXT:    Symbol {
+# SYMBOL64-NEXT:      Index: 34
+# SYMBOL64-NEXT:      Name: i
+# SYMBOL64-NEXT:      Value (RelocatableAddress): 0x120
+# SYMBOL64-NEXT:      Section: .data
+# SYMBOL64-NEXT:      Type: 0x0
+# SYMBOL64-NEXT:      StorageClass: C_HIDEXT (0x6B)
+# SYMBOL64-NEXT:      NumberOfAuxEntries: 1
+# SYMBOL64-NEXT:      CSECT Auxiliary Entry {
+# SYMBOL64-NEXT:        Index: 35
+# SYMBOL64-NEXT:        SectionLen: 8
+# SYMBOL64-NEXT:        ParameterHashIndex: 0x0
+# SYMBOL64-NEXT:        TypeChkSectNum: 0x0
+# SYMBOL64-NEXT:        SymbolAlignmentLog2: 3
+# SYMBOL64-NEXT:        SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT:        StorageMappingClass: XMC_TC (0x3)
+# SYMBOL64-NEXT:        Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT:      }
+# SYMBOL64-NEXT:    }
+# SYMBOL64-NEXT:    Symbol {
+# SYMBOL64-NEXT:      Index: 36
+# SYMBOL64-NEXT:      Name: .fun
+# SYMBOL64-NEXT:      Value (RelocatableAddress): 0x0
+# SYMBOL64-NEXT:      Section: N_UNDEF
+# SYMBOL64-NEXT:      Type: 0x0
+# SYMBOL64-NEXT:      StorageClass: C_EXT (0x2)
+# SYMBOL64-NEXT:      NumberOfAuxEntries: 1
+# SYMBOL64-NEXT:      CSECT Auxiliary Entry {
+# SYMBOL64-NEXT:        Index: 37
+# SYMBOL64-NEXT:        SectionLen: 0
+# SYMBOL64-NEXT:        ParameterHashIndex: 0x0
+# SYMBOL64-NEXT:        TypeChkSectNum: 0x0
+# SYMBOL64-NEXT:        SymbolAlignmentLog2: 0
+# SYMBOL64-NEXT:        SymbolType: XTY_ER (0x0)
+# SYMBOL64-NEXT:        StorageMappingClass: XMC_PR (0x0)
+# SYMBOL64-NEXT:        Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT:      }
+# SYMBOL64-NEXT:    }
+# SYMBOL64-NEXT:  ]

diff  --git a/llvm/tools/llvm-objdump/XCOFFDump.cpp b/llvm/tools/llvm-objdump/XCOFFDump.cpp
index df37abbd38813..c4cc5fe7e21c7 100644
--- a/llvm/tools/llvm-objdump/XCOFFDump.cpp
+++ b/llvm/tools/llvm-objdump/XCOFFDump.cpp
@@ -46,22 +46,30 @@ Error objdump::getXCOFFRelocationValueString(const XCOFFObjectFile *Obj,
 Optional<XCOFF::StorageMappingClass>
 objdump::getXCOFFSymbolCsectSMC(const XCOFFObjectFile *Obj,
                                 const SymbolRef &Sym) {
-  XCOFFSymbolRef SymRef(Sym.getRawDataRefImpl(), Obj);
+  const XCOFFSymbolRef SymRef = Obj->toSymbolRef(Sym.getRawDataRefImpl());
 
-  if (SymRef.hasCsectAuxEnt())
-    return SymRef.getXCOFFCsectAuxEnt32()->StorageMappingClass;
+  if (!SymRef.isCsectSymbol())
+    return None;
 
-  return None;
+  auto CsectAuxEntOrErr = SymRef.getXCOFFCsectAuxRef();
+  if (!CsectAuxEntOrErr)
+    return None;
+
+  return CsectAuxEntOrErr.get().getStorageMappingClass();
 }
 
 bool objdump::isLabel(const XCOFFObjectFile *Obj, const SymbolRef &Sym) {
 
-  XCOFFSymbolRef SymRef(Sym.getRawDataRefImpl(), Obj);
+  const XCOFFSymbolRef SymRef = Obj->toSymbolRef(Sym.getRawDataRefImpl());
+
+  if (!SymRef.isCsectSymbol())
+    return false;
 
-  if (SymRef.hasCsectAuxEnt())
-    return SymRef.getXCOFFCsectAuxEnt32()->isLabel();
+  auto CsectAuxEntOrErr = SymRef.getXCOFFCsectAuxRef();
+  if (!CsectAuxEntOrErr)
+    return false;
 
-  return false;
+  return CsectAuxEntOrErr.get().isLabel();
 }
 
 std::string objdump::getXCOFFSymbolDescription(const SymbolInfoTy &SymbolInfo,

diff  --git a/llvm/tools/llvm-readobj/XCOFFDumper.cpp b/llvm/tools/llvm-readobj/XCOFFDumper.cpp
index 5c4bfbd309562..bff2fecfb5d57 100644
--- a/llvm/tools/llvm-readobj/XCOFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/XCOFFDumper.cpp
@@ -40,7 +40,7 @@ class XCOFFDumper : public ObjDumper {
   template <typename T> void printGenericSectionHeader(T &Sec) const;
   template <typename T> void printOverflowSectionHeader(T &Sec) const;
   void printFileAuxEnt(const XCOFFFileAuxEnt *AuxEntPtr);
-  void printCsectAuxEnt32(const XCOFFCsectAuxEnt32 *AuxEntPtr);
+  void printCsectAuxEnt(XCOFFCsectAuxRef AuxEntRef);
   void printSectAuxEntForStat(const XCOFFSectAuxEntForStat *AuxEntPtr);
   void printSymbol(const SymbolRef &);
   void printRelocations(ArrayRef<XCOFFSectionHeader32> Sections);
@@ -164,10 +164,17 @@ static const EnumEntry<XCOFF::CFileStringType> FileStringType[] = {
 #undef ECase
 };
 
+static const EnumEntry<XCOFF::SymbolAuxType> SymAuxType[] = {
+#define ECase(X)                                                               \
+  { #X, XCOFF::X }
+    ECase(AUX_EXCEPT), ECase(AUX_FCN), ECase(AUX_SYM), ECase(AUX_FILE),
+    ECase(AUX_CSECT),  ECase(AUX_SECT)
+#undef ECase
+};
+
 void XCOFFDumper::printFileAuxEnt(const XCOFFFileAuxEnt *AuxEntPtr) {
-  if (Obj.is64Bit())
-    report_fatal_error(
-        "Printing for File Auxiliary Entry in 64-bit is unimplemented.");
+  assert((!Obj.is64Bit() || AuxEntPtr->AuxType == XCOFF::AUX_FILE) &&
+         "Mismatched auxiliary type!");
   StringRef FileName =
       unwrapOrError(Obj.getFileName(), Obj.getCFileName(AuxEntPtr));
   DictScope SymDs(W, "File Auxiliary Entry");
@@ -176,6 +183,10 @@ void XCOFFDumper::printFileAuxEnt(const XCOFFFileAuxEnt *AuxEntPtr) {
   W.printString("Name", FileName);
   W.printEnum("Type", static_cast<uint8_t>(AuxEntPtr->Type),
               makeArrayRef(FileStringType));
+  if (Obj.is64Bit()) {
+    W.printEnum("Auxiliary Type", static_cast<uint8_t>(AuxEntPtr->AuxType),
+                makeArrayRef(SymAuxType));
+  }
 }
 
 static const EnumEntry<XCOFF::StorageMappingClass> CsectStorageMappingClass[] =
@@ -198,27 +209,32 @@ static const EnumEntry<XCOFF::SymbolType> CsectSymbolTypeClass[] = {
 #undef ECase
 };
 
-void XCOFFDumper::printCsectAuxEnt32(const XCOFFCsectAuxEnt32 *AuxEntPtr) {
-  assert(!Obj.is64Bit() && "32-bit interface called on 64-bit object file.");
+void XCOFFDumper::printCsectAuxEnt(XCOFFCsectAuxRef AuxEntRef) {
+  assert((!Obj.is64Bit() || AuxEntRef.getAuxType64() == XCOFF::AUX_CSECT) &&
+         "Mismatched auxiliary type!");
 
   DictScope SymDs(W, "CSECT Auxiliary Entry");
-  W.printNumber("Index",
-                Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
-  if (AuxEntPtr->isLabel())
-    W.printNumber("ContainingCsectSymbolIndex", AuxEntPtr->SectionOrLength);
-  else
-    W.printNumber("SectionLen", AuxEntPtr->SectionOrLength);
-  W.printHex("ParameterHashIndex", AuxEntPtr->ParameterHashIndex);
-  W.printHex("TypeChkSectNum", AuxEntPtr->TypeChkSectNum);
+  W.printNumber("Index", Obj.getSymbolIndex(AuxEntRef.getEntryAddress()));
+  W.printNumber(AuxEntRef.isLabel() ? "ContainingCsectSymbolIndex"
+                                    : "SectionLen",
+                AuxEntRef.getSectionOrLength());
+  W.printHex("ParameterHashIndex", AuxEntRef.getParameterHashIndex());
+  W.printHex("TypeChkSectNum", AuxEntRef.getTypeChkSectNum());
   // Print out symbol alignment and type.
-  W.printNumber("SymbolAlignmentLog2", AuxEntPtr->getAlignmentLog2());
-  W.printEnum("SymbolType", AuxEntPtr->getSymbolType(),
+  W.printNumber("SymbolAlignmentLog2", AuxEntRef.getAlignmentLog2());
+  W.printEnum("SymbolType", AuxEntRef.getSymbolType(),
               makeArrayRef(CsectSymbolTypeClass));
   W.printEnum("StorageMappingClass",
-              static_cast<uint8_t>(AuxEntPtr->StorageMappingClass),
+              static_cast<uint8_t>(AuxEntRef.getStorageMappingClass()),
               makeArrayRef(CsectStorageMappingClass));
-  W.printHex("StabInfoIndex", AuxEntPtr->StabInfoIndex);
-  W.printHex("StabSectNum", AuxEntPtr->StabSectNum);
+
+  if (Obj.is64Bit()) {
+    W.printEnum("Auxiliary Type", static_cast<uint8_t>(XCOFF::AUX_CSECT),
+                makeArrayRef(SymAuxType));
+  } else {
+    W.printHex("StabInfoIndex", AuxEntRef.getStabInfoIndex32());
+    W.printHex("StabSectNum", AuxEntRef.getStabSectNum32());
+  }
 }
 
 void XCOFFDumper::printSectAuxEntForStat(
@@ -300,53 +316,62 @@ static const EnumEntry<XCOFF::CFileCpuId> CFileCpuIdClass[] = {
 };
 
 void XCOFFDumper::printSymbol(const SymbolRef &S) {
-  if (Obj.is64Bit())
-    report_fatal_error("64-bit support is unimplemented.");
-
   DataRefImpl SymbolDRI = S.getRawDataRefImpl();
-  const XCOFFSymbolEntry *SymbolEntPtr = Obj.toSymbolEntry(SymbolDRI);
+  XCOFFSymbolRef SymbolEntRef = Obj.toSymbolRef(SymbolDRI);
 
-  XCOFFSymbolRef XCOFFSymRef(SymbolDRI, &Obj);
-  uint8_t NumberOfAuxEntries = XCOFFSymRef.getNumberOfAuxEntries();
+  uint8_t NumberOfAuxEntries = SymbolEntRef.getNumberOfAuxEntries();
 
   DictScope SymDs(W, "Symbol");
 
   StringRef SymbolName =
-      unwrapOrError(Obj.getFileName(), Obj.getSymbolName(SymbolDRI));
+      unwrapOrError(Obj.getFileName(), SymbolEntRef.getName());
 
-  W.printNumber("Index",
-                Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(SymbolEntPtr)));
+  W.printNumber("Index", Obj.getSymbolIndex(SymbolEntRef.getEntryAddress()));
   W.printString("Name", SymbolName);
-  W.printHex(GetSymbolValueName(SymbolEntPtr->StorageClass),
-             SymbolEntPtr->Value);
+  W.printHex(GetSymbolValueName(SymbolEntRef.getStorageClass()),
+             SymbolEntRef.getValue());
 
   StringRef SectionName =
-      unwrapOrError(Obj.getFileName(), Obj.getSymbolSectionName(SymbolEntPtr));
+      unwrapOrError(Obj.getFileName(), Obj.getSymbolSectionName(SymbolEntRef));
 
   W.printString("Section", SectionName);
-  if (XCOFFSymRef.getStorageClass() == XCOFF::C_FILE) {
-    W.printEnum("Source Language ID",
-                SymbolEntPtr->CFileLanguageIdAndTypeId.LanguageId,
+  if (SymbolEntRef.getStorageClass() == XCOFF::C_FILE) {
+    W.printEnum("Source Language ID", SymbolEntRef.getLanguageIdForCFile(),
                 makeArrayRef(CFileLangIdClass));
-    W.printEnum("CPU Version ID",
-                SymbolEntPtr->CFileLanguageIdAndTypeId.CpuTypeId,
+    W.printEnum("CPU Version ID", SymbolEntRef.getCPUTypeIddForCFile(),
                 makeArrayRef(CFileCpuIdClass));
   } else
-    W.printHex("Type", SymbolEntPtr->SymbolType);
+    W.printHex("Type", SymbolEntRef.getSymbolType());
 
-  W.printEnum("StorageClass", static_cast<uint8_t>(SymbolEntPtr->StorageClass),
+  W.printEnum("StorageClass",
+              static_cast<uint8_t>(SymbolEntRef.getStorageClass()),
               makeArrayRef(SymStorageClass));
-  W.printNumber("NumberOfAuxEntries", SymbolEntPtr->NumberOfAuxEntries);
+  W.printNumber("NumberOfAuxEntries", NumberOfAuxEntries);
 
   if (NumberOfAuxEntries == 0)
     return;
 
-  switch (XCOFFSymRef.getStorageClass()) {
+  switch (SymbolEntRef.getStorageClass()) {
   case XCOFF::C_FILE:
     // If the symbol is C_FILE and has auxiliary entries...
-    for (int i = 1; i <= NumberOfAuxEntries; i++) {
+    for (int I = 1; I <= NumberOfAuxEntries; I++) {
+      uintptr_t AuxAddress = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
+          SymbolEntRef.getEntryAddress(), I);
+
+      if (Obj.is64Bit() &&
+          *Obj.getSymbolAuxType(AuxAddress) != XCOFF::SymbolAuxType::AUX_FILE) {
+        W.startLine() << "!Unexpected raw auxiliary entry data:\n";
+        W.startLine() << format_bytes(
+                             ArrayRef<uint8_t>(
+                                 reinterpret_cast<const uint8_t *>(AuxAddress),
+                                 XCOFF::SymbolTableEntrySize),
+                             0, XCOFF::SymbolTableEntrySize)
+                      << "\n";
+        continue;
+      }
+
       const XCOFFFileAuxEnt *FileAuxEntPtr =
-          reinterpret_cast<const XCOFFFileAuxEnt *>(SymbolEntPtr + i);
+          reinterpret_cast<const XCOFFFileAuxEnt *>(AuxAddress);
 #ifndef NDEBUG
       Obj.checkSymbolEntryPointer(reinterpret_cast<uintptr_t>(FileAuxEntPtr));
 #endif
@@ -355,34 +380,52 @@ void XCOFFDumper::printSymbol(const SymbolRef &S) {
     break;
   case XCOFF::C_EXT:
   case XCOFF::C_WEAKEXT:
-  case XCOFF::C_HIDEXT:
+  case XCOFF::C_HIDEXT: {
     // If the symbol is for a function, and it has more than 1 auxiliary entry,
     // then one of them must be function auxiliary entry which we do not
     // support yet.
-    if (XCOFFSymRef.isFunction() && NumberOfAuxEntries >= 2)
+    if (SymbolEntRef.isFunction() && NumberOfAuxEntries >= 2)
       report_fatal_error("Function auxiliary entry printing is unimplemented.");
 
     // If there is more than 1 auxiliary entry, instead of printing out
-    // error information, print out the raw Auxiliary entry from 1st till
-    // the last - 1. The last one must be a CSECT Auxiliary Entry.
-    for (int i = 1; i < NumberOfAuxEntries; i++) {
+    // error information, print out the raw Auxiliary entry.
+    // For 32-bit object, print from first to the last - 1. The last one must be
+    // a CSECT Auxiliary Entry.
+    // For 64-bit object, print from first to last and skips if SymbolAuxType is
+    // AUX_CSECT.
+    for (int I = 1; I <= NumberOfAuxEntries; I++) {
+      if (I == NumberOfAuxEntries && !Obj.is64Bit())
+        break;
+
+      uintptr_t AuxAddress = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
+          SymbolEntRef.getEntryAddress(), I);
+      if (Obj.is64Bit() &&
+          *Obj.getSymbolAuxType(AuxAddress) == XCOFF::SymbolAuxType::AUX_CSECT)
+        continue;
+
       W.startLine() << "!Unexpected raw auxiliary entry data:\n";
       W.startLine() << format_bytes(
-          ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(SymbolEntPtr + i),
+          ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(AuxAddress),
                             XCOFF::SymbolTableEntrySize));
     }
 
-    // The symbol's last auxiliary entry is a CSECT Auxiliary Entry.
-    printCsectAuxEnt32(XCOFFSymRef.getXCOFFCsectAuxEnt32());
+    auto ErrOrCsectAuxRef = SymbolEntRef.getXCOFFCsectAuxRef();
+    if (!ErrOrCsectAuxRef)
+      reportUniqueWarning(ErrOrCsectAuxRef.takeError());
+    else
+      printCsectAuxEnt(*ErrOrCsectAuxRef);
+
     break;
+  }
   case XCOFF::C_STAT:
     if (NumberOfAuxEntries > 1)
       report_fatal_error(
           "C_STAT symbol should not have more than 1 auxiliary entry.");
 
     const XCOFFSectAuxEntForStat *StatAuxEntPtr;
-    StatAuxEntPtr =
-        reinterpret_cast<const XCOFFSectAuxEntForStat *>(SymbolEntPtr + 1);
+    StatAuxEntPtr = reinterpret_cast<const XCOFFSectAuxEntForStat *>(
+        XCOFFObjectFile::getAdvancedSymbolEntryAddress(
+            SymbolEntRef.getEntryAddress(), 1));
 #ifndef NDEBUG
     Obj.checkSymbolEntryPointer(reinterpret_cast<uintptr_t>(StatAuxEntPtr));
 #endif
@@ -398,7 +441,9 @@ void XCOFFDumper::printSymbol(const SymbolRef &S) {
     for (int i = 1; i <= NumberOfAuxEntries; i++) {
       W.startLine() << "!Unexpected raw auxiliary entry data:\n";
       W.startLine() << format_bytes(
-          ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(SymbolEntPtr + i),
+          ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(
+                                XCOFFObjectFile::getAdvancedSymbolEntryAddress(
+                                    SymbolEntRef.getEntryAddress(), i)),
                             XCOFF::SymbolTableEntrySize));
     }
     break;

diff  --git a/llvm/tools/obj2yaml/xcoff2yaml.cpp b/llvm/tools/obj2yaml/xcoff2yaml.cpp
index dd9d8e8750965..0309856556baf 100644
--- a/llvm/tools/obj2yaml/xcoff2yaml.cpp
+++ b/llvm/tools/obj2yaml/xcoff2yaml.cpp
@@ -55,7 +55,7 @@ std::error_code XCOFFDumper::dumpSymbols() {
 
   for (const SymbolRef &S : Obj.symbols()) {
     DataRefImpl SymbolDRI = S.getRawDataRefImpl();
-    const XCOFFSymbolEntry *SymbolEntPtr = Obj.toSymbolEntry(SymbolDRI);
+    const XCOFFSymbolRef SymbolEntRef = Obj.toSymbolRef(SymbolDRI);
     XCOFFYAML::Symbol Sym;
 
     Expected<StringRef> SymNameRefOrErr = Obj.getSymbolName(SymbolDRI);
@@ -64,18 +64,18 @@ std::error_code XCOFFDumper::dumpSymbols() {
     }
     Sym.SymbolName = SymNameRefOrErr.get();
 
-    Sym.Value = SymbolEntPtr->Value;
+    Sym.Value = SymbolEntRef.getValue();
 
     Expected<StringRef> SectionNameRefOrErr =
-        Obj.getSymbolSectionName(SymbolEntPtr);
+        Obj.getSymbolSectionName(SymbolEntRef);
     if (!SectionNameRefOrErr)
       return errorToErrorCode(SectionNameRefOrErr.takeError());
 
     Sym.SectionName = SectionNameRefOrErr.get();
 
-    Sym.Type = SymbolEntPtr->SymbolType;
-    Sym.StorageClass = SymbolEntPtr->StorageClass;
-    Sym.NumberOfAuxEntries = SymbolEntPtr->NumberOfAuxEntries;
+    Sym.Type = SymbolEntRef.getSymbolType();
+    Sym.StorageClass = SymbolEntRef.getStorageClass();
+    Sym.NumberOfAuxEntries = SymbolEntRef.getNumberOfAuxEntries();
     Symbols.push_back(Sym);
   }
 

diff  --git a/llvm/unittests/Object/XCOFFObjectFileTest.cpp b/llvm/unittests/Object/XCOFFObjectFileTest.cpp
index cb1cfe44e077f..71b902c93e3dd 100644
--- a/llvm/unittests/Object/XCOFFObjectFileTest.cpp
+++ b/llvm/unittests/Object/XCOFFObjectFileTest.cpp
@@ -384,3 +384,115 @@ TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtExtLongTBTable) {
           "unexpected end of data at offset 0x2c while reading [0x2c, 0x2d)"));
   EXPECT_EQ(Size, 44u);
 }
+
+TEST(XCOFFObjectFileTest, XCOFFGetCsectAuxRef32) {
+  uint8_t XCOFF32Binary[] = {
+      // File header.
+      0x01, 0xdf, 0x00, 0x01, 0x5f, 0x58, 0xf8, 0x95, 0x00, 0x00, 0x00, 0x3c,
+      0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+
+      // Section header for empty .data section.
+      0x2e, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x40,
+
+      // Start of symbol table.
+      // C_File symbol.
+      0x2e, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0xff, 0xfe, 0x00, 0x03, 0x67, 0x01,
+      // File Auxiliary Entry.
+      0x61, 0x2e, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+      // Csect symbol.
+      0x2e, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x01, 0x00, 0x00, 0x6b, 0x01,
+      // Csect auxiliary entry.
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x05,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+  ArrayRef<uint8_t> XCOFF32Ref(XCOFF32Binary, sizeof(XCOFF32Binary));
+  Expected<std::unique_ptr<ObjectFile>> XCOFFObjOrErr =
+      object::ObjectFile::createObjectFile(
+          MemoryBufferRef(toStringRef(XCOFF32Ref), "dummyXCOFF"),
+          file_magic::xcoff_object_32);
+  ASSERT_THAT_EXPECTED(XCOFFObjOrErr, Succeeded());
+
+  const XCOFFObjectFile &File = *cast<XCOFFObjectFile>((*XCOFFObjOrErr).get());
+  DataRefImpl Ref;
+  Ref.p = File.getSymbolEntryAddressByIndex(2);
+  XCOFFSymbolRef SymRef = File.toSymbolRef(Ref);
+  Expected<XCOFFCsectAuxRef> CsectRefOrErr = SymRef.getXCOFFCsectAuxRef();
+  ASSERT_THAT_EXPECTED(CsectRefOrErr, Succeeded());
+
+  // Set csect symbol's auxiliary entry count to 0.
+  XCOFF32Binary[113] = 0;
+  Expected<XCOFFCsectAuxRef> ExpectErr = SymRef.getXCOFFCsectAuxRef();
+  EXPECT_THAT_ERROR(
+      ExpectErr.takeError(),
+      FailedWithMessage("csect symbol \".data\" contains no auxiliary entry"));
+}
+
+TEST(XCOFFObjectFileTest, XCOFFGetCsectAuxRef64) {
+  uint8_t XCOFF64Binary[] = {
+      // File header.
+      0x01, 0xf7, 0x00, 0x01, 0x5f, 0x59, 0x25, 0xeb, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+
+      // Section header for empty .data section.
+      0x2e, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+
+      // Start of symbol table.
+      // C_File symbol.
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+      0xff, 0xfe, 0x00, 0x02, 0x67, 0x01,
+      // File Auxiliary Entry.
+      0x61, 0x2e, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+
+      // Csect symbol.
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
+      0x00, 0x01, 0x00, 0x00, 0x6b, 0x01,
+      // Csect auxiliary entry.
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x05,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0xfb,
+
+      // String table.
+      0x00, 0x00, 0x00, 0x10, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x2e, 0x64,
+      0x61, 0x74, 0x61, 0x00};
+
+  ArrayRef<uint8_t> XCOFF64Ref(XCOFF64Binary, sizeof(XCOFF64Binary));
+  Expected<std::unique_ptr<ObjectFile>> XCOFFObjOrErr =
+      object::ObjectFile::createObjectFile(
+          MemoryBufferRef(toStringRef(XCOFF64Ref), "dummyXCOFF"),
+          file_magic::xcoff_object_64);
+  ASSERT_THAT_EXPECTED(XCOFFObjOrErr, Succeeded());
+
+  const XCOFFObjectFile &File = *cast<XCOFFObjectFile>((*XCOFFObjOrErr).get());
+  DataRefImpl Ref;
+  Ref.p = File.getSymbolEntryAddressByIndex(2);
+  XCOFFSymbolRef SymRef = File.toSymbolRef(Ref);
+  Expected<XCOFFCsectAuxRef> CsectRefOrErr = SymRef.getXCOFFCsectAuxRef();
+  ASSERT_THAT_EXPECTED(CsectRefOrErr, Succeeded());
+
+  // Inject incorrect auxiliary type value.
+  XCOFF64Binary[167] = static_cast<uint8_t>(XCOFF::AUX_SYM);
+  Expected<XCOFFCsectAuxRef> NotFoundErr = SymRef.getXCOFFCsectAuxRef();
+  EXPECT_THAT_ERROR(
+      NotFoundErr.takeError(),
+      FailedWithMessage(
+          "a csect auxiliary entry is not found for symbol \".data\""));
+
+  // Set csect symbol's auxiliary entry count to 0.
+  XCOFF64Binary[149] = 0;
+  Expected<XCOFFCsectAuxRef> ExpectErr = SymRef.getXCOFFCsectAuxRef();
+  EXPECT_THAT_ERROR(
+      ExpectErr.takeError(),
+      FailedWithMessage("csect symbol \".data\" contains no auxiliary entry"));
+}


        


More information about the llvm-commits mailing list