Index: llvm/include/llvm/BinaryFormat/XCOFF.h
===================================================================
--- llvm/include/llvm/BinaryFormat/XCOFF.h
+++ llvm/include/llvm/BinaryFormat/XCOFF.h
@@ -13,11 +13,14 @@
 #ifndef LLVM_BINARYFORMAT_XCOFF_H
 #define LLVM_BINARYFORMAT_XCOFF_H
 
+#include <cstdint>
+
 namespace llvm {
 namespace XCOFF {
 
 // Constants used in the XCOFF definition.
-enum { SectionNameSize = 8 };
+enum { SectionNameSize = 8, SymbolNameSize = 8 };
+enum ReservedSectionNum { N_DEBUG = -2, N_ABS = -1, N_UNDEF = 0 };
 
 // Flags for defining the section type. Used for the s_flags field of
 // the section header structure. Defined in the system header `scnhdr.h`.
@@ -37,6 +40,75 @@
   STYP_OVRFLO = 0x8000
 };
 
+// STORAGE CLASSES, n_sclass field of syment.
+// The values come from `storclass.h` and `dbxstclass.h`.
+enum StorageClass : uint8_t {
+  // Storage classes used for symbolic debugging symbols.
+  C_FILE = 103,  // File name
+  C_BINCL = 108, // Beginning of include file
+  C_EINCL = 109, // Ending of include file
+  C_GSYM = 128,  // Global variable
+  C_STSYM = 133, // Statically allocated symbol
+  C_BCOMM = 135, // Beginning of common block
+  C_ECOMM = 137, // End of common block
+  C_ENTRY = 141, // Alternate entry
+  C_BSTAT = 143, // Beginning of static block
+  C_ESTAT = 144, // End of static block
+  C_GTLS = 145,  // Global thread-local variable
+  C_STTLS = 146, // Static thread-local variable
+
+  // Storage classes used for DWARF symbols.
+  C_DWARF = 112, // DWARF section symbol
+
+  // Storage classes used for absolute symbols.
+  C_LSYM = 129,  // Automatic variable allocated on stack
+  C_PSYM = 130,  // Argument to subroutine allocated on stack
+  C_RSYM = 131,  // Register variable
+  C_RPSYM = 132, // Argument to function or procedure stored in register
+  C_ECOML = 136, // Local member of common block
+  C_FUN = 142,   // Function or procedure
+
+  // Storage classes used for undefined external symbols or
+  // symbols of general sections.
+  C_EXT = 2,       // External symbol
+  C_WEAKEXT = 111, // Weak external symbol
+
+  // Storage classes used for symbols of general sections.
+  C_NULL = 0,
+  C_STAT = 3,     // Static
+  C_BLOCK = 100,  // ".bb" or ".eb"
+  C_FCN = 101,    // ".bf" or ".ef"
+  C_HIDEXT = 107, // Un-named external symbol
+  C_INFO = 110,   // Comment string in .info section
+  C_DECL = 140,   // Declaration of object (type)
+
+  // Storage classes - Obsolete/Undocumented.
+  C_AUTO = 1,     // Automatic variable
+  C_REG = 4,      // Register variable
+  C_EXTDEF = 5,   // External definition
+  C_LABEL = 6,    // Label
+  C_ULABEL = 7,   // Undefined label
+  C_MOS = 8,      // Member of structure
+  C_ARG = 9,      // Function argument
+  C_STRTAG = 10,  // Structure tag
+  C_MOU = 11,     // Member of union
+  C_UNTAG = 12,   // Union tag
+  C_TPDEF = 13,   // Type definition
+  C_USTATIC = 14, // Undefined static
+  C_ENTAG = 15,   // Enumeration tag
+  C_MOE = 16,     // Member of enumeration
+  C_REGPARM = 17, // Register parameter
+  C_FIELD = 18,   // Bit field
+  C_EOS = 102,    // End of structure
+  C_LINE = 104,
+  C_ALIAS = 105,  // Duplicate tag
+  C_HIDDEN = 106, // Special storage class for external
+  C_EFCN = 255,   // Physical end of function
+
+  // Storage classes - reserved
+  C_TCSYM = 134 // Reserved
+};
+
 } // end namespace XCOFF
 } // end namespace llvm
 
Index: llvm/include/llvm/Object/XCOFFObjectFile.h
===================================================================
--- llvm/include/llvm/Object/XCOFFObjectFile.h
+++ llvm/include/llvm/Object/XCOFFObjectFile.h
@@ -61,15 +61,50 @@
   support::big32_t Flags;
 };
 
+struct XCOFFSymbolEntry {
+  enum { NAME_IN_STR_TBL_MAGIC = 0x0 };
+  union {
+    char SymbolName[XCOFF::SymbolNameSize];
+    struct {
+      support::big32_t Magic; // Zero indicates name in string table.
+      support::ubig32_t Offset;
+    } NameInStrTbl;
+  };
+
+  support::ubig32_t Value; // Symbol value; storage class-dependent.
+  support::big16_t SectionNumber;
+
+  union {
+    support::ubig16_t SymbolType;
+    struct {
+      uint8_t LanguageId;
+      uint8_t CpuTypeId;
+    } CFileLanguageIdAndTypeId;
+  };
+
+  XCOFF::StorageClass StorageClass;
+  uint8_t NumberOfAuxEntries;
+};
+
+struct XCOFFStringTable {
+  uint32_t Size;
+  const char *Data;
+};
+
 class XCOFFObjectFile : public ObjectFile {
 private:
   const XCOFFFileHeader *FileHdrPtr = nullptr;
   const XCOFFSectionHeader *SectionHdrTablePtr = nullptr;
+  const XCOFFSymbolEntry *SymbolTblPtr = nullptr;
+  XCOFFStringTable StringTable = {0, nullptr};
 
   size_t getFileHeaderSize() const;
   size_t getSectionHeaderSize() const;
 
   const XCOFFSectionHeader *toSection(DataRefImpl Ref) const;
+  static bool isReservedSectionNumber(int16_t SectionNumber);
+  std::error_code getSectionByNum(int16_t Num,
+                                  const XCOFFSectionHeader *&Result) const;
 
 
 public:
@@ -121,18 +156,27 @@
   XCOFFObjectFile(MemoryBufferRef Object, std::error_code &EC);
 
   const XCOFFFileHeader *getFileHeader() const { return FileHdrPtr; }
+  const XCOFFSymbolEntry *getPointerToSymbolTable() const {
+    return SymbolTblPtr;
+  }
+
+  Expected<StringRef>
+  getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const;
 
+  const XCOFFSymbolEntry *toSymbolEntry(DataRefImpl Ref) const;
   uint16_t getMagic() const;
   uint16_t getNumberOfSections() const;
   int32_t  getTimeStamp() const;
   uint32_t  getSymbolTableOffset() const;
 
-  // Note that this value is signed and might return a negative value. Negative
-  // values are reserved for future use.
-  int32_t  getNumberOfSymbolTableEntries() const;
-
+  // Returns the value as encoded in the object file.
+  // Negative values are reserved for future use.
+  int32_t getRawNumberOfSymbolTableEntries() const;
+	
+  // Returns a sanitized value, useable as an index into the symbol table.
+  uint32_t getLogicalNumberOfSymbolTableEntries() const;
   uint16_t getOptionalHeaderSize() const;
-  uint16_t getFlags() const;
+  uint16_t getFlags() const { return FileHdrPtr->Flags; };
 }; // XCOFFObjectFile
 
 } // namespace object
Index: llvm/include/llvm/ObjectYAML/XCOFFYAML.h
===================================================================
--- llvm/include/llvm/ObjectYAML/XCOFFYAML.h
+++ llvm/include/llvm/ObjectYAML/XCOFFYAML.h
@@ -12,8 +12,11 @@
 #ifndef LLVM_OBJECTYAML_XCOFFYAML_H
 #define LLVM_OBJECTYAML_XCOFFYAML_H
 
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/XCOFF.h"
 #include "llvm/ObjectYAML/YAML.h"
 #include <cstdint>
+#include <vector>
 
 namespace llvm {
 namespace XCOFFYAML {
@@ -28,14 +31,30 @@
   llvm::yaml::Hex16 Flags;
 };
 
+struct Symbol {
+  StringRef SymbolName;
+  llvm::yaml::Hex32 Value; // Symbol value; storage class-dependent.
+  StringRef SectionName;
+  llvm::yaml::Hex16 Type;
+  XCOFF::StorageClass StorageClass;
+  uint8_t NumberOfAuxEntries; // Number of auxiliary entries
+};
+
 struct Object {
   FileHeader Header;
+  std::vector<Symbol> Symbols;
   Object();
 };
 } // namespace XCOFFYAML
-
+} // namespace llvm
+LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Symbol)
+namespace llvm {
 namespace yaml {
 
+template <> struct ScalarEnumerationTraits<XCOFF::StorageClass> {
+  static void enumeration(IO &IO, XCOFF::StorageClass &Value);
+};
+
 template <> struct MappingTraits<XCOFFYAML::FileHeader> {
   static void mapping(IO &IO, XCOFFYAML::FileHeader &H);
 };
@@ -44,6 +63,10 @@
   static void mapping(IO &IO, XCOFFYAML::Object &Obj);
 };
 
+template <> struct MappingTraits<XCOFFYAML::Symbol> {
+  static void mapping(IO &IO, XCOFFYAML::Symbol &S);
+};
+
 } // namespace yaml
 } // namespace llvm
 
Index: llvm/lib/Object/XCOFFObjectFile.cpp
===================================================================
--- llvm/lib/Object/XCOFFObjectFile.cpp
+++ llvm/lib/Object/XCOFFObjectFile.cpp
@@ -26,6 +26,17 @@
 static_assert(sizeof(XCOFFFileHeader) == XCOFF32FileHeaderSize,
               "Wrong size for XCOFF file header.");
 
+// Sets EC and returns false if there is less than 'Size' bytes left in the
+// buffer at 'Offset'.
+static bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Offset,
+                      uint64_t Size) {
+  if (M.getBufferSize() < Offset + Size) {
+    EC = object_error::unexpected_eof;
+    return false;
+  }
+  return true;
+}
+
 // Sets Obj unless any bytes in [addr, addr + size) fall outsize of m.
 // Returns unexpected_eof on error.
 template <typename T>
@@ -43,6 +54,12 @@
   return reinterpret_cast<const T *>(in);
 }
 
+static StringRef generateStringRef(const char *Name, uint64_t Size) {
+  auto NulCharPtr = static_cast<const char *>(memchr(Name, '\0', Size));
+  return NulCharPtr ? StringRef(Name, NulCharPtr - Name)
+                    : StringRef(Name, Size);
+}
+
 const XCOFFSectionHeader *XCOFFObjectFile::toSection(DataRefImpl Ref) const {
   auto Sec = viewAs<XCOFFSectionHeader>(Ref.p);
 #ifndef NDEBUG
@@ -58,6 +75,12 @@
   return Sec;
 }
 
+const XCOFFSymbolEntry *XCOFFObjectFile::toSymbolEntry(DataRefImpl Ref) const {
+  assert(Ref.p != 0 && "Symbol table pointer can not be nullptr!");
+  auto SymEntPtr = viewAs<XCOFFSymbolEntry>(Ref.p);
+  return SymEntPtr;
+}
+
 // The next 2 functions are not exactly necessary yet, but they are useful to
 // abstract over the size difference between XCOFF32 and XCOFF64 structure
 // definitions.
@@ -69,15 +92,39 @@
   return sizeof(XCOFFSectionHeader);
 }
 
+uint16_t XCOFFObjectFile::getMagic() const { return FileHdrPtr->Magic; }
+
 void XCOFFObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
-  llvm_unreachable("Not yet implemented!");
+  const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
+
+  SymEntPtr += SymEntPtr->NumberOfAuxEntries + 1;
+  Symb.p = reinterpret_cast<uintptr_t>(SymEntPtr);
   return;
 }
 
 Expected<StringRef> XCOFFObjectFile::getSymbolName(DataRefImpl Symb) const {
-  StringRef Result;
-  llvm_unreachable("Not yet implemented!");
-  return Result;
+  const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
+
+  if (SymEntPtr->NameInStrTbl.Magic != XCOFFSymbolEntry::NAME_IN_STR_TBL_MAGIC)
+    return generateStringRef(SymEntPtr->SymbolName, XCOFF::SymbolNameSize);
+
+  if (SymEntPtr->SectionNumber == XCOFF::N_DEBUG) {
+    llvm_unreachable("Not yet implemented!");
+    return StringRef(nullptr, 0);
+  }
+
+  uint32_t Offset = SymEntPtr->NameInStrTbl.Offset;
+  // The byte offset is relative to the start of the string table
+  // or .debug section.
+  // A byte offset value less than 4 is a null or zero-length symbol name.
+  if (Offset < 4)
+    return StringRef(nullptr, 0);
+
+  if (StringTable.Data != nullptr && StringTable.Size > Offset)
+    return (StringTable.Data + Offset);
+
+  return make_error<GenericBinaryError>("Symbol Name parse failed.",
+                                        object_error::parse_failed);
 }
 
 Expected<uint64_t> XCOFFObjectFile::getSymbolAddress(DataRefImpl Symb) const {
@@ -87,9 +134,7 @@
 }
 
 uint64_t XCOFFObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
-  uint64_t Result = 0;
-  llvm_unreachable("Not yet implemented!");
-  return Result;
+  return toSymbolEntry(Symb)->Value;
 }
 
 uint64_t XCOFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
@@ -106,8 +151,20 @@
 
 Expected<section_iterator>
 XCOFFObjectFile::getSymbolSection(DataRefImpl Symb) const {
-  llvm_unreachable("Not yet implemented!");
-  return section_iterator(SectionRef());
+  const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
+  int16_t SectNum = SymEntPtr->SectionNumber;
+
+  if (isReservedSectionNumber(SectNum))
+    return section_end();
+
+  const XCOFFSectionHeader *Sec;
+  if (std::error_code EC = getSectionByNum(SectNum, Sec))
+    return errorCodeToError(EC);
+
+  DataRefImpl SecDRI;
+  SecDRI.p = reinterpret_cast<uintptr_t>(Sec);
+
+  return section_iterator(SectionRef(SecDRI, this));
 }
 
 void XCOFFObjectFile::moveSectionNext(DataRefImpl &Sec) const {
@@ -220,13 +277,16 @@
 }
 
 basic_symbol_iterator XCOFFObjectFile::symbol_begin() const {
-  llvm_unreachable("Not yet implemented!");
-  return basic_symbol_iterator(SymbolRef());
+  DataRefImpl SymDRI;
+  SymDRI.p = reinterpret_cast<uintptr_t>(SymbolTblPtr);
+  return basic_symbol_iterator(SymbolRef(SymDRI, this));
 }
 
 basic_symbol_iterator XCOFFObjectFile::symbol_end() const {
-  llvm_unreachable("Not yet implemented!");
-  return basic_symbol_iterator(SymbolRef());
+  DataRefImpl SymDRI;
+  SymDRI.p = reinterpret_cast<uintptr_t>(
+      SymbolTblPtr + getLogicalNumberOfSymbolTableEntries());
+  return basic_symbol_iterator(SymbolRef(SymDRI, this));
 }
 
 section_iterator XCOFFObjectFile::section_begin() const {
@@ -244,7 +304,7 @@
 
 uint8_t XCOFFObjectFile::getBytesInAddress() const {
   // Only support 32-bit object files for now ...
-  assert(getFileHeaderSize() ==  XCOFF32FileHeaderSize);
+  assert(getFileHeaderSize() == XCOFF32FileHeaderSize);
   return 4;
 }
 
@@ -275,6 +335,67 @@
   return 0;
 }
 
+std::error_code
+XCOFFObjectFile::getSectionByNum(int16_t Num,
+                                 const XCOFFSectionHeader *&Result) const {
+  if (Num > 0 && static_cast<uint16_t>(Num) <= getNumberOfSections()) {
+    Result = SectionHdrTablePtr + (Num - 1);
+    return std::error_code();
+  }
+
+  return object_error::invalid_section_index;
+}
+
+Expected<StringRef>
+XCOFFObjectFile::getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const {
+  int16_t SectionNum = SymEntPtr->SectionNumber;
+
+  switch (SectionNum) {
+  case XCOFF::N_DEBUG:
+    return "N_DEBUG";
+  case XCOFF::N_ABS:
+    return "N_ABS";
+  case XCOFF::N_UNDEF:
+    return "N_UNDEF";
+  default: {
+    const XCOFFSectionHeader *SectHeaderPtr;
+    std::error_code EC;
+    if (EC = getSectionByNum(SectionNum, SectHeaderPtr))
+      return errorCodeToError(EC);
+    else
+      return generateStringRef(SectHeaderPtr->Name, XCOFF::SectionNameSize);
+  }
+  }
+}
+
+bool XCOFFObjectFile::isReservedSectionNumber(int16_t SectionNumber) {
+  return (SectionNumber <= 0 && SectionNumber >= -2);
+}
+
+uint16_t XCOFFObjectFile::getNumberOfSections() const {
+  return FileHdrPtr->NumberOfSections;
+}
+
+int32_t XCOFFObjectFile::getTimeStamp() const { return FileHdrPtr->TimeStamp; }
+
+uint32_t XCOFFObjectFile::getSymbolTableOffset() const {
+  return FileHdrPtr->SymbolTableOffset;
+}
+
+int32_t XCOFFObjectFile::getRawNumberOfSymbolTableEntries() const {
+  return FileHdrPtr->NumberOfSymTableEntries;
+}
+
+uint32_t XCOFFObjectFile::getLogicalNumberOfSymbolTableEntries() const {
+  return (FileHdrPtr->NumberOfSymTableEntries >= 0
+              ? FileHdrPtr->NumberOfSymTableEntries
+              : 0);
+}
+
+uint16_t XCOFFObjectFile::getOptionalHeaderSize() const {
+  return FileHdrPtr->AuxHeaderSize;
+}
+
 XCOFFObjectFile::XCOFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
     : ObjectFile(Binary::ID_XCOFF32, Object) {
 
@@ -294,37 +415,39 @@
                         getNumberOfSections() * getSectionHeaderSize())))
       return;
   }
-}
 
-uint16_t XCOFFObjectFile::getMagic() const {
-  return FileHdrPtr->Magic;
-}
+  if (getLogicalNumberOfSymbolTableEntries() == 0)
+    return;
 
-uint16_t XCOFFObjectFile::getNumberOfSections() const {
-  return FileHdrPtr->NumberOfSections;
-}
+  // Get pointer to the symbol table.
+  CurPtr = FileHdrPtr->SymbolTableOffset;
+  uint64_t SymbolTableSize = (uint64_t)(sizeof(XCOFFSymbolEntry)) *
+                             getLogicalNumberOfSymbolTableEntries();
 
-int32_t XCOFFObjectFile::getTimeStamp() const {
-  return FileHdrPtr->TimeStamp;
-}
+  if ((EC = getObject(SymbolTblPtr, Data, base() + CurPtr, SymbolTableSize)))
+    return;
 
-uint32_t XCOFFObjectFile::getSymbolTableOffset() const {
-  return FileHdrPtr->SymbolTableOffset;
-}
+  // Move pointer to the string table.
+  CurPtr += SymbolTableSize;
 
-int32_t XCOFFObjectFile::getNumberOfSymbolTableEntries() const {
-  // As far as symbol table size is concerned, if this field is negative it is
-  // to be treated as a 0. However since this field is also used for printing we
-  // don't want to truncate any negative values.
-  return FileHdrPtr->NumberOfSymTableEntries;
-}
+  if (CurPtr + 4 > Data.getBufferSize())
+    return;
 
-uint16_t XCOFFObjectFile::getOptionalHeaderSize() const {
-  return FileHdrPtr->AuxHeaderSize;
-}
+  StringTable.Size = support::endian::read32be(base() + CurPtr);
+
+  if (StringTable.Size <= 4)
+    return;
+
+  // Check for whether the String table has the size indicated by length
+  // field
+  if (!checkSize(Data, EC, CurPtr, (StringTable.Size)))
+    return;
 
-uint16_t XCOFFObjectFile::getFlags() const {
-  return FileHdrPtr->Flags;
+  StringTable.Data = reinterpret_cast<const char *>(base() + CurPtr);
+  if (StringTable.Data[StringTable.Size - 1] != '\0') {
+    EC = object_error::string_table_non_null_end;
+    return;
+  }
 }
 
 Expected<std::unique_ptr<ObjectFile>>
Index: llvm/lib/ObjectYAML/XCOFFYAML.cpp
===================================================================
--- llvm/lib/ObjectYAML/XCOFFYAML.cpp
+++ llvm/lib/ObjectYAML/XCOFFYAML.cpp
@@ -11,7 +11,13 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/ObjectYAML/XCOFFYAML.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/XCOFF.h"
+#include "llvm/ObjectYAML/YAML.h"
+#include "llvm/Support/YAMLTraits.h"
 #include <string.h>
+#include <cstdint>
+#include <vector>
 
 namespace llvm {
 namespace XCOFFYAML {
@@ -22,6 +28,62 @@
 
 namespace yaml {
 
+void ScalarEnumerationTraits<XCOFF::StorageClass>::enumeration(
+    IO &IO, XCOFF::StorageClass &Value) {
+#define ECase(X) IO.enumCase(Value, #X, XCOFF::X)
+  ECase(C_NULL);
+  ECase(C_AUTO);
+  ECase(C_EXT);
+  ECase(C_STAT);
+  ECase(C_REG);
+  ECase(C_EXTDEF);
+  ECase(C_LABEL);
+  ECase(C_ULABEL);
+  ECase(C_MOS);
+  ECase(C_ARG);
+  ECase(C_STRTAG);
+  ECase(C_MOU);
+  ECase(C_UNTAG);
+  ECase(C_TPDEF);
+  ECase(C_USTATIC);
+  ECase(C_ENTAG);
+  ECase(C_MOE);
+  ECase(C_REGPARM);
+  ECase(C_FIELD);
+  ECase(C_BLOCK);
+  ECase(C_FCN);
+  ECase(C_EOS);
+  ECase(C_FILE);
+  ECase(C_LINE);
+  ECase(C_ALIAS);
+  ECase(C_HIDDEN);
+  ECase(C_HIDEXT);
+  ECase(C_BINCL);
+  ECase(C_EINCL);
+  ECase(C_INFO);
+  ECase(C_WEAKEXT);
+  ECase(C_DWARF);
+  ECase(C_GSYM);
+  ECase(C_LSYM);
+  ECase(C_PSYM);
+  ECase(C_RSYM);
+  ECase(C_RPSYM);
+  ECase(C_STSYM);
+  ECase(C_TCSYM);
+  ECase(C_BCOMM);
+  ECase(C_ECOML);
+  ECase(C_ECOMM);
+  ECase(C_DECL);
+  ECase(C_ENTRY);
+  ECase(C_FUN);
+  ECase(C_BSTAT);
+  ECase(C_ESTAT);
+  ECase(C_GTLS);
+  ECase(C_STTLS);
+  ECase(C_EFCN);
+#undef ECase
+}
+
 void MappingTraits<XCOFFYAML::FileHeader>::mapping(
     IO &IO, XCOFFYAML::FileHeader &FileHdr) {
   IO.mapRequired("MagicNumber", FileHdr.Magic);
@@ -33,9 +95,19 @@
   IO.mapRequired("Flags", FileHdr.Flags);
 }
 
+void MappingTraits<XCOFFYAML::Symbol>::mapping(IO &IO, XCOFFYAML::Symbol &S) {
+  IO.mapRequired("Name", S.SymbolName);
+  IO.mapRequired("Value", S.Value);
+  IO.mapRequired("Section", S.SectionName);
+  IO.mapRequired("Type", S.Type);
+  IO.mapRequired("StorageClass", S.StorageClass);
+  IO.mapRequired("NumberOfAuxEntries", S.NumberOfAuxEntries);
+}
+
 void MappingTraits<XCOFFYAML::Object>::mapping(IO &IO, XCOFFYAML::Object &Obj) {
   IO.mapTag("!XCOFF", true);
   IO.mapRequired("FileHeader", Obj.Header);
+  IO.mapRequired("Symbols", Obj.Symbols);
 }
 
 } // namespace yaml
Index: llvm/test/tools/obj2yaml/aix_xcoff.test
===================================================================
--- llvm/test/tools/obj2yaml/aix_xcoff.test
+++ llvm/test/tools/obj2yaml/aix_xcoff.test
@@ -1,11 +1,80 @@
 # RUN: obj2yaml %S/Inputs/aix_xcoff.o | FileCheck %s
 # Test that we can parse the XCOFF object file correctly.
 # CHECK: --- !XCOFF
-# CHECK-NEXT: FileHeader:
-# CHECK-NEXT: MagicNumber:     0x01DF
-# CHECK-NEXT: NumberOfSections: 2
-# CHECK-NEXT: CreationTime:    1548692020
-# CHECK-NEXT: OffsetToSymbolTable: 0x00000108
-# CHECK-NEXT: EntriesInSymbolTable: 18
-# CHECK-NEXT: AuxiliaryHeaderSize: 0
-# CHECK-NEXT: Flags:           0x0000
+# CHECK-NEXT: FileHeader:      
+# CHECK-NEXT:   MagicNumber:     0x01DF
+# CHECK-NEXT:   NumberOfSections: 2
+# CHECK-NEXT:   CreationTime:    1552337792
+# CHECK-NEXT:   OffsetToSymbolTable: 0x0000013A
+# CHECK-NEXT:   EntriesInSymbolTable: 22
+# CHECK-NEXT:   AuxiliaryHeaderSize: 0
+# CHECK-NEXT:   Flags:           0x0000
+
+# CHECK: Symbols:         
+# CHECK-NEXT:   - Name:      .file
+# CHECK-NEXT:     Value:     0x00000000
+# CHECK-NEXT:     Section: N_DEBUG
+# CHECK-NEXT:     Type:      0x0003
+# CHECK-NEXT:     StorageClass:    C_FILE
+# CHECK-NEXT:     NumberOfAuxEntries: 1
+# CHECK-NEXT:   - Name:      i
+# CHECK-NEXT:     Value:     0x00000000
+# CHECK-NEXT:     Section: N_UNDEF
+# CHECK-NEXT:     Type:      0x0000
+# CHECK-NEXT:     StorageClass:    C_EXT
+# CHECK-NEXT:     NumberOfAuxEntries: 1
+# CHECK-NEXT:   - Name:      TestforXcoff
+# CHECK-NEXT:     Value:     0x00000000
+# CHECK-NEXT:     Section: N_UNDEF
+# CHECK-NEXT:     Type:      0x0000
+# CHECK-NEXT:     StorageClass:    C_EXT
+# CHECK-NEXT:     NumberOfAuxEntries: 1
+# CHECK-NEXT:   - Name:      .text
+# CHECK-NEXT:     Value:     0x00000000
+# CHECK-NEXT:     Section: .text
+# CHECK-NEXT:     Type:      0x0000
+# CHECK-NEXT:     StorageClass:    C_HIDEXT
+# CHECK-NEXT:     NumberOfAuxEntries: 1
+# CHECK-NEXT:   - Name:      .main
+# CHECK-NEXT:     Value:     0x00000000
+# CHECK-NEXT:     Section: .text
+# CHECK-NEXT:     Type:      0x0000
+# CHECK-NEXT:     StorageClass:    C_EXT
+# CHECK-NEXT:     NumberOfAuxEntries: 1
+# CHECK-NEXT:   - Name:      main
+# CHECK-NEXT:     Value:     0x00000060
+# CHECK-NEXT:     Section: .data
+# CHECK-NEXT:     Type:      0x0000
+# CHECK-NEXT:     StorageClass:    C_HIDEXT
+# CHECK-NEXT:     NumberOfAuxEntries: 1
+# CHECK-NEXT:   - Name:      main
+# CHECK-NEXT:     Value:     0x00000060
+# CHECK-NEXT:     Section: .data
+# CHECK-NEXT:     Type:      0x0000
+# CHECK-NEXT:     StorageClass:    C_EXT
+# CHECK-NEXT:     NumberOfAuxEntries: 1
+# CHECK-NEXT:   - Name:      .data
+# CHECK-NEXT:     Value:     0x00000070
+# CHECK-NEXT:     Section: .data
+# CHECK-NEXT:     Type:      0x0000
+# CHECK-NEXT:     StorageClass:    C_HIDEXT
+# CHECK-NEXT:     NumberOfAuxEntries: 1
+# CHECK-NEXT:   - Name:      TOC
+# CHECK-NEXT:     Value:     0x00000074
+# CHECK-NEXT:     Section: .data
+# CHECK-NEXT:     Type:      0x0000
+# CHECK-NEXT:     StorageClass:    C_HIDEXT
+# CHECK-NEXT:     NumberOfAuxEntries: 1
+# CHECK-NEXT:   - Name:      i
+# CHECK-NEXT:     Value:     0x00000074
+# CHECK-NEXT:     Section: .data
+# CHECK-NEXT:     Type:      0x0000
+# CHECK-NEXT:     StorageClass:    C_HIDEXT
+# CHECK-NEXT:     NumberOfAuxEntries: 1
+# CHECK-NEXT:   - Name:      TestforXcoff
+# CHECK-NEXT:     Value:     0x00000078
+# CHECK-NEXT:     Section: .data
+# CHECK-NEXT:     Type:      0x0000
+# CHECK-NEXT:     StorageClass:    C_HIDEXT
+# CHECK-NEXT:     NumberOfAuxEntries: 1
+# CHECK-NEXT: ...
Index: llvm/tools/llvm-readobj/XCOFFDumper.cpp
===================================================================
--- llvm/tools/llvm-readobj/XCOFFDumper.cpp
+++ llvm/tools/llvm-readobj/XCOFFDumper.cpp
@@ -66,7 +66,7 @@
   }
 
   W.printHex("SymbolTableOffset", Obj.getSymbolTableOffset());
-  int32_t SymTabEntries = Obj.getNumberOfSymbolTableEntries();
+  int32_t SymTabEntries = Obj.getRawNumberOfSymbolTableEntries();
   if (SymTabEntries >= 0)
     W.printNumber("SymbolTableEntries", SymTabEntries);
   else
Index: llvm/tools/obj2yaml/xcoff2yaml.cpp
===================================================================
--- llvm/tools/obj2yaml/xcoff2yaml.cpp
+++ llvm/tools/obj2yaml/xcoff2yaml.cpp
@@ -19,15 +19,20 @@
   const object::XCOFFObjectFile &Obj;
   XCOFFYAML::Object YAMLObj;
   void dumpHeader();
+  std::error_code dumpSymbols();
 
 public:
-  XCOFFDumper(const object::XCOFFObjectFile &obj);
+  XCOFFDumper(const object::XCOFFObjectFile &obj) : Obj(obj) {}
+  std::error_code dump();
   XCOFFYAML::Object &getYAMLObj() { return YAMLObj; }
 };
 } // namespace
 
-XCOFFDumper::XCOFFDumper(const object::XCOFFObjectFile &obj) : Obj(obj) {
+std::error_code XCOFFDumper::dump() {
+  std::error_code EC;
   dumpHeader();
+  if ((EC = dumpSymbols()))
+    return EC;
 }
 
 void XCOFFDumper::dumpHeader() {
@@ -42,9 +47,45 @@
   YAMLObj.Header.Flags = FileHdrPtr->Flags;
 }
 
+std::error_code XCOFFDumper::dumpSymbols() {
+  std::vector<XCOFFYAML::Symbol> &Symbols = YAMLObj.Symbols;
+
+  for (const SymbolRef &S : Obj.symbols()) {
+    DataRefImpl SymbolDRI = S.getRawDataRefImpl();
+    const XCOFFSymbolEntry *SymbolEntPtr = Obj.toSymbolEntry(SymbolDRI);
+    XCOFFYAML::Symbol Sym;
+
+    Expected<StringRef> SymNameRefOrErr = Obj.getSymbolName(SymbolDRI);
+    if (!SymNameRefOrErr) {
+      return errorToErrorCode(SymNameRefOrErr.takeError());
+    }
+    Sym.SymbolName = SymNameRefOrErr.get();
+
+    Sym.Value = SymbolEntPtr->Value;
+
+    Expected<StringRef> SectionNameRefOrErr =
+        Obj.getSymbolSectionName(SymbolEntPtr);
+    if (!SectionNameRefOrErr) 
+      return errorToErrorCode(SectionNameRefOrErr.takeError());
+    
+    Sym.SectionName = SectionNameRefOrErr.get();
+
+    Sym.Type = SymbolEntPtr->SymbolType;
+    Sym.StorageClass = SymbolEntPtr->StorageClass;
+    Sym.NumberOfAuxEntries = SymbolEntPtr->NumberOfAuxEntries;
+    Symbols.push_back(Sym);
+  }
+
+  return std::error_code();
+}
+
 std::error_code xcoff2yaml(raw_ostream &Out,
                            const object::XCOFFObjectFile &Obj) {
   XCOFFDumper Dumper(Obj);
+
+  if (std::error_code EC = Dumper.dump())
+    return EC;
+
   yaml::Output Yout(Out);
   Yout << Dumper.getYAMLObj();