[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