[llvm] r370097 - [XCOFF][AIX] Generate symbol table entries with llvm-readobj

Jason Liu via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 27 11:54:46 PDT 2019


Author: jasonliu
Date: Tue Aug 27 11:54:46 2019
New Revision: 370097

URL: http://llvm.org/viewvc/llvm-project?rev=370097&view=rev
Log:
[XCOFF][AIX] Generate symbol table entries with llvm-readobj

Summary:

This patch implements main entry and auxiliary entries of symbol table generation for llvm-readobj on AIX.
The source code of aix_xcoff_xlc_test8.o (compile with xlc) is:

-bash-4.2$ 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);
}

Patch provided by DiggerLin

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

Added:
    llvm/trunk/test/tools/llvm-readobj/Inputs/aix_xcoff_xlc_test8.o   (with props)
    llvm/trunk/test/tools/llvm-readobj/xcoff-symbols.test
Modified:
    llvm/trunk/include/llvm/BinaryFormat/XCOFF.h
    llvm/trunk/include/llvm/Object/XCOFFObjectFile.h
    llvm/trunk/lib/Object/XCOFFObjectFile.cpp
    llvm/trunk/tools/llvm-readobj/XCOFFDumper.cpp

Modified: llvm/trunk/include/llvm/BinaryFormat/XCOFF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BinaryFormat/XCOFF.h?rev=370097&r1=370096&r2=370097&view=diff
==============================================================================
--- llvm/trunk/include/llvm/BinaryFormat/XCOFF.h (original)
+++ llvm/trunk/include/llvm/BinaryFormat/XCOFF.h Tue Aug 27 11:54:46 2019
@@ -19,12 +19,13 @@ namespace llvm {
 namespace XCOFF {
 
 // Constants used in the XCOFF definition.
-enum { NameSize = 8 };
+enum { FileNamePadSize = 6, NameSize = 8, SymbolTableEntrySize = 18 };
+
 enum ReservedSectionNum { N_DEBUG = -2, N_ABS = -1, N_UNDEF = 0 };
 
 // x_smclas field of x_csect from system header: /usr/include/syms.h
 /// Storage Mapping Class definitions.
-enum StorageMappingClass {
+enum StorageMappingClass : uint8_t {
   //     READ ONLY CLASSES
   XMC_PR = 0,      ///< Program Code
   XMC_RO = 1,      ///< Read Only Constant
@@ -170,6 +171,24 @@ struct SectionHeader32 {
   int32_t Flags;
 };
 
+enum CFileStringType : uint8_t {
+  XFT_FN = 0,  ///< Specifies the source-file name.
+  XFT_CT = 1,  ///< Specifies the compiler time stamp.
+  XFT_CV = 2,  ///< Specifies the compiler version number.
+  XFT_CD = 128 ///< Specifies compiler-defined information.
+};
+
+enum CFileLangId : uint8_t {
+  TB_C = 0,        ///< C language.
+  TB_CPLUSPLUS = 9 ///< C++ language.
+};
+
+enum CFileCpuId : uint8_t {
+  TCPU_PPC64 = 2, ///< PowerPC common architecture 64-bit mode.
+  TCPU_COM = 3,   ///< POWER and PowerPC architecture common.
+  TCPU_970 = 19   ///< PPC970 - PowerPC 64-bit architecture.
+};
+
 } // end namespace XCOFF
 } // end namespace llvm
 

Modified: llvm/trunk/include/llvm/Object/XCOFFObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/XCOFFObjectFile.h?rev=370097&r1=370096&r2=370097&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/XCOFFObjectFile.h (original)
+++ llvm/trunk/include/llvm/Object/XCOFFObjectFile.h Tue Aug 27 11:54:46 2019
@@ -112,6 +112,38 @@ struct XCOFFStringTable {
   const char *Data;
 };
 
+struct XCOFFCsectAuxEnt32 {
+  support::ubig32_t SectionLen;
+  support::ubig32_t ParameterHashIndex;
+  support::ubig16_t TypeChkSectNum;
+  uint8_t SymbolAlignmentAndType;
+  XCOFF::StorageMappingClass StorageMappingClass;
+  support::ubig32_t StabInfoIndex;
+  support::ubig16_t StabSectNum;
+};
+
+struct XCOFFFileAuxEnt {
+  typedef struct {
+    support::big32_t Magic; // Zero indicates name in string table.
+    support::ubig32_t Offset;
+    char NamePad[XCOFF::FileNamePadSize];
+  } NameInStrTblType;
+  union {
+    char Name[XCOFF::NameSize + XCOFF::FileNamePadSize];
+    NameInStrTblType NameInStrTbl;
+  };
+  XCOFF::CFileStringType Type;
+  uint8_t ReservedZeros[2];
+  uint8_t AuxType; // 64-bit XCOFF file only.
+};
+
+struct XCOFFSectAuxEntForStat {
+  support::ubig32_t SectionLength;
+  support::ubig16_t NumberOfRelocEnt;
+  support::ubig16_t NumberOfLineNum;
+  uint8_t Pad[10];
+};
+
 class XCOFFObjectFile : public ObjectFile {
 private:
   const void *FileHeader = nullptr;
@@ -131,18 +163,18 @@ private:
 
   const XCOFFSectionHeader32 *toSection32(DataRefImpl Ref) const;
   const XCOFFSectionHeader64 *toSection64(DataRefImpl Ref) const;
-  void checkSectionAddress(uintptr_t Addr, uintptr_t TableAddr) const;
   uintptr_t getSectionHeaderTableAddress() const;
+  uintptr_t getEndOfSymbolTableAddress() const;
 
   // This returns a pointer to the start of the storage for the name field of
   // the 32-bit or 64-bit SectionHeader struct. This string is *not* necessarily
   // null-terminated.
   const char *getSectionNameInternal(DataRefImpl Sec) const;
 
-  int32_t getSectionFlags(DataRefImpl Sec) const;
+  // This function returns string table entry.
+  Expected<StringRef> getStringTableEntry(uint32_t Offset) const;
 
   static bool isReservedSectionNumber(int16_t SectionNumber);
-  Expected<DataRefImpl> getSectionByNum(int16_t Num) const;
 
   // Constructor and "create" factory function. The constructor is only a thin
   // wrapper around the base constructor. The "create" function fills out the
@@ -160,6 +192,8 @@ private:
   friend Expected<std::unique_ptr<ObjectFile>>
   ObjectFile::createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType);
 
+  void checkSectionAddress(uintptr_t Addr, uintptr_t TableAddr) const;
+
 public:
   // Interface inherited from base classes.
   void moveSymbolNext(DataRefImpl &Symb) const override;
@@ -238,15 +272,41 @@ public:
   uint32_t getLogicalNumberOfSymbolTableEntries32() const;
 
   uint32_t getNumberOfSymbolTableEntries64() const;
+  uint32_t getSymbolIndex(uintptr_t SymEntPtr) const;
 
+  Expected<StringRef> getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const;
   uint16_t getOptionalHeaderSize() const;
   uint16_t getFlags() const;
 
   // Section header table related interfaces.
   ArrayRef<XCOFFSectionHeader32> sections32() const;
   ArrayRef<XCOFFSectionHeader64> sections64() const;
+
+  int32_t getSectionFlags(DataRefImpl Sec) const;
+  Expected<DataRefImpl> getSectionByNum(int16_t Num) const;
+
+  void checkSymbolEntryPointer(uintptr_t SymbolEntPtr) const;
 }; // XCOFFObjectFile
 
+class XCOFFSymbolRef {
+  const DataRefImpl SymEntDataRef;
+  const XCOFFObjectFile *const OwningObjectPtr;
+
+public:
+  XCOFFSymbolRef(DataRefImpl SymEntDataRef,
+                 const XCOFFObjectFile *OwningObjectPtr)
+      : SymEntDataRef(SymEntDataRef), OwningObjectPtr(OwningObjectPtr){};
+
+  XCOFF::StorageClass getStorageClass() const;
+  uint8_t getNumberOfAuxEntries() const;
+  const XCOFFCsectAuxEnt32 *getXCOFFCsectAuxEnt32() const;
+  uint16_t getType() const;
+  int16_t getSectionNumber() const;
+
+  bool hasCsectAuxEnt() const;
+  bool isFunction() const;
+};
+
 } // namespace object
 } // namespace llvm
 

Modified: llvm/trunk/lib/Object/XCOFFObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/XCOFFObjectFile.cpp?rev=370097&r1=370096&r2=370097&view=diff
==============================================================================
--- llvm/trunk/lib/Object/XCOFFObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/XCOFFObjectFile.cpp Tue Aug 27 11:54:46 2019
@@ -17,6 +17,11 @@
 namespace llvm {
 namespace object {
 
+enum {
+  FUNCTION_SYM = 0x20,
+  SYM_TYPE_MASK = 0x07
+};
+
 // Checks that [Ptr, Ptr + Size) bytes fall inside the memory buffer
 // 'M'. Returns a pointer to the underlying object on success.
 template <typename T>
@@ -37,7 +42,7 @@ template <typename T> static const T *vi
   return reinterpret_cast<const T *>(in);
 }
 
-static StringRef generateStringRef(const char *Name) {
+static StringRef generateXCOFFFixedNameStringRef(const char *Name) {
   auto NulCharPtr =
       static_cast<const char *>(memchr(Name, '\0', XCOFF::NameSize));
   return NulCharPtr ? StringRef(Name, NulCharPtr - Name)
@@ -79,6 +84,9 @@ XCOFFObjectFile::toSection64(DataRefImpl
 const XCOFFSymbolEntry *XCOFFObjectFile::toSymbolEntry(DataRefImpl Ref) const {
   assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
   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;
 }
@@ -108,23 +116,19 @@ XCOFFObjectFile::sectionHeaderTable64()
 void XCOFFObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
   const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
   SymEntPtr += SymEntPtr->NumberOfAuxEntries + 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));
+#endif
   Symb.p = reinterpret_cast<uintptr_t>(SymEntPtr);
 }
 
-Expected<StringRef> XCOFFObjectFile::getSymbolName(DataRefImpl Symb) const {
-  const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
-
-  if (SymEntPtr->NameInStrTbl.Magic != XCOFFSymbolEntry::NAME_IN_STR_TBL_MAGIC)
-    return generateStringRef(SymEntPtr->SymbolName);
-
-  // 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");
-
-  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 of 0 is a null or zero-length symbol
+Expected<StringRef>
+XCOFFObjectFile::getStringTableEntry(uint32_t Offset) const {
+  // The byte offset is relative to the start of the string table.
+  // A byte offset value of 0 is a null or zero-length symbol
   // name. A byte offset in the range 1 to 3 (inclusive) points into the length
   // field; as a soft-error recovery mechanism, we treat such cases as having an
   // offset of 0.
@@ -134,10 +138,32 @@ Expected<StringRef> XCOFFObjectFile::get
   if (StringTable.Data != nullptr && StringTable.Size > Offset)
     return (StringTable.Data + Offset);
 
-  return make_error<GenericBinaryError>("Symbol Name parse failed",
+  return make_error<GenericBinaryError>("Bad offset for string table entry",
                                         object_error::parse_failed);
 }
 
+Expected<StringRef>
+XCOFFObjectFile::getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const {
+  if (CFileEntPtr->NameInStrTbl.Magic !=
+      XCOFFSymbolEntry::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);
+}
+
 Expected<uint64_t> XCOFFObjectFile::getSymbolAddress(DataRefImpl Symb) const {
   uint64_t Result = 0;
   llvm_unreachable("Not yet implemented!");
@@ -145,6 +171,7 @@ Expected<uint64_t> XCOFFObjectFile::getS
 }
 
 uint64_t XCOFFObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
+  assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
   return toSymbolEntry(Symb)->Value;
 }
 
@@ -181,7 +208,7 @@ void XCOFFObjectFile::moveSectionNext(Da
 }
 
 Expected<StringRef> XCOFFObjectFile::getSectionName(DataRefImpl Sec) const {
-  return generateStringRef(getSectionNameInternal(Sec));
+  return generateXCOFFFixedNameStringRef(getSectionNameInternal(Sec));
 }
 
 uint64_t XCOFFObjectFile::getSectionAddress(DataRefImpl Sec) const {
@@ -389,7 +416,8 @@ XCOFFObjectFile::getSymbolSectionName(co
   default:
     Expected<DataRefImpl> SecRef = getSectionByNum(SectionNum);
     if (SecRef)
-      return generateStringRef(getSectionNameInternal(SecRef.get()));
+      return generateXCOFFFixedNameStringRef(
+          getSectionNameInternal(SecRef.get()));
     return SecRef.takeError();
   }
 }
@@ -437,6 +465,35 @@ uint32_t XCOFFObjectFile::getNumberOfSym
   return fileHeader64()->NumberOfSymTableEntries;
 }
 
+uintptr_t XCOFFObjectFile::getEndOfSymbolTableAddress() const {
+  uint32_t NumberOfSymTableEntries =
+      is64Bit() ? getNumberOfSymbolTableEntries64()
+                : getLogicalNumberOfSymbolTableEntries32();
+  return getWithOffset(reinterpret_cast<uintptr_t>(SymbolTblPtr),
+                       XCOFF::SymbolTableEntrySize * NumberOfSymTableEntries);
+}
+
+void XCOFFObjectFile::checkSymbolEntryPointer(uintptr_t SymbolEntPtr) const {
+  if (SymbolEntPtr < reinterpret_cast<uintptr_t>(SymbolTblPtr))
+    report_fatal_error("Symbol table entry is outside of symbol table.");
+
+  if (SymbolEntPtr >= getEndOfSymbolTableAddress())
+    report_fatal_error("Symbol table entry is outside of symbol table.");
+
+  ptrdiff_t Offset = reinterpret_cast<const char *>(SymbolEntPtr) -
+                     reinterpret_cast<const char *>(SymbolTblPtr);
+
+  if (Offset % XCOFF::SymbolTableEntrySize != 0)
+    report_fatal_error(
+        "Symbol table entry position is not valid inside of symbol table.");
+}
+
+uint32_t XCOFFObjectFile::getSymbolIndex(uintptr_t SymbolEntPtr) const {
+  return (reinterpret_cast<const char *>(SymbolEntPtr) -
+          reinterpret_cast<const char *>(SymbolTblPtr)) /
+         XCOFF::SymbolTableEntrySize;
+}
+
 uint16_t XCOFFObjectFile::getFlags() const {
   return is64Bit() ? fileHeader64()->Flags : fileHeader32()->Flags;
 }
@@ -568,11 +625,77 @@ ObjectFile::createXCOFFObjectFile(Memory
 }
 
 StringRef XCOFFSectionHeader32::getName() const {
-  return generateStringRef(Name);
+  return generateXCOFFFixedNameStringRef(Name);
 }
 
 StringRef XCOFFSectionHeader64::getName() const {
-  return generateStringRef(Name);
+  return generateXCOFFFixedNameStringRef(Name);
+}
+
+XCOFF::StorageClass XCOFFSymbolRef::getStorageClass() const {
+  return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->StorageClass;
+}
+
+uint8_t XCOFFSymbolRef::getNumberOfAuxEntries() const {
+  return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->NumberOfAuxEntries;
+}
+
+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.");
+
+  // In XCOFF32, the csect auxilliary entry is always the last auxiliary
+  // entry for the symbol.
+  uintptr_t AuxAddr = getWithOffset(
+      SymEntDataRef.p, XCOFF::SymbolTableEntrySize * getNumberOfAuxEntries());
+
+#ifndef NDEBUG
+  OwningObjectPtr->checkSymbolEntryPointer(AuxAddr);
+#endif
+
+  return reinterpret_cast<const XCOFFCsectAuxEnt32 *>(AuxAddr);
+}
+
+uint16_t XCOFFSymbolRef::getType() const {
+  return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->SymbolType;
+}
+
+int16_t XCOFFSymbolRef::getSectionNumber() const {
+  return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->SectionNumber;
+}
+
+bool XCOFFSymbolRef::hasCsectAuxEnt() 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.");
+
+  if (getType() & FUNCTION_SYM)
+    return true;
+
+  if (!hasCsectAuxEnt())
+    return false;
+
+  const XCOFFCsectAuxEnt32 *CsectAuxEnt = getXCOFFCsectAuxEnt32();
+
+  // A function definition should be a label definition.
+  if ((CsectAuxEnt->SymbolAlignmentAndType & SYM_TYPE_MASK) != XCOFF::XTY_LD)
+    return false;
+
+  if (CsectAuxEnt->StorageMappingClass != XCOFF::XMC_PR)
+    return false;
+
+  int16_t SectNum = getSectionNumber();
+  Expected<DataRefImpl> SI = OwningObjectPtr->getSectionByNum(SectNum);
+  if (!SI)
+    return false;
+
+  return (OwningObjectPtr->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT);
 }
 
 } // namespace object

Added: llvm/trunk/test/tools/llvm-readobj/Inputs/aix_xcoff_xlc_test8.o
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/aix_xcoff_xlc_test8.o?rev=370097&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/llvm-readobj/Inputs/aix_xcoff_xlc_test8.o
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/llvm-readobj/xcoff-symbols.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/xcoff-symbols.test?rev=370097&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/xcoff-symbols.test (added)
+++ llvm/trunk/test/tools/llvm-readobj/xcoff-symbols.test Tue Aug 27 11:54:46 2019
@@ -0,0 +1,446 @@
+# This file tests the ability of llvm-readobj to display the symbol table for a
+# 32-bit XCOFF object file.
+RUN: llvm-readobj --symbols %p/Inputs/aix_xcoff_xlc_test8.o | \
+RUN: FileCheck --check-prefix=SYMBOL32 %s
+
+SYMBOL32: File: {{.*}}aix_xcoff_xlc_test8.o
+SYMBOL32-NEXT: Format: aixcoff-rs6000
+SYMBOL32-NEXT: Arch: powerpc
+SYMBOL32-NEXT: AddressSize: 32bit
+SYMBOL32-NEXT: Symbols [
+SYMBOL32-NEXT:   Symbol {
+SYMBOL32-NEXT:     Index: 0
+SYMBOL32-NEXT:     Name: .file
+SYMBOL32-NEXT:     Value (SymbolTableIndex): 0x0
+SYMBOL32-NEXT:     Section: N_DEBUG
+SYMBOL32-NEXT:     Source Language ID: TB_C (0x0)
+SYMBOL32-NEXT:     CPU Version ID: TCPU_COM (0x3)
+SYMBOL32-NEXT:     StorageClass: C_FILE (0x67)
+SYMBOL32-NEXT:     NumberOfAuxEntries: 3
+SYMBOL32-NEXT:     File Auxiliary Entry {
+SYMBOL32-NEXT:       Index: 1
+SYMBOL32-NEXT:       Name: test8.c
+SYMBOL32-NEXT:       Type: XFT_FN (0x0)
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:     File Auxiliary Entry {
+SYMBOL32-NEXT:       Index: 2
+SYMBOL32-NEXT:       Name: Sun Apr 28 15:56:49 2019
+SYMBOL32-NEXT:       Type: XFT_CT (0x1)
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:     File Auxiliary Entry {
+SYMBOL32-NEXT:       Index: 3
+SYMBOL32-NEXT:       Name: IBM XL C for AIX, Version 16.1.0.2
+SYMBOL32-NEXT:       Type: XFT_CV (0x2)
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:   }
+SYMBOL32-NEXT:   Symbol {
+SYMBOL32-NEXT:     Index: 4
+SYMBOL32-NEXT:     Name: .text
+SYMBOL32-NEXT:     Value (RelocatableAddress): 0x0
+SYMBOL32-NEXT:     Section: .text
+SYMBOL32-NEXT:     Type: 0x0
+SYMBOL32-NEXT:     StorageClass: C_STAT (0x3)
+SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+SYMBOL32-NEXT:     Sect Auxiliary Entry For Stat {
+SYMBOL32-NEXT:       Index: 5
+SYMBOL32-NEXT:       SectionLength: 256
+SYMBOL32-NEXT:       NumberOfRelocEnt: 4
+SYMBOL32-NEXT:       NumberOfLineNum: 0
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:   }
+SYMBOL32-NEXT:   Symbol {
+SYMBOL32-NEXT:     Index: 6
+SYMBOL32-NEXT:     Name: .data
+SYMBOL32-NEXT:     Value (RelocatableAddress): 0x100
+SYMBOL32-NEXT:     Section: .data
+SYMBOL32-NEXT:     Type: 0x0
+SYMBOL32-NEXT:     StorageClass: C_STAT (0x3)
+SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+SYMBOL32-NEXT:     Sect Auxiliary Entry For Stat {
+SYMBOL32-NEXT:       Index: 7
+SYMBOL32-NEXT:       SectionLength: 60
+SYMBOL32-NEXT:       NumberOfRelocEnt: 11
+SYMBOL32-NEXT:       NumberOfLineNum: 0
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:   }
+SYMBOL32-NEXT:   Symbol {
+SYMBOL32-NEXT:     Index: 8
+SYMBOL32-NEXT:     Name: .bss
+SYMBOL32-NEXT:     Value (RelocatableAddress): 0x13C
+SYMBOL32-NEXT:     Section: .bss
+SYMBOL32-NEXT:     Type: 0x0
+SYMBOL32-NEXT:     StorageClass: C_STAT (0x3)
+SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+SYMBOL32-NEXT:     Sect Auxiliary Entry For Stat {
+SYMBOL32-NEXT:       Index: 9
+SYMBOL32-NEXT:       SectionLength: 4
+SYMBOL32-NEXT:       NumberOfRelocEnt: 0
+SYMBOL32-NEXT:       NumberOfLineNum: 0
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:   }
+SYMBOL32-NEXT:   Symbol {
+SYMBOL32-NEXT:     Index: 10
+SYMBOL32-NEXT:     Name:
+SYMBOL32-NEXT:     Value (RelocatableAddress): 0x0
+SYMBOL32-NEXT:     Section: .text
+SYMBOL32-NEXT:     Type: 0x0
+SYMBOL32-NEXT:     StorageClass: C_HIDEXT (0x6B)
+SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+SYMBOL32-NEXT:     CSECT Auxiliary Entry {
+SYMBOL32-NEXT:       Index: 11
+SYMBOL32-NEXT:       SectionLen: 256
+SYMBOL32-NEXT:       ParameterHashIndex: 0x0
+SYMBOL32-NEXT:       TypeChkSectNum: 0x0
+SYMBOL32-NEXT:       SymbolAlignmentLog2: 7
+SYMBOL32-NEXT:       SymbolType: XTY_SD (0x1)
+SYMBOL32-NEXT:       StorageMappingClass: XMC_PR (0x0)
+SYMBOL32-NEXT:       StabInfoIndex: 0x0
+SYMBOL32-NEXT:       StabSectNum: 0x0
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:   }
+SYMBOL32-NEXT:   Symbol {
+SYMBOL32-NEXT:     Index: 12
+SYMBOL32-NEXT:     Name: .fun1
+SYMBOL32-NEXT:     Value (RelocatableAddress): 0x0
+SYMBOL32-NEXT:     Section: .text
+SYMBOL32-NEXT:     Type: 0x20
+SYMBOL32-NEXT:     StorageClass: C_EXT (0x2)
+SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+SYMBOL32-NEXT:     CSECT Auxiliary Entry {
+SYMBOL32-NEXT:       Index: 13
+SYMBOL32-NEXT:       ContainingCsectSymbolIndex: 10
+SYMBOL32-NEXT:       ParameterHashIndex: 0x0
+SYMBOL32-NEXT:       TypeChkSectNum: 0x0
+SYMBOL32-NEXT:       SymbolAlignmentLog2: 0
+SYMBOL32-NEXT:       SymbolType: XTY_LD (0x2)
+SYMBOL32-NEXT:       StorageMappingClass: XMC_PR (0x0)
+SYMBOL32-NEXT:       StabInfoIndex: 0x0
+SYMBOL32-NEXT:       StabSectNum: 0x0
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:   }
+SYMBOL32-NEXT:   Symbol {
+SYMBOL32-NEXT:     Index: 14
+SYMBOL32-NEXT:     Name: .main
+SYMBOL32-NEXT:     Value (RelocatableAddress): 0x60
+SYMBOL32-NEXT:     Section: .text
+SYMBOL32-NEXT:     Type: 0x20
+SYMBOL32-NEXT:     StorageClass: C_EXT (0x2)
+SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+SYMBOL32-NEXT:     CSECT Auxiliary Entry {
+SYMBOL32-NEXT:       Index: 15
+SYMBOL32-NEXT:       ContainingCsectSymbolIndex: 10
+SYMBOL32-NEXT:       ParameterHashIndex: 0x0
+SYMBOL32-NEXT:       TypeChkSectNum: 0x0
+SYMBOL32-NEXT:       SymbolAlignmentLog2: 0
+SYMBOL32-NEXT:       SymbolType: XTY_LD (0x2)
+SYMBOL32-NEXT:       StorageMappingClass: XMC_PR (0x0)
+SYMBOL32-NEXT:       StabInfoIndex: 0x0
+SYMBOL32-NEXT:       StabSectNum: 0x0
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:   }
+SYMBOL32-NEXT:   Symbol {
+SYMBOL32-NEXT:     Index: 16
+SYMBOL32-NEXT:     Name: TOC
+SYMBOL32-NEXT:     Value (RelocatableAddress): 0x100
+SYMBOL32-NEXT:     Section: .data
+SYMBOL32-NEXT:     Type: 0x0
+SYMBOL32-NEXT:     StorageClass: C_HIDEXT (0x6B)
+SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+SYMBOL32-NEXT:     CSECT Auxiliary Entry {
+SYMBOL32-NEXT:       Index: 17
+SYMBOL32-NEXT:       SectionLen: 0
+SYMBOL32-NEXT:       ParameterHashIndex: 0x0
+SYMBOL32-NEXT:       TypeChkSectNum: 0x0
+SYMBOL32-NEXT:       SymbolAlignmentLog2: 2
+SYMBOL32-NEXT:       SymbolType: XTY_SD (0x1)
+SYMBOL32-NEXT:       StorageMappingClass: XMC_TC0 (0xF)
+SYMBOL32-NEXT:       StabInfoIndex: 0x0
+SYMBOL32-NEXT:       StabSectNum: 0x0
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:   }
+SYMBOL32-NEXT:   Symbol {
+SYMBOL32-NEXT:     Index: 18
+SYMBOL32-NEXT:     Name:
+SYMBOL32-NEXT:     Value (RelocatableAddress): 0x114
+SYMBOL32-NEXT:     Section: .data
+SYMBOL32-NEXT:     Type: 0x0
+SYMBOL32-NEXT:     StorageClass: C_HIDEXT (0x6B)
+SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+SYMBOL32-NEXT:     CSECT Auxiliary Entry {
+SYMBOL32-NEXT:       Index: 19
+SYMBOL32-NEXT:       SectionLen: 4
+SYMBOL32-NEXT:       ParameterHashIndex: 0x0
+SYMBOL32-NEXT:       TypeChkSectNum: 0x0
+SYMBOL32-NEXT:       SymbolAlignmentLog2: 2
+SYMBOL32-NEXT:       SymbolType: XTY_SD (0x1)
+SYMBOL32-NEXT:       StorageMappingClass: XMC_TC (0x3)
+SYMBOL32-NEXT:       StabInfoIndex: 0x0
+SYMBOL32-NEXT:       StabSectNum: 0x0
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:   }
+SYMBOL32-NEXT:   Symbol {
+SYMBOL32-NEXT:     Index: 20
+SYMBOL32-NEXT:     Name:
+SYMBOL32-NEXT:     Value (RelocatableAddress): 0x134
+SYMBOL32-NEXT:     Section: .data
+SYMBOL32-NEXT:     Type: 0x0
+SYMBOL32-NEXT:     StorageClass: C_HIDEXT (0x6B)
+SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+SYMBOL32-NEXT:     CSECT Auxiliary Entry {
+SYMBOL32-NEXT:       Index: 21
+SYMBOL32-NEXT:       SectionLen: 5
+SYMBOL32-NEXT:       ParameterHashIndex: 0x0
+SYMBOL32-NEXT:       TypeChkSectNum: 0x0
+SYMBOL32-NEXT:       SymbolAlignmentLog2: 3
+SYMBOL32-NEXT:       SymbolType: XTY_SD (0x1)
+SYMBOL32-NEXT:       StorageMappingClass: XMC_RO (0x1)
+SYMBOL32-NEXT:       StabInfoIndex: 0x0
+SYMBOL32-NEXT:       StabSectNum: 0x0
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:   }
+SYMBOL32-NEXT:   Symbol {
+SYMBOL32-NEXT:     Index: 22
+SYMBOL32-NEXT:     Name: _$STATIC_BSS
+SYMBOL32-NEXT:     Value (RelocatableAddress): 0x13C
+SYMBOL32-NEXT:     Section: .bss
+SYMBOL32-NEXT:     Type: 0x0
+SYMBOL32-NEXT:     StorageClass: C_HIDEXT (0x6B)
+SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+SYMBOL32-NEXT:     CSECT Auxiliary Entry {
+SYMBOL32-NEXT:       Index: 23
+SYMBOL32-NEXT:       SectionLen: 4
+SYMBOL32-NEXT:       ParameterHashIndex: 0x0
+SYMBOL32-NEXT:       TypeChkSectNum: 0x0
+SYMBOL32-NEXT:       SymbolAlignmentLog2: 2
+SYMBOL32-NEXT:       SymbolType: XTY_CM (0x3)
+SYMBOL32-NEXT:       StorageMappingClass: XMC_RW (0x5)
+SYMBOL32-NEXT:       StabInfoIndex: 0x0
+SYMBOL32-NEXT:       StabSectNum: 0x0
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:   }
+SYMBOL32-NEXT:   Symbol {
+SYMBOL32-NEXT:     Index: 24
+SYMBOL32-NEXT:     Name: _$STATIC_BSS
+SYMBOL32-NEXT:     Value (RelocatableAddress): 0x104
+SYMBOL32-NEXT:     Section: .data
+SYMBOL32-NEXT:     Type: 0x0
+SYMBOL32-NEXT:     StorageClass: C_HIDEXT (0x6B)
+SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+SYMBOL32-NEXT:     CSECT Auxiliary Entry {
+SYMBOL32-NEXT:       Index: 25
+SYMBOL32-NEXT:       SectionLen: 4
+SYMBOL32-NEXT:       ParameterHashIndex: 0x0
+SYMBOL32-NEXT:       TypeChkSectNum: 0x0
+SYMBOL32-NEXT:       SymbolAlignmentLog2: 2
+SYMBOL32-NEXT:       SymbolType: XTY_SD (0x1)
+SYMBOL32-NEXT:       StorageMappingClass: XMC_TC (0x3)
+SYMBOL32-NEXT:       StabInfoIndex: 0x0
+SYMBOL32-NEXT:       StabSectNum: 0x0
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:   }
+SYMBOL32-NEXT:   Symbol {
+SYMBOL32-NEXT:     Index: 26
+SYMBOL32-NEXT:     Name: fun1
+SYMBOL32-NEXT:     Value (RelocatableAddress): 0x118
+SYMBOL32-NEXT:     Section: .data
+SYMBOL32-NEXT:     Type: 0x0
+SYMBOL32-NEXT:     StorageClass: C_EXT (0x2)
+SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+SYMBOL32-NEXT:     CSECT Auxiliary Entry {
+SYMBOL32-NEXT:       Index: 27
+SYMBOL32-NEXT:       SectionLen: 12
+SYMBOL32-NEXT:       ParameterHashIndex: 0x0
+SYMBOL32-NEXT:       TypeChkSectNum: 0x0
+SYMBOL32-NEXT:       SymbolAlignmentLog2: 2
+SYMBOL32-NEXT:       SymbolType: XTY_SD (0x1)
+SYMBOL32-NEXT:       StorageMappingClass: XMC_DS (0xA)
+SYMBOL32-NEXT:       StabInfoIndex: 0x0
+SYMBOL32-NEXT:       StabSectNum: 0x0
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:   }
+SYMBOL32-NEXT:   Symbol {
+SYMBOL32-NEXT:     Index: 28
+SYMBOL32-NEXT:     Name: fun1
+SYMBOL32-NEXT:     Value (RelocatableAddress): 0x100
+SYMBOL32-NEXT:     Section: .data
+SYMBOL32-NEXT:     Type: 0x0
+SYMBOL32-NEXT:     StorageClass: C_HIDEXT (0x6B)
+SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+SYMBOL32-NEXT:     CSECT Auxiliary Entry {
+SYMBOL32-NEXT:       Index: 29
+SYMBOL32-NEXT:       SectionLen: 4
+SYMBOL32-NEXT:       ParameterHashIndex: 0x0
+SYMBOL32-NEXT:       TypeChkSectNum: 0x0
+SYMBOL32-NEXT:       SymbolAlignmentLog2: 2
+SYMBOL32-NEXT:       SymbolType: XTY_SD (0x1)
+SYMBOL32-NEXT:       StorageMappingClass: XMC_TC (0x3)
+SYMBOL32-NEXT:       StabInfoIndex: 0x0
+SYMBOL32-NEXT:       StabSectNum: 0x0
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:   }
+SYMBOL32-NEXT:   Symbol {
+SYMBOL32-NEXT:     Index: 30
+SYMBOL32-NEXT:     Name: p
+SYMBOL32-NEXT:     Value (RelocatableAddress): 0x130
+SYMBOL32-NEXT:     Section: .data
+SYMBOL32-NEXT:     Type: 0x0
+SYMBOL32-NEXT:     StorageClass: C_EXT (0x2)
+SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+SYMBOL32-NEXT:     CSECT Auxiliary Entry {
+SYMBOL32-NEXT:       Index: 31
+SYMBOL32-NEXT:       SectionLen: 4
+SYMBOL32-NEXT:       ParameterHashIndex: 0x0
+SYMBOL32-NEXT:       TypeChkSectNum: 0x0
+SYMBOL32-NEXT:       SymbolAlignmentLog2: 2
+SYMBOL32-NEXT:       SymbolType: XTY_SD (0x1)
+SYMBOL32-NEXT:       StorageMappingClass: XMC_RW (0x5)
+SYMBOL32-NEXT:       StabInfoIndex: 0x0
+SYMBOL32-NEXT:       StabSectNum: 0x0
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:   }
+SYMBOL32-NEXT:   Symbol {
+SYMBOL32-NEXT:     Index: 32
+SYMBOL32-NEXT:     Name: p
+SYMBOL32-NEXT:     Value (RelocatableAddress): 0x108
+SYMBOL32-NEXT:     Section: .data
+SYMBOL32-NEXT:     Type: 0x0
+SYMBOL32-NEXT:     StorageClass: C_HIDEXT (0x6B)
+SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+SYMBOL32-NEXT:     CSECT Auxiliary Entry {
+SYMBOL32-NEXT:       Index: 33
+SYMBOL32-NEXT:       SectionLen: 4
+SYMBOL32-NEXT:       ParameterHashIndex: 0x0
+SYMBOL32-NEXT:       TypeChkSectNum: 0x0
+SYMBOL32-NEXT:       SymbolAlignmentLog2: 2
+SYMBOL32-NEXT:       SymbolType: XTY_SD (0x1)
+SYMBOL32-NEXT:       StorageMappingClass: XMC_TC (0x3)
+SYMBOL32-NEXT:       StabInfoIndex: 0x0
+SYMBOL32-NEXT:       StabSectNum: 0x0
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:   }
+SYMBOL32-NEXT:   Symbol {
+SYMBOL32-NEXT:     Index: 34
+SYMBOL32-NEXT:     Name: main
+SYMBOL32-NEXT:     Value (RelocatableAddress): 0x124
+SYMBOL32-NEXT:     Section: .data
+SYMBOL32-NEXT:     Type: 0x0
+SYMBOL32-NEXT:     StorageClass: C_EXT (0x2)
+SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+SYMBOL32-NEXT:     CSECT Auxiliary Entry {
+SYMBOL32-NEXT:       Index: 35
+SYMBOL32-NEXT:       SectionLen: 12
+SYMBOL32-NEXT:       ParameterHashIndex: 0x0
+SYMBOL32-NEXT:       TypeChkSectNum: 0x0
+SYMBOL32-NEXT:       SymbolAlignmentLog2: 2
+SYMBOL32-NEXT:       SymbolType: XTY_SD (0x1)
+SYMBOL32-NEXT:       StorageMappingClass: XMC_DS (0xA)
+SYMBOL32-NEXT:       StabInfoIndex: 0x0
+SYMBOL32-NEXT:       StabSectNum: 0x0
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:   }
+SYMBOL32-NEXT:   Symbol {
+SYMBOL32-NEXT:     Index: 36
+SYMBOL32-NEXT:     Name: main
+SYMBOL32-NEXT:     Value (RelocatableAddress): 0x10C
+SYMBOL32-NEXT:     Section: .data
+SYMBOL32-NEXT:     Type: 0x0
+SYMBOL32-NEXT:     StorageClass: C_HIDEXT (0x6B)
+SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+SYMBOL32-NEXT:     CSECT Auxiliary Entry {
+SYMBOL32-NEXT:       Index: 37
+SYMBOL32-NEXT:       SectionLen: 4
+SYMBOL32-NEXT:       ParameterHashIndex: 0x0
+SYMBOL32-NEXT:       TypeChkSectNum: 0x0
+SYMBOL32-NEXT:       SymbolAlignmentLog2: 2
+SYMBOL32-NEXT:       SymbolType: XTY_SD (0x1)
+SYMBOL32-NEXT:       StorageMappingClass: XMC_TC (0x3)
+SYMBOL32-NEXT:       StabInfoIndex: 0x0
+SYMBOL32-NEXT:       StabSectNum: 0x0
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:   }
+SYMBOL32-NEXT:   Symbol {
+SYMBOL32-NEXT:     Index: 38
+SYMBOL32-NEXT:     Name: i
+SYMBOL32-NEXT:     Value (RelocatableAddress): 0x0
+SYMBOL32-NEXT:     Section: N_UNDEF
+SYMBOL32-NEXT:     Type: 0x0
+SYMBOL32-NEXT:     StorageClass: C_EXT (0x2)
+SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+SYMBOL32-NEXT:     CSECT Auxiliary Entry {
+SYMBOL32-NEXT:       Index: 39
+SYMBOL32-NEXT:       SectionLen: 0
+SYMBOL32-NEXT:       ParameterHashIndex: 0x0
+SYMBOL32-NEXT:       TypeChkSectNum: 0x0
+SYMBOL32-NEXT:       SymbolAlignmentLog2: 0
+SYMBOL32-NEXT:       SymbolType: XTY_ER (0x0)
+SYMBOL32-NEXT:       StorageMappingClass: XMC_UA (0x4)
+SYMBOL32-NEXT:       StabInfoIndex: 0x0
+SYMBOL32-NEXT:       StabSectNum: 0x0
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:   }
+SYMBOL32-NEXT:   Symbol {
+SYMBOL32-NEXT:     Index: 40
+SYMBOL32-NEXT:     Name: i
+SYMBOL32-NEXT:     Value (RelocatableAddress): 0x110
+SYMBOL32-NEXT:     Section: .data
+SYMBOL32-NEXT:     Type: 0x0
+SYMBOL32-NEXT:     StorageClass: C_HIDEXT (0x6B)
+SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+SYMBOL32-NEXT:     CSECT Auxiliary Entry {
+SYMBOL32-NEXT:       Index: 41
+SYMBOL32-NEXT:       SectionLen: 4
+SYMBOL32-NEXT:       ParameterHashIndex: 0x0
+SYMBOL32-NEXT:       TypeChkSectNum: 0x0
+SYMBOL32-NEXT:       SymbolAlignmentLog2: 2
+SYMBOL32-NEXT:       SymbolType: XTY_SD (0x1)
+SYMBOL32-NEXT:       StorageMappingClass: XMC_TC (0x3)
+SYMBOL32-NEXT:       StabInfoIndex: 0x0
+SYMBOL32-NEXT:       StabSectNum: 0x0
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:   }
+SYMBOL32-NEXT:   Symbol {
+SYMBOL32-NEXT:     Index: 42
+SYMBOL32-NEXT:     Name: .fun
+SYMBOL32-NEXT:     Value (RelocatableAddress): 0x0
+SYMBOL32-NEXT:     Section: N_UNDEF
+SYMBOL32-NEXT:     Type: 0x0
+SYMBOL32-NEXT:     StorageClass: C_EXT (0x2)
+SYMBOL32-NEXT:     NumberOfAuxEntries: 1
+SYMBOL32-NEXT:     CSECT Auxiliary Entry {
+SYMBOL32-NEXT:       Index: 43
+SYMBOL32-NEXT:       SectionLen: 0
+SYMBOL32-NEXT:       ParameterHashIndex: 0x0
+SYMBOL32-NEXT:       TypeChkSectNum: 0x0
+SYMBOL32-NEXT:       SymbolAlignmentLog2: 0
+SYMBOL32-NEXT:       SymbolType: XTY_ER (0x0)
+SYMBOL32-NEXT:       StorageMappingClass: XMC_PR (0x0)
+SYMBOL32-NEXT:       StabInfoIndex: 0x0
+SYMBOL32-NEXT:       StabSectNum: 0x0
+SYMBOL32-NEXT:     }
+SYMBOL32-NEXT:   }
+SYMBOL32-NEXT: ]
+
+# 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 -c test8.c -o aix_xcoff_xlc_test8.o

Modified: llvm/trunk/tools/llvm-readobj/XCOFFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/XCOFFDumper.cpp?rev=370097&r1=370096&r2=370097&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/XCOFFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/XCOFFDumper.cpp Tue Aug 27 11:54:46 2019
@@ -22,6 +22,12 @@ using namespace object;
 namespace {
 
 class XCOFFDumper : public ObjDumper {
+  enum {
+    SymbolTypeMask = 0x07,
+    SymbolAlignmentMask = 0xF8,
+    SymbolAlignmentBitOffset = 3
+  };
+
 public:
   XCOFFDumper(const XCOFFObjectFile &Obj, ScopedPrinter &Writer)
       : ObjDumper(Writer), Obj(Obj) {}
@@ -37,11 +43,14 @@ public:
 
 private:
   template <typename T> void printSectionHeaders(ArrayRef<T> Sections);
-
-  const XCOFFObjectFile &Obj;
+  void printFileAuxEnt(const XCOFFFileAuxEnt *AuxEntPtr);
+  void printCsectAuxEnt32(const XCOFFCsectAuxEnt32 *AuxEntPtr);
+  void printSectAuxEntForStat(const XCOFFSectAuxEntForStat *AuxEntPtr);
+  void printSymbol(const SymbolRef &);
 
   // Least significant 3 bits are reserved.
   static constexpr unsigned SectionFlagsReservedMask = 0x7;
+  const XCOFFObjectFile &Obj;
 };
 } // anonymous namespace
 
@@ -103,8 +112,260 @@ void XCOFFDumper::printRelocations() {
   llvm_unreachable("Unimplemented functionality for XCOFFDumper");
 }
 
+static const EnumEntry<XCOFF::CFileStringType> FileStringType[] = {
+#define ECase(X)                                                               \
+  { #X, XCOFF::X }
+    ECase(XFT_FN), ECase(XFT_CT), ECase(XFT_CV), ECase(XFT_CD)
+#undef ECase
+};
+
+void XCOFFDumper::printFileAuxEnt(const XCOFFFileAuxEnt *AuxEntPtr) {
+  if (Obj.is64Bit())
+    report_fatal_error(
+        "Printing for File Auxiliary Entry in 64-bit is unimplemented.");
+  StringRef FileName =
+      unwrapOrError(Obj.getFileName(), Obj.getCFileName(AuxEntPtr));
+  DictScope SymDs(W, "File Auxiliary Entry");
+  W.printNumber("Index",
+                Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
+  W.printString("Name", FileName);
+  W.printEnum("Type", static_cast<uint8_t>(AuxEntPtr->Type),
+              makeArrayRef(FileStringType));
+}
+
+static const EnumEntry<XCOFF::StorageMappingClass> CsectStorageMappingClass[] =
+    {
+#define ECase(X)                                                               \
+  { #X, XCOFF::X }
+        ECase(XMC_PR),   ECase(XMC_RO),     ECase(XMC_DB),
+        ECase(XMC_GL),   ECase(XMC_XO),     ECase(XMC_SV),
+        ECase(XMC_SV64), ECase(XMC_SV3264), ECase(XMC_TI),
+        ECase(XMC_TB),   ECase(XMC_RW),     ECase(XMC_TC0),
+        ECase(XMC_TC),   ECase(XMC_TD),     ECase(XMC_DS),
+        ECase(XMC_UA),   ECase(XMC_BS),     ECase(XMC_UC),
+        ECase(XMC_TL),   ECase(XMC_TE)
+#undef ECase
+};
+
+static const EnumEntry<XCOFF::SymbolType> CsectSymbolTypeClass[] = {
+#define ECase(X)                                                               \
+  { #X, XCOFF::X }
+    ECase(XTY_ER), ECase(XTY_SD), ECase(XTY_LD), ECase(XTY_CM)
+#undef ECase
+};
+
+void XCOFFDumper::printCsectAuxEnt32(const XCOFFCsectAuxEnt32 *AuxEntPtr) {
+  assert(!Obj.is64Bit() && "32-bit interface called on 64-bit object file.");
+
+  DictScope SymDs(W, "CSECT Auxiliary Entry");
+  W.printNumber("Index",
+                Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
+  if ((AuxEntPtr->SymbolAlignmentAndType & SymbolTypeMask) == XCOFF::XTY_LD)
+    W.printNumber("ContainingCsectSymbolIndex", AuxEntPtr->SectionLen);
+  else
+    W.printNumber("SectionLen", AuxEntPtr->SectionLen);
+  W.printHex("ParameterHashIndex", AuxEntPtr->ParameterHashIndex);
+  W.printHex("TypeChkSectNum", AuxEntPtr->TypeChkSectNum);
+  // Print out symbol alignment and type.
+  W.printNumber("SymbolAlignmentLog2",
+                (AuxEntPtr->SymbolAlignmentAndType & SymbolAlignmentMask) >>
+                    SymbolAlignmentBitOffset);
+  W.printEnum("SymbolType", AuxEntPtr->SymbolAlignmentAndType & SymbolTypeMask,
+              makeArrayRef(CsectSymbolTypeClass));
+  W.printEnum("StorageMappingClass",
+              static_cast<uint8_t>(AuxEntPtr->StorageMappingClass),
+              makeArrayRef(CsectStorageMappingClass));
+  W.printHex("StabInfoIndex", AuxEntPtr->StabInfoIndex);
+  W.printHex("StabSectNum", AuxEntPtr->StabSectNum);
+}
+
+void XCOFFDumper::printSectAuxEntForStat(
+    const XCOFFSectAuxEntForStat *AuxEntPtr) {
+  assert(!Obj.is64Bit() && "32-bit interface called on 64-bit object file.");
+
+  DictScope SymDs(W, "Sect Auxiliary Entry For Stat");
+  W.printNumber("Index",
+                Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
+  W.printNumber("SectionLength", AuxEntPtr->SectionLength);
+
+  // Unlike the corresponding fields in the section header, NumberOfRelocEnt
+  // and NumberOfLineNum do not handle values greater than 65535.
+  W.printNumber("NumberOfRelocEnt", AuxEntPtr->NumberOfRelocEnt);
+  W.printNumber("NumberOfLineNum", AuxEntPtr->NumberOfLineNum);
+}
+
+static const EnumEntry<XCOFF::StorageClass> SymStorageClass[] = {
+#define ECase(X)                                                               \
+  { #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
+};
+
+static StringRef GetSymbolValueName(XCOFF::StorageClass SC) {
+  switch (SC) {
+  case XCOFF::C_EXT:
+  case XCOFF::C_WEAKEXT:
+  case XCOFF::C_HIDEXT:
+  case XCOFF::C_STAT:
+    return "Value (RelocatableAddress)";
+  case XCOFF::C_FILE:
+    return "Value (SymbolTableIndex)";
+  case XCOFF::C_FCN:
+  case XCOFF::C_BLOCK:
+  case XCOFF::C_FUN:
+  case XCOFF::C_STSYM:
+  case XCOFF::C_BINCL:
+  case XCOFF::C_EINCL:
+  case XCOFF::C_INFO:
+  case XCOFF::C_BSTAT:
+  case XCOFF::C_LSYM:
+  case XCOFF::C_PSYM:
+  case XCOFF::C_RPSYM:
+  case XCOFF::C_RSYM:
+  case XCOFF::C_ECOML:
+  case XCOFF::C_DWARF:
+    assert(false && "This StorageClass for the symbol is not yet implemented.");
+  default:
+    return "Value";
+  }
+}
+
+static const EnumEntry<XCOFF::CFileLangId> CFileLangIdClass[] = {
+#define ECase(X)                                                               \
+  { #X, XCOFF::X }
+    ECase(TB_C), ECase(TB_CPLUSPLUS)
+#undef ECase
+};
+
+static const EnumEntry<XCOFF::CFileCpuId> CFileCpuIdClass[] = {
+#define ECase(X)                                                               \
+  { #X, XCOFF::X }
+    ECase(TCPU_PPC64), ECase(TCPU_COM), ECase(TCPU_970)
+#undef ECase
+};
+
+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 XCOFFSymRef(SymbolDRI, &Obj);
+  uint8_t NumberOfAuxEntries = XCOFFSymRef.getNumberOfAuxEntries();
+
+  DictScope SymDs(W, "Symbol");
+
+  StringRef SymbolName =
+      unwrapOrError(Obj.getFileName(), Obj.getSymbolName(SymbolDRI));
+
+  W.printNumber("Index",
+                Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(SymbolEntPtr)));
+  W.printString("Name", SymbolName);
+  W.printHex(GetSymbolValueName(SymbolEntPtr->StorageClass),
+             SymbolEntPtr->Value);
+
+  StringRef SectionName =
+      unwrapOrError(Obj.getFileName(), Obj.getSymbolSectionName(SymbolEntPtr));
+
+  W.printString("Section", SectionName);
+  if (XCOFFSymRef.getStorageClass() == XCOFF::C_FILE) {
+    W.printEnum("Source Language ID",
+                SymbolEntPtr->CFileLanguageIdAndTypeId.LanguageId,
+                makeArrayRef(CFileLangIdClass));
+    W.printEnum("CPU Version ID",
+                SymbolEntPtr->CFileLanguageIdAndTypeId.CpuTypeId,
+                makeArrayRef(CFileCpuIdClass));
+  } else
+    W.printHex("Type", SymbolEntPtr->SymbolType);
+
+  W.printEnum("StorageClass", static_cast<uint8_t>(SymbolEntPtr->StorageClass),
+              makeArrayRef(SymStorageClass));
+  W.printNumber("NumberOfAuxEntries", SymbolEntPtr->NumberOfAuxEntries);
+
+  if (NumberOfAuxEntries == 0)
+    return;
+
+  switch (XCOFFSymRef.getStorageClass()) {
+  case XCOFF::C_FILE:
+    // If the symbol is C_FILE and has auxiliary entries...
+    for (int i = 1; i <= NumberOfAuxEntries; i++) {
+      const XCOFFFileAuxEnt *FileAuxEntPtr =
+          reinterpret_cast<const XCOFFFileAuxEnt *>(SymbolEntPtr + i);
+#ifndef NDEBUG
+      Obj.checkSymbolEntryPointer(reinterpret_cast<uintptr_t>(FileAuxEntPtr));
+#endif
+      printFileAuxEnt(FileAuxEntPtr);
+    }
+    break;
+  case XCOFF::C_EXT:
+  case XCOFF::C_WEAKEXT:
+  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)
+      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++) {
+      W.startLine() << "!Unexpected raw auxiliary entry data:\n";
+      W.startLine() << format_bytes(
+          ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(SymbolEntPtr + i),
+                            XCOFF::SymbolTableEntrySize));
+    }
+
+    // The symbol's last auxiliary entry is a CSECT Auxiliary Entry.
+    printCsectAuxEnt32(XCOFFSymRef.getXCOFFCsectAuxEnt32());
+    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);
+#ifndef NDEBUG
+    Obj.checkSymbolEntryPointer(reinterpret_cast<uintptr_t>(StatAuxEntPtr));
+#endif
+    printSectAuxEntForStat(StatAuxEntPtr);
+    break;
+  case XCOFF::C_DWARF:
+  case XCOFF::C_BLOCK:
+  case XCOFF::C_FCN:
+    report_fatal_error("Symbol table entry printing for this storage class "
+                       "type is unimplemented.");
+    break;
+  default:
+    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),
+                            XCOFF::SymbolTableEntrySize));
+    }
+    break;
+  }
+}
+
 void XCOFFDumper::printSymbols() {
-  llvm_unreachable("Unimplemented functionality for XCOFFDumper");
+  ListScope Group(W, "Symbols");
+  for (const SymbolRef &S : Obj.symbols())
+    printSymbol(S);
 }
 
 void XCOFFDumper::printDynamicSymbols() {




More information about the llvm-commits mailing list