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

Daniel Sanders via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 28 11:56:22 PDT 2019



> On Aug 27, 2019, at 11:54, Jason Liu via llvm-commits <llvm-commits at lists.llvm.org> wrote:
> 
> 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.");

Hi Jason,

This assert causes "XCOFFDumper.cpp:240:3: error: unannotated fall-through between switch labels [-Werror,-Wimplicit-fallthrough]" because assert might return (even though it won't in practice). Using llvm_unreachable() instead or adding a return after it should fix it.

> +  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() {
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list