[llvm] 8e84311 - [XCOFF][AIX] Enable tooling support for 64 bit symbol table parsing
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 7 10:25:34 PDT 2021
Author: jasonliu
Date: 2021-06-07T17:24:13Z
New Revision: 8e84311a84b35ced5c18c3af8a802f7d2aa5c8a0
URL: https://github.com/llvm/llvm-project/commit/8e84311a84b35ced5c18c3af8a802f7d2aa5c8a0
DIFF: https://github.com/llvm/llvm-project/commit/8e84311a84b35ced5c18c3af8a802f7d2aa5c8a0.diff
LOG: [XCOFF][AIX] Enable tooling support for 64 bit symbol table parsing
Add in the ability of parsing symbol table for 64 bit object.
Reviewed By: jhenderson, DiggerLin
Differential Revision: https://reviews.llvm.org/D85774
Added:
llvm/test/tools/llvm-objdump/XCOFF/Inputs/xcoff-section-headers64.o
llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbol-description64.test
llvm/test/tools/llvm-readobj/XCOFF/Inputs/file-aux-wrong64.o
llvm/test/tools/llvm-readobj/XCOFF/Inputs/symbol64.o
llvm/test/tools/llvm-readobj/XCOFF/file-aux-wrong64.test
llvm/test/tools/llvm-readobj/XCOFF/symbols64.test
Modified:
llvm/include/llvm/BinaryFormat/XCOFF.h
llvm/include/llvm/Object/XCOFFObjectFile.h
llvm/lib/Object/XCOFFObjectFile.cpp
llvm/tools/llvm-objdump/XCOFFDump.cpp
llvm/tools/llvm-readobj/XCOFFDumper.cpp
llvm/tools/obj2yaml/xcoff2yaml.cpp
llvm/unittests/Object/XCOFFObjectFileTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/BinaryFormat/XCOFF.h b/llvm/include/llvm/BinaryFormat/XCOFF.h
index 3fcf302366abb..bfd0baf7cf4fa 100644
--- a/llvm/include/llvm/BinaryFormat/XCOFF.h
+++ b/llvm/include/llvm/BinaryFormat/XCOFF.h
@@ -296,6 +296,15 @@ enum CFileCpuId : uint8_t {
TCPU_970 = 19 ///< PPC970 - PowerPC 64-bit architecture.
};
+enum SymbolAuxType : uint8_t {
+ AUX_EXCEPT = 255, ///< Identifies an exception auxiliary entry.
+ AUX_FCN = 254, ///< Identifies a function auxiliary entry.
+ AUX_SYM = 253, ///< Identifies a symbol auxiliary entry.
+ AUX_FILE = 252, ///< Identifies a file auxiliary entry.
+ AUX_CSECT = 251, ///< Identifies a csect auxiliary entry.
+ AUX_SECT = 250 ///< Identifies a SECT auxiliary entry.
+}; // 64-bit XCOFF file only.
+
StringRef getMappingClassString(XCOFF::StorageMappingClass SMC);
StringRef getRelocationTypeString(XCOFF::RelocationType Type);
SmallString<32> parseParmsType(uint32_t Value, unsigned ParmsNum);
diff --git a/llvm/include/llvm/Object/XCOFFObjectFile.h b/llvm/include/llvm/Object/XCOFFObjectFile.h
index dbc40c4ea8804..7bd02fa4a2d25 100644
--- a/llvm/include/llvm/Object/XCOFFObjectFile.h
+++ b/llvm/include/llvm/Object/XCOFFObjectFile.h
@@ -97,68 +97,113 @@ struct XCOFFSectionHeader64 : XCOFFSectionHeader<XCOFFSectionHeader64> {
char Padding[4];
};
-struct XCOFFSymbolEntry {
- enum { NAME_IN_STR_TBL_MAGIC = 0x0 };
- typedef struct {
- support::big32_t Magic; // Zero indicates name in string table.
- support::ubig32_t Offset;
- } NameInStrTblType;
-
- typedef struct {
- uint8_t LanguageId;
- uint8_t CpuTypeId;
- } CFileLanguageIdAndTypeIdType;
-
- union {
- char SymbolName[XCOFF::NameSize];
- NameInStrTblType NameInStrTbl;
- };
-
- support::ubig32_t Value; // Symbol value; storage class-dependent.
- support::big16_t SectionNumber;
-
- union {
- support::ubig16_t SymbolType;
- CFileLanguageIdAndTypeIdType CFileLanguageIdAndTypeId;
- };
-
- XCOFF::StorageClass StorageClass;
- uint8_t NumberOfAuxEntries;
-};
-
struct XCOFFStringTable {
uint32_t Size;
const char *Data;
};
struct XCOFFCsectAuxEnt32 {
- static constexpr uint8_t SymbolTypeMask = 0x07;
- static constexpr uint8_t SymbolAlignmentMask = 0xF8;
- static constexpr size_t SymbolAlignmentBitOffset = 3;
-
- support::ubig32_t
- SectionOrLength; // If the symbol type is XTY_SD or XTY_CM, the csect
- // length.
- // If the symbol type is XTY_LD, the symbol table
- // index of the containing csect.
- // If the symbol type is XTY_ER, 0.
+ support::ubig32_t SectionOrLength;
support::ubig32_t ParameterHashIndex;
support::ubig16_t TypeChkSectNum;
uint8_t SymbolAlignmentAndType;
XCOFF::StorageMappingClass StorageMappingClass;
support::ubig32_t StabInfoIndex;
support::ubig16_t StabSectNum;
+};
+
+struct XCOFFCsectAuxEnt64 {
+ support::ubig32_t SectionOrLengthLowByte;
+ support::ubig32_t ParameterHashIndex;
+ support::ubig16_t TypeChkSectNum;
+ uint8_t SymbolAlignmentAndType;
+ XCOFF::StorageMappingClass StorageMappingClass;
+ support::ubig32_t SectionOrLengthHighByte;
+ uint8_t Pad;
+ XCOFF::SymbolAuxType AuxType;
+};
+
+class XCOFFCsectAuxRef {
+public:
+ static constexpr uint8_t SymbolTypeMask = 0x07;
+ static constexpr uint8_t SymbolAlignmentMask = 0xF8;
+ static constexpr size_t SymbolAlignmentBitOffset = 3;
+
+ XCOFFCsectAuxRef(const XCOFFCsectAuxEnt32 *Entry32) : Entry32(Entry32) {}
+ XCOFFCsectAuxRef(const XCOFFCsectAuxEnt64 *Entry64) : Entry64(Entry64) {}
+
+ // For getSectionOrLength(),
+ // If the symbol type is XTY_SD or XTY_CM, the csect length.
+ // If the symbol type is XTY_LD, the symbol table
+ // index of the containing csect.
+ // If the symbol type is XTY_ER, 0.
+ uint64_t getSectionOrLength() const {
+ return Entry32 ? getSectionOrLength32() : getSectionOrLength64();
+ }
+
+ uint32_t getSectionOrLength32() const {
+ assert(Entry32 && "32-bit interface called on 64-bit object file.");
+ return Entry32->SectionOrLength;
+ }
+
+ uint64_t getSectionOrLength64() const {
+ assert(Entry64 && "64-bit interface called on 32-bit object file.");
+ return (static_cast<uint64_t>(Entry64->SectionOrLengthHighByte) << 32) |
+ Entry64->SectionOrLengthLowByte;
+ }
+
+#define GETVALUE(X) Entry32 ? Entry32->X : Entry64->X
+
+ uint32_t getParameterHashIndex() const {
+ return GETVALUE(ParameterHashIndex);
+ }
+
+ uint16_t getTypeChkSectNum() const { return GETVALUE(TypeChkSectNum); }
+
+ XCOFF::StorageMappingClass getStorageMappingClass() const {
+ return GETVALUE(StorageMappingClass);
+ }
+
+ uintptr_t getEntryAddress() const {
+ return Entry32 ? reinterpret_cast<uintptr_t>(Entry32)
+ : reinterpret_cast<uintptr_t>(Entry64);
+ }
uint16_t getAlignmentLog2() const {
- return (SymbolAlignmentAndType & SymbolAlignmentMask) >>
+ return (getSymbolAlignmentAndType() & SymbolAlignmentMask) >>
SymbolAlignmentBitOffset;
}
uint8_t getSymbolType() const {
- return SymbolAlignmentAndType & SymbolTypeMask;
+ return getSymbolAlignmentAndType() & SymbolTypeMask;
}
bool isLabel() const { return getSymbolType() == XCOFF::XTY_LD; }
+
+ uint32_t getStabInfoIndex32() const {
+ assert(Entry32 && "32-bit interface called on 64-bit object file.");
+ return Entry32->StabInfoIndex;
+ }
+
+ uint16_t getStabSectNum32() const {
+ assert(Entry32 && "32-bit interface called on 64-bit object file.");
+ return Entry32->StabSectNum;
+ }
+
+ XCOFF::SymbolAuxType getAuxType64() const {
+ assert(Entry64 && "64-bit interface called on 32-bit object file.");
+ return Entry64->AuxType;
+ }
+
+private:
+ uint8_t getSymbolAlignmentAndType() const {
+ return GETVALUE(SymbolAlignmentAndType);
+ }
+
+#undef GETVALUE
+
+ const XCOFFCsectAuxEnt32 *Entry32 = nullptr;
+ const XCOFFCsectAuxEnt64 *Entry64 = nullptr;
};
struct XCOFFFileAuxEnt {
@@ -173,7 +218,7 @@ struct XCOFFFileAuxEnt {
};
XCOFF::CFileStringType Type;
uint8_t ReservedZeros[2];
- uint8_t AuxType; // 64-bit XCOFF file only.
+ XCOFF::SymbolAuxType AuxType; // 64-bit XCOFF file only.
};
struct XCOFFSectAuxEntForStat {
@@ -181,7 +226,7 @@ struct XCOFFSectAuxEntForStat {
support::ubig16_t NumberOfRelocEnt;
support::ubig16_t NumberOfLineNum;
uint8_t Pad[10];
-};
+}; // 32-bit XCOFF file only.
struct XCOFFRelocation32 {
// Masks for packing/unpacking the r_rsize field of relocations.
@@ -215,12 +260,14 @@ struct XCOFFRelocation32 {
uint8_t getRelocatedLength() const;
};
+class XCOFFSymbolRef;
+
class XCOFFObjectFile : public ObjectFile {
private:
const void *FileHeader = nullptr;
const void *SectionHeaderTable = nullptr;
- const XCOFFSymbolEntry *SymbolTblPtr = nullptr;
+ const void *SymbolTblPtr = nullptr;
XCOFFStringTable StringTable = {0, nullptr};
const XCOFFFileHeader32 *fileHeader32() const;
@@ -242,9 +289,6 @@ class XCOFFObjectFile : public ObjectFile {
// null-terminated.
const char *getSectionNameInternal(DataRefImpl Sec) const;
- // This function returns string table entry.
- Expected<StringRef> getStringTableEntry(uint32_t Offset) const;
-
static bool isReservedSectionNumber(int16_t SectionNumber);
// Constructor and "create" factory function. The constructor is only a thin
@@ -323,15 +367,11 @@ class XCOFFObjectFile : public ObjectFile {
// Below here is the non-inherited interface.
bool is64Bit() const;
- const XCOFFSymbolEntry *getPointerToSymbolTable() const {
- assert(!is64Bit() && "Symbol table handling not supported yet.");
- return SymbolTblPtr;
- }
+ const void *getPointerToSymbolTable() const { return SymbolTblPtr; }
- Expected<StringRef>
- getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const;
+ Expected<StringRef> getSymbolSectionName(XCOFFSymbolRef Ref) const;
- const XCOFFSymbolEntry *toSymbolEntry(DataRefImpl Ref) const;
+ XCOFFSymbolRef toSymbolRef(DataRefImpl Ref) const;
// File header related interfaces.
uint16_t getMagic() const;
@@ -351,7 +391,13 @@ class XCOFFObjectFile : public ObjectFile {
uint32_t getLogicalNumberOfSymbolTableEntries32() const;
uint32_t getNumberOfSymbolTableEntries64() const;
+
+ // Return getLogicalNumberOfSymbolTableEntries32 or
+ // getNumberOfSymbolTableEntries64 depending on the object mode.
+ uint32_t getNumberOfSymbolTableEntries() const;
+
uint32_t getSymbolIndex(uintptr_t SymEntPtr) const;
+ uintptr_t getSymbolEntryAddressByIndex(uint32_t SymbolTableIndex) const;
Expected<StringRef> getSymbolNameByIndex(uint32_t SymbolTableIndex) const;
Expected<StringRef> getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const;
@@ -374,26 +420,120 @@ class XCOFFObjectFile : public ObjectFile {
Expected<ArrayRef<XCOFFRelocation32>>
relocations(const XCOFFSectionHeader32 &) const;
+ // This function returns string table entry.
+ Expected<StringRef> getStringTableEntry(uint32_t Offset) const;
+
+ const XCOFF::SymbolAuxType *getSymbolAuxType(uintptr_t AuxEntryAddress) const;
+
+ static uintptr_t getAdvancedSymbolEntryAddress(uintptr_t CurrentAddress,
+ uint32_t Distance);
+
static bool classof(const Binary *B) { return B->isXCOFF(); }
}; // XCOFFObjectFile
-class XCOFFSymbolRef {
- const DataRefImpl SymEntDataRef;
- const XCOFFObjectFile *const OwningObjectPtr;
+typedef struct {
+ uint8_t LanguageId;
+ uint8_t CpuTypeId;
+} CFileLanguageIdAndTypeIdType;
+
+struct XCOFFSymbolEntry32 {
+ typedef struct {
+ support::big32_t Magic; // Zero indicates name in string table.
+ support::ubig32_t Offset;
+ } NameInStrTblType;
+ union {
+ char SymbolName[XCOFF::NameSize];
+ NameInStrTblType NameInStrTbl;
+ };
+
+ support::ubig32_t Value; // Symbol value; storage class-dependent.
+ support::big16_t SectionNumber;
+
+ union {
+ support::ubig16_t SymbolType;
+ CFileLanguageIdAndTypeIdType CFileLanguageIdAndTypeId;
+ };
+
+ XCOFF::StorageClass StorageClass;
+ uint8_t NumberOfAuxEntries;
+};
+
+struct XCOFFSymbolEntry64 {
+ support::ubig64_t Value; // Symbol value; storage class-dependent.
+ support::ubig32_t Offset;
+ support::big16_t SectionNumber;
+
+ union {
+ support::ubig16_t SymbolType;
+ CFileLanguageIdAndTypeIdType CFileLanguageIdAndTypeId;
+ };
+
+ XCOFF::StorageClass StorageClass;
+ uint8_t NumberOfAuxEntries;
+};
+
+class XCOFFSymbolRef {
public:
+ enum { NAME_IN_STR_TBL_MAGIC = 0x0 };
+
XCOFFSymbolRef(DataRefImpl SymEntDataRef,
const XCOFFObjectFile *OwningObjectPtr)
- : SymEntDataRef(SymEntDataRef), OwningObjectPtr(OwningObjectPtr){};
+ : OwningObjectPtr(OwningObjectPtr) {
+ assert(OwningObjectPtr && "OwningObjectPtr cannot be nullptr!");
+ assert(SymEntDataRef.p != 0 &&
+ "Symbol table entry pointer cannot be nullptr!");
+
+ if (OwningObjectPtr->is64Bit())
+ Entry64 = reinterpret_cast<const XCOFFSymbolEntry64 *>(SymEntDataRef.p);
+ else
+ Entry32 = reinterpret_cast<const XCOFFSymbolEntry32 *>(SymEntDataRef.p);
+ }
- XCOFF::StorageClass getStorageClass() const;
- uint8_t getNumberOfAuxEntries() const;
- const XCOFFCsectAuxEnt32 *getXCOFFCsectAuxEnt32() const;
- uint16_t getType() const;
- int16_t getSectionNumber() const;
+ uint64_t getValue() const { return Entry32 ? getValue32() : getValue64(); }
- bool hasCsectAuxEnt() const;
+ uint32_t getValue32() const { return Entry32->Value; }
+
+ uint64_t getValue64() const { return Entry64->Value; }
+
+#define GETVALUE(X) Entry32 ? Entry32->X : Entry64->X
+
+ int16_t getSectionNumber() const { return GETVALUE(SectionNumber); }
+
+ uint16_t getSymbolType() const { return GETVALUE(SymbolType); }
+
+ uint8_t getLanguageIdForCFile() const {
+ assert(getStorageClass() == XCOFF::C_FILE &&
+ "This interface is for C_FILE only.");
+ return GETVALUE(CFileLanguageIdAndTypeId.LanguageId);
+ }
+
+ uint8_t getCPUTypeIddForCFile() const {
+ assert(getStorageClass() == XCOFF::C_FILE &&
+ "This interface is for C_FILE only.");
+ return GETVALUE(CFileLanguageIdAndTypeId.CpuTypeId);
+ }
+
+ XCOFF::StorageClass getStorageClass() const { return GETVALUE(StorageClass); }
+
+ uint8_t getNumberOfAuxEntries() const { return GETVALUE(NumberOfAuxEntries); }
+
+#undef GETVALUE
+
+ uintptr_t getEntryAddress() const {
+ return Entry32 ? reinterpret_cast<uintptr_t>(Entry32)
+ : reinterpret_cast<uintptr_t>(Entry64);
+ }
+
+ Expected<StringRef> getName() const;
bool isFunction() const;
+ bool isCsectSymbol() const;
+ Expected<XCOFFCsectAuxRef> getXCOFFCsectAuxRef() const;
+
+private:
+ const XCOFFObjectFile *OwningObjectPtr;
+ const XCOFFSymbolEntry32 *Entry32 = nullptr;
+ const XCOFFSymbolEntry64 *Entry64 = nullptr;
};
class TBVectorExt {
diff --git a/llvm/lib/Object/XCOFFObjectFile.cpp b/llvm/lib/Object/XCOFFObjectFile.cpp
index 74b10faad68f1..86815539a033d 100644
--- a/llvm/lib/Object/XCOFFObjectFile.cpp
+++ b/llvm/lib/Object/XCOFFObjectFile.cpp
@@ -24,8 +24,8 @@ using namespace XCOFF;
namespace object {
static const uint8_t FunctionSym = 0x20;
-static const uint8_t SymTypeMask = 0x07;
static const uint16_t NoRelMask = 0x0001;
+static const size_t SymbolAuxTypeOffset = 17;
// Checks that [Ptr, Ptr + Size) bytes fall inside the memory buffer
// 'M'. Returns a pointer to the underlying object on success.
@@ -83,6 +83,19 @@ uint8_t XCOFFRelocation32::getRelocatedLength() const {
return (Info & XR_BIASED_LENGTH_MASK) + 1;
}
+uintptr_t
+XCOFFObjectFile::getAdvancedSymbolEntryAddress(uintptr_t CurrentAddress,
+ uint32_t Distance) {
+ return getWithOffset(CurrentAddress, Distance * XCOFF::SymbolTableEntrySize);
+}
+
+const XCOFF::SymbolAuxType *
+XCOFFObjectFile::getSymbolAuxType(uintptr_t AuxEntryAddress) const {
+ assert(is64Bit() && "64-bit interface called on a 32-bit object file.");
+ return viewAs<XCOFF::SymbolAuxType>(
+ getWithOffset(AuxEntryAddress, SymbolAuxTypeOffset));
+}
+
void XCOFFObjectFile::checkSectionAddress(uintptr_t Addr,
uintptr_t TableAddress) const {
if (Addr < TableAddress)
@@ -115,14 +128,12 @@ XCOFFObjectFile::toSection64(DataRefImpl Ref) const {
return viewAs<XCOFFSectionHeader64>(Ref.p);
}
-const XCOFFSymbolEntry *XCOFFObjectFile::toSymbolEntry(DataRefImpl Ref) const {
- assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
+XCOFFSymbolRef XCOFFObjectFile::toSymbolRef(DataRefImpl Ref) const {
assert(Ref.p != 0 && "Symbol table pointer can not be nullptr!");
#ifndef NDEBUG
checkSymbolEntryPointer(Ref.p);
#endif
- auto SymEntPtr = viewAs<XCOFFSymbolEntry>(Ref.p);
- return SymEntPtr;
+ return XCOFFSymbolRef(Ref, this);
}
const XCOFFFileHeader32 *XCOFFObjectFile::fileHeader32() const {
@@ -148,15 +159,15 @@ XCOFFObjectFile::sectionHeaderTable64() const {
}
void XCOFFObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
- const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
- SymEntPtr += SymEntPtr->NumberOfAuxEntries + 1;
+ uintptr_t NextSymbolAddr = getAdvancedSymbolEntryAddress(
+ Symb.p, toSymbolRef(Symb).getNumberOfAuxEntries() + 1);
#ifndef NDEBUG
// This function is used by basic_symbol_iterator, which allows to
// point to the end-of-symbol-table address.
- if (reinterpret_cast<uintptr_t>(SymEntPtr) != getEndOfSymbolTableAddress())
- checkSymbolEntryPointer(reinterpret_cast<uintptr_t>(SymEntPtr));
+ if (NextSymbolAddr != getEndOfSymbolTableAddress())
+ checkSymbolEntryPointer(NextSymbolAddr);
#endif
- Symb.p = reinterpret_cast<uintptr_t>(SymEntPtr);
+ Symb.p = NextSymbolAddr;
}
Expected<StringRef>
@@ -178,34 +189,21 @@ XCOFFObjectFile::getStringTableEntry(uint32_t Offset) const {
Expected<StringRef>
XCOFFObjectFile::getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const {
- if (CFileEntPtr->NameInStrTbl.Magic !=
- XCOFFSymbolEntry::NAME_IN_STR_TBL_MAGIC)
+ if (CFileEntPtr->NameInStrTbl.Magic != XCOFFSymbolRef::NAME_IN_STR_TBL_MAGIC)
return generateXCOFFFixedNameStringRef(CFileEntPtr->Name);
return getStringTableEntry(CFileEntPtr->NameInStrTbl.Offset);
}
Expected<StringRef> XCOFFObjectFile::getSymbolName(DataRefImpl Symb) const {
- const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
-
- // A storage class value with the high-order bit on indicates that the name is
- // a symbolic debugger stabstring.
- if (SymEntPtr->StorageClass & 0x80)
- return StringRef("Unimplemented Debug Name");
-
- if (SymEntPtr->NameInStrTbl.Magic != XCOFFSymbolEntry::NAME_IN_STR_TBL_MAGIC)
- return generateXCOFFFixedNameStringRef(SymEntPtr->SymbolName);
-
- return getStringTableEntry(SymEntPtr->NameInStrTbl.Offset);
+ return toSymbolRef(Symb).getName();
}
Expected<uint64_t> XCOFFObjectFile::getSymbolAddress(DataRefImpl Symb) const {
- assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
- return toSymbolEntry(Symb)->Value;
+ return toSymbolRef(Symb).getValue();
}
uint64_t XCOFFObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
- assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
- return toSymbolEntry(Symb)->Value;
+ return toSymbolRef(Symb).getValue();
}
uint64_t XCOFFObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
@@ -222,8 +220,7 @@ XCOFFObjectFile::getSymbolType(DataRefImpl Symb) const {
Expected<section_iterator>
XCOFFObjectFile::getSymbolSection(DataRefImpl Symb) const {
- const XCOFFSymbolEntry *SymEntPtr = toSymbolEntry(Symb);
- int16_t SectNum = SymEntPtr->SectionNumber;
+ const int16_t SectNum = toSymbolRef(Symb).getSectionNumber();
if (isReservedSectionNumber(SectNum))
return section_end();
@@ -376,7 +373,7 @@ symbol_iterator XCOFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
return symbol_end();
DataRefImpl SymDRI;
- SymDRI.p = reinterpret_cast<uintptr_t>(getPointerToSymbolTable() + Index);
+ SymDRI.p = getSymbolEntryAddressByIndex(Index);
return symbol_iterator(SymbolRef(SymDRI, this));
}
@@ -402,19 +399,15 @@ Expected<uint32_t> XCOFFObjectFile::getSymbolFlags(DataRefImpl Symb) const {
}
basic_symbol_iterator XCOFFObjectFile::symbol_begin() const {
- if (is64Bit())
- report_fatal_error("64-bit support not implemented yet");
DataRefImpl SymDRI;
SymDRI.p = reinterpret_cast<uintptr_t>(SymbolTblPtr);
return basic_symbol_iterator(SymbolRef(SymDRI, this));
}
basic_symbol_iterator XCOFFObjectFile::symbol_end() const {
- if (is64Bit())
- report_fatal_error("64-bit support not implemented yet");
DataRefImpl SymDRI;
- SymDRI.p = reinterpret_cast<uintptr_t>(
- SymbolTblPtr + getLogicalNumberOfSymbolTableEntries32());
+ const uint32_t NumberOfSymbolTableEntries = getNumberOfSymbolTableEntries();
+ SymDRI.p = getSymbolEntryAddressByIndex(NumberOfSymbolTableEntries);
return basic_symbol_iterator(SymbolRef(SymDRI, this));
}
@@ -501,9 +494,8 @@ Expected<DataRefImpl> XCOFFObjectFile::getSectionByNum(int16_t Num) const {
}
Expected<StringRef>
-XCOFFObjectFile::getSymbolSectionName(const XCOFFSymbolEntry *SymEntPtr) const {
- assert(!is64Bit() && "Symbol table support not implemented for 64-bit.");
- int16_t SectionNum = SymEntPtr->SectionNumber;
+XCOFFObjectFile::getSymbolSectionName(XCOFFSymbolRef SymEntPtr) const {
+ const int16_t SectionNum = SymEntPtr.getSectionNumber();
switch (SectionNum) {
case XCOFF::N_DEBUG:
@@ -564,10 +556,13 @@ uint32_t XCOFFObjectFile::getNumberOfSymbolTableEntries64() const {
return fileHeader64()->NumberOfSymTableEntries;
}
+uint32_t XCOFFObjectFile::getNumberOfSymbolTableEntries() const {
+ return is64Bit() ? getNumberOfSymbolTableEntries64()
+ : getLogicalNumberOfSymbolTableEntries32();
+}
+
uintptr_t XCOFFObjectFile::getEndOfSymbolTableAddress() const {
- uint32_t NumberOfSymTableEntries =
- is64Bit() ? getNumberOfSymbolTableEntries64()
- : getLogicalNumberOfSymbolTableEntries32();
+ const uint32_t NumberOfSymTableEntries = getNumberOfSymbolTableEntries();
return getWithOffset(reinterpret_cast<uintptr_t>(SymbolTblPtr),
XCOFF::SymbolTableEntrySize * NumberOfSymTableEntries);
}
@@ -593,16 +588,20 @@ uint32_t XCOFFObjectFile::getSymbolIndex(uintptr_t SymbolEntPtr) const {
XCOFF::SymbolTableEntrySize;
}
+uintptr_t XCOFFObjectFile::getSymbolEntryAddressByIndex(uint32_t Index) const {
+ return getAdvancedSymbolEntryAddress(
+ reinterpret_cast<uintptr_t>(getPointerToSymbolTable()), Index);
+}
+
Expected<StringRef>
XCOFFObjectFile::getSymbolNameByIndex(uint32_t Index) const {
- if (is64Bit())
- report_fatal_error("64-bit symbol table support not implemented yet.");
+ const uint32_t NumberOfSymTableEntries = getNumberOfSymbolTableEntries();
- if (Index >= getLogicalNumberOfSymbolTableEntries32())
+ if (Index >= NumberOfSymTableEntries)
return errorCodeToError(object_error::invalid_symbol_index);
DataRefImpl SymDRI;
- SymDRI.p = reinterpret_cast<uintptr_t>(getPointerToSymbolTable() + Index);
+ SymDRI.p = getSymbolEntryAddressByIndex(Index);
return getSymbolName(SymDRI);
}
@@ -745,20 +744,21 @@ XCOFFObjectFile::create(unsigned Type, MemoryBufferRef MBR) {
Obj->SectionHeaderTable = SecHeadersOrErr.get();
}
- // 64-bit object supports only file header and section headers for now.
- if (Obj->is64Bit())
- return std::move(Obj);
+ const uint32_t NumberOfSymbolTableEntries =
+ Obj->getNumberOfSymbolTableEntries();
// If there is no symbol table we are done parsing the memory buffer.
- if (Obj->getLogicalNumberOfSymbolTableEntries32() == 0)
+ if (NumberOfSymbolTableEntries == 0)
return std::move(Obj);
// Parse symbol table.
- CurOffset = Obj->fileHeader32()->SymbolTableOffset;
- uint64_t SymbolTableSize = (uint64_t)(sizeof(XCOFFSymbolEntry)) *
- Obj->getLogicalNumberOfSymbolTableEntries32();
+ CurOffset = Obj->is64Bit() ? Obj->getSymbolTableOffset64()
+ : Obj->getSymbolTableOffset32();
+ const uint64_t SymbolTableSize =
+ static_cast<uint64_t>(XCOFF::SymbolTableEntrySize) *
+ NumberOfSymbolTableEntries;
auto SymTableOrErr =
- getObject<XCOFFSymbolEntry>(Data, Base + CurOffset, SymbolTableSize);
+ getObject<void *>(Data, Base + CurOffset, SymbolTableSize);
if (Error E = SymTableOrErr.takeError())
return std::move(E);
Obj->SymbolTblPtr = SymTableOrErr.get();
@@ -780,74 +780,103 @@ ObjectFile::createXCOFFObjectFile(MemoryBufferRef MemBufRef,
return XCOFFObjectFile::create(FileType, MemBufRef);
}
-XCOFF::StorageClass XCOFFSymbolRef::getStorageClass() const {
- return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->StorageClass;
-}
+bool XCOFFSymbolRef::isFunction() const {
+ if (!isCsectSymbol())
+ return false;
-uint8_t XCOFFSymbolRef::getNumberOfAuxEntries() const {
- return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->NumberOfAuxEntries;
-}
+ if (getSymbolType() & FunctionSym)
+ return true;
-// TODO: The function needs to return an error if there is no csect auxiliary
-// entry.
-const XCOFFCsectAuxEnt32 *XCOFFSymbolRef::getXCOFFCsectAuxEnt32() const {
- assert(!OwningObjectPtr->is64Bit() &&
- "32-bit interface called on 64-bit object file.");
- assert(hasCsectAuxEnt() && "No Csect Auxiliary Entry is found.");
+ Expected<XCOFFCsectAuxRef> ExpCsectAuxEnt = getXCOFFCsectAuxRef();
+ if (!ExpCsectAuxEnt)
+ return false;
- // In XCOFF32, the csect auxilliary entry is always the last auxiliary
- // entry for the symbol.
- uintptr_t AuxAddr = getWithOffset(
- SymEntDataRef.p, XCOFF::SymbolTableEntrySize * getNumberOfAuxEntries());
+ const XCOFFCsectAuxRef CsectAuxRef = ExpCsectAuxEnt.get();
-#ifndef NDEBUG
- OwningObjectPtr->checkSymbolEntryPointer(AuxAddr);
-#endif
+ // A function definition should be a label definition.
+ // FIXME: This is not necessarily the case when -ffunction-sections is
+ // enabled.
+ if (!CsectAuxRef.isLabel())
+ return false;
- return reinterpret_cast<const XCOFFCsectAuxEnt32 *>(AuxAddr);
-}
+ if (CsectAuxRef.getStorageMappingClass() != XCOFF::XMC_PR)
+ return false;
-uint16_t XCOFFSymbolRef::getType() const {
- return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->SymbolType;
-}
+ const int16_t SectNum = getSectionNumber();
+ Expected<DataRefImpl> SI = OwningObjectPtr->getSectionByNum(SectNum);
+ if (!SI) {
+ // If we could not get the section, then this symbol should not be
+ // a function. So consume the error and return `false` to move on.
+ consumeError(SI.takeError());
+ return false;
+ }
-int16_t XCOFFSymbolRef::getSectionNumber() const {
- return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->SectionNumber;
+ return (OwningObjectPtr->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT);
}
-// TODO: The function name needs to be changed to express the purpose of the
-// function.
-bool XCOFFSymbolRef::hasCsectAuxEnt() const {
+bool XCOFFSymbolRef::isCsectSymbol() const {
XCOFF::StorageClass SC = getStorageClass();
return (SC == XCOFF::C_EXT || SC == XCOFF::C_WEAKEXT ||
SC == XCOFF::C_HIDEXT);
}
-bool XCOFFSymbolRef::isFunction() const {
- if (OwningObjectPtr->is64Bit())
- report_fatal_error("64-bit support is unimplemented yet.");
+Expected<XCOFFCsectAuxRef> XCOFFSymbolRef::getXCOFFCsectAuxRef() const {
+ assert(isCsectSymbol() &&
+ "Calling csect symbol interface with a non-csect symbol.");
- if (getType() & FunctionSym)
- return true;
+ uint8_t NumberOfAuxEntries = getNumberOfAuxEntries();
- if (!hasCsectAuxEnt())
- return false;
+ Expected<StringRef> NameOrErr = getName();
+ if (auto Err = NameOrErr.takeError())
+ return std::move(Err);
- const XCOFFCsectAuxEnt32 *CsectAuxEnt = getXCOFFCsectAuxEnt32();
+ if (!NumberOfAuxEntries) {
+ return createStringError(object_error::parse_failed,
+ "csect symbol \"" + *NameOrErr +
+ "\" contains no auxiliary entry");
+ }
- // A function definition should be a label definition.
- if ((CsectAuxEnt->SymbolAlignmentAndType & SymTypeMask) != XCOFF::XTY_LD)
- return false;
+ if (!OwningObjectPtr->is64Bit()) {
+ // In XCOFF32, the csect auxilliary entry is always the last auxiliary
+ // entry for the symbol.
+ uintptr_t AuxAddr = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
+ getEntryAddress(), NumberOfAuxEntries);
+ return XCOFFCsectAuxRef(viewAs<XCOFFCsectAuxEnt32>(AuxAddr));
+ }
- if (CsectAuxEnt->StorageMappingClass != XCOFF::XMC_PR)
- return false;
+ // XCOFF64 uses SymbolAuxType to identify the auxiliary entry type.
+ // We need to iterate through all the auxiliary entries to find it.
+ for (uint8_t Index = NumberOfAuxEntries; Index > 0; --Index) {
+ uintptr_t AuxAddr = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
+ getEntryAddress(), Index);
+ if (*OwningObjectPtr->getSymbolAuxType(AuxAddr) ==
+ XCOFF::SymbolAuxType::AUX_CSECT) {
+#ifndef NDEBUG
+ OwningObjectPtr->checkSymbolEntryPointer(AuxAddr);
+#endif
+ return XCOFFCsectAuxRef(viewAs<XCOFFCsectAuxEnt64>(AuxAddr));
+ }
+ }
- int16_t SectNum = getSectionNumber();
- Expected<DataRefImpl> SI = OwningObjectPtr->getSectionByNum(SectNum);
- if (!SI)
- return false;
+ return createStringError(
+ object_error::parse_failed,
+ "a csect auxiliary entry is not found for symbol \"" + *NameOrErr + "\"");
+}
- return (OwningObjectPtr->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT);
+Expected<StringRef> XCOFFSymbolRef::getName() const {
+ // A storage class value with the high-order bit on indicates that the name is
+ // a symbolic debugger stabstring.
+ if (getStorageClass() & 0x80)
+ return StringRef("Unimplemented Debug Name");
+
+ if (Entry32) {
+ if (Entry32->NameInStrTbl.Magic != XCOFFSymbolRef::NAME_IN_STR_TBL_MAGIC)
+ return generateXCOFFFixedNameStringRef(Entry32->SymbolName);
+
+ return OwningObjectPtr->getStringTableEntry(Entry32->NameInStrTbl.Offset);
+ }
+
+ return OwningObjectPtr->getStringTableEntry(Entry64->Offset);
}
// Explictly instantiate template classes.
diff --git a/llvm/test/tools/llvm-objdump/XCOFF/Inputs/xcoff-section-headers64.o b/llvm/test/tools/llvm-objdump/XCOFF/Inputs/xcoff-section-headers64.o
new file mode 100644
index 0000000000000..f65b962ca302d
Binary files /dev/null and b/llvm/test/tools/llvm-objdump/XCOFF/Inputs/xcoff-section-headers64.o
diff er
diff --git a/llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbol-description64.test b/llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbol-description64.test
new file mode 100644
index 0000000000000..fd3e2bb6b3119
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/XCOFF/disassemble-symbol-description64.test
@@ -0,0 +1,96 @@
+# REQUIRES: powerpc-registered-target
+
+# RUN: llvm-objdump -D %p/Inputs/xcoff-section-headers64.o | \
+# RUN: FileCheck --check-prefixes=COMMON,PLAIN %s
+
+# RUN: llvm-objdump -D --symbol-description %p/Inputs/xcoff-section-headers64.o | \
+# RUN: FileCheck --check-prefixes=COMMON,DESC %s
+
+# RUN: not --crash llvm-objdump -D -r --symbol-description %p/Inputs/xcoff-section-headers64.o 2>&1 | \
+# RUN: FileCheck --check-prefix=ERROR %s
+# ERROR: 64-bit support not implemented yet
+
+## xcoff-section-headers64.o Compiled with IBM XL C/C++ for AIX, V16.1.0
+## compiler command: xlc -q64 -qtls -o xcoff-section-headers64.o -c test.c
+
+## test.c:
+## int a;
+## int b = 12345;
+## __thread int c;
+## __thread double d = 3.14159;
+##
+## int func(void) {
+## return a;
+## }
+
+COMMON: Inputs/xcoff-section-headers64.o: file format aix5coff64-rs6000
+COMMON: Disassembly of section .text:
+COMMON-EMPTY:
+PLAIN: 0000000000000000 <.func>:
+DESC: 0000000000000000 (idx: 6) .func:
+COMMON-NEXT: 0: e8 62 00 08 ld 3, 8(2)
+COMMON-NEXT: 4: e8 63 00 02 lwa 3, 0(3)
+COMMON-NEXT: 8: 4e 80 00 20 blr
+COMMON-NEXT: c: 00 00 00 00 <unknown>
+COMMON-NEXT: 10: 00 00 20 40 <unknown>
+COMMON-NEXT: 14: 00 00 00 01 <unknown>
+COMMON-NEXT: 18: 00 00 00 0c <unknown>
+COMMON-NEXT: 1c: 00 04 66 75 <unknown>
+COMMON-NEXT: 20: 6e 63 00 00 xoris 3, 19, 0
+COMMON-NEXT: ...
+COMMON-EMPTY:
+COMMON-NEXT: Disassembly of section .data:
+COMMON-EMPTY:
+PLAIN: 0000000000000080 <func>:
+DESC: 0000000000000080 (idx: 12) func[TC]:
+COMMON-NEXT: 80: 00 00 00 00 <unknown>
+COMMON-NEXT: 84: 00 00 00 a8 <unknown>
+COMMON-EMPTY:
+PLAIN: 0000000000000088 <a>:
+DESC: 0000000000000088 (idx: 16) a[TC]:
+COMMON-NEXT: 88: 00 00 00 00 <unknown>
+COMMON-NEXT: 8c: 00 00 00 c8 <unknown>
+COMMON-EMPTY:
+PLAIN: 0000000000000090 <b>:
+DESC: 0000000000000090 (idx: 20) b[TC]:
+COMMON-NEXT: 90: 00 00 00 00 <unknown>
+COMMON-NEXT: 94: 00 00 00 c0 <unknown>
+COMMON-EMPTY:
+PLAIN: 0000000000000098 <c>:
+DESC: 0000000000000098 (idx: 24) c[TC]:
+COMMON-NEXT: 98: 00 00 00 00 <unknown>
+COMMON-NEXT: 9c: 00 00 00 08 <unknown>
+COMMON-EMPTY:
+PLAIN: 00000000000000a0 <d>:
+DESC: 00000000000000a0 (idx: 28) d[TC]:
+COMMON-NEXT: ...
+COMMON-EMPTY:
+PLAIN: 00000000000000a8 <func>:
+DESC: 00000000000000a8 (idx: 10) func[DS]:
+COMMON-NEXT: ...
+COMMON-NEXT: b4: 00 00 00 80 <unknown>
+COMMON-NEXT: ...
+COMMON-EMPTY:
+PLAIN: 00000000000000c0 <b>:
+DESC: 00000000000000c0 (idx: 18) b[RW]:
+COMMON-NEXT: c0: 00 00 30 39 <unknown>
+COMMON-NEXT: c4: 00 00 00 00 <unknown>
+COMMON-EMPTY:
+COMMON-NEXT: Disassembly of section .bss:
+COMMON-EMPTY:
+PLAIN: 00000000000000c8 <a>:
+DESC: 00000000000000c8 (idx: 14) a[RW]:
+COMMON-NEXT: ...
+COMMON-EMPTY:
+COMMON-NEXT: Disassembly of section .tdata:
+COMMON-EMPTY:
+PLAIN: 0000000000000000 <d>:
+DESC: 0000000000000000 (idx: 26) d[TL]:
+COMMON-NEXT: 0: 40 09 21 f9 bdnzfl 9, 0x21f8
+COMMON-NEXT: 4: f0 1b 86 6e <unknown>
+COMMON-EMPTY:
+COMMON-NEXT: Disassembly of section .tbss:
+COMMON-EMPTY:
+PLAIN: 0000000000000008 <c>:
+DESC: 0000000000000008 (idx: 22) c[UL]:
+COMMON-NEXT: ...
diff --git a/llvm/test/tools/llvm-readobj/XCOFF/Inputs/file-aux-wrong64.o b/llvm/test/tools/llvm-readobj/XCOFF/Inputs/file-aux-wrong64.o
new file mode 100644
index 0000000000000..dc5052f0b83d0
Binary files /dev/null and b/llvm/test/tools/llvm-readobj/XCOFF/Inputs/file-aux-wrong64.o
diff er
diff --git a/llvm/test/tools/llvm-readobj/XCOFF/Inputs/symbol64.o b/llvm/test/tools/llvm-readobj/XCOFF/Inputs/symbol64.o
new file mode 100644
index 0000000000000..60d4cd9e80934
Binary files /dev/null and b/llvm/test/tools/llvm-readobj/XCOFF/Inputs/symbol64.o
diff er
diff --git a/llvm/test/tools/llvm-readobj/XCOFF/file-aux-wrong64.test b/llvm/test/tools/llvm-readobj/XCOFF/file-aux-wrong64.test
new file mode 100644
index 0000000000000..f17e27a071d5a
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/XCOFF/file-aux-wrong64.test
@@ -0,0 +1,19 @@
+## This file tests the raw data output ability when a file auxiliary entry does
+## not have the matching auxiliary type.
+
+# RUN: llvm-readobj --symbols %p/Inputs/file-aux-wrong64.o | FileCheck %s
+
+# CHECK: Symbols [
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Index: 0
+# CHECK-NEXT: Name: .file
+# CHECK-NEXT: Value (SymbolTableIndex): 0x0
+# CHECK-NEXT: Section: N_DEBUG
+# CHECK-NEXT: Source Language ID: 0xC
+# CHECK-NEXT: CPU Version ID: TCPU_PPC64 (0x2)
+# CHECK-NEXT: StorageClass: C_FILE (0x67)
+# CHECK-NEXT: NumberOfAuxEntries: 1
+# CHECK-NEXT: !Unexpected raw auxiliary entry data:
+# CHECK-NEXT: 612e7300 00000000 00000000 00000000 00fb
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
diff --git a/llvm/test/tools/llvm-readobj/XCOFF/symbols64.test b/llvm/test/tools/llvm-readobj/XCOFF/symbols64.test
new file mode 100644
index 0000000000000..f3cfcda6a49e4
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/XCOFF/symbols64.test
@@ -0,0 +1,387 @@
+## This file tests the ability of llvm-readobj to display the symbol table for a
+## 64-bit XCOFF object file.
+## The object file used is generated by the following source file
+## and command on AIX:
+##
+## > cat test8.c
+##
+## extern int i;
+## extern int TestforXcoff;
+## extern int fun(int i);
+## static int static_i;
+## char* p="abcd";
+## int fun1(int j) {
+## static_i++;
+## j++;
+## j=j+*p;
+## return j;
+## }
+##
+## int main() {
+## i++;
+## fun(i);
+## return fun1(i);
+## }
+##
+## > xlc -q64 -c test8.c -o symbol64.o
+
+# RUN: llvm-readobj --symbols %p/Inputs/symbol64.o | \
+# RUN: FileCheck --check-prefix=SYMBOL64 %s
+
+# SYMBOL64: File: {{.*}}symbol64.o
+# SYMBOL64-NEXT: Format: aix5coff64-rs6000
+# SYMBOL64-NEXT: Arch: powerpc64
+# SYMBOL64-NEXT: AddressSize: 64bit
+# SYMBOL64-NEXT: Symbols [
+# SYMBOL64-NEXT: Symbol {
+# SYMBOL64-NEXT: Index: 0
+# SYMBOL64-NEXT: Name: .file
+# SYMBOL64-NEXT: Value (SymbolTableIndex): 0x0
+# SYMBOL64-NEXT: Section: N_DEBUG
+# SYMBOL64-NEXT: Source Language ID: TB_C (0x0)
+# SYMBOL64-NEXT: CPU Version ID: TCPU_PPC64 (0x2)
+# SYMBOL64-NEXT: StorageClass: C_FILE (0x67)
+# SYMBOL64-NEXT: NumberOfAuxEntries: 3
+# SYMBOL64-NEXT: File Auxiliary Entry {
+# SYMBOL64-NEXT: Index: 1
+# SYMBOL64-NEXT: Name: test64.c
+# SYMBOL64-NEXT: Type: XFT_FN (0x0)
+# SYMBOL64-NEXT: Auxiliary Type: AUX_FILE (0xFC)
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: File Auxiliary Entry {
+# SYMBOL64-NEXT: Index: 2
+# SYMBOL64-NEXT: Name: Mon Aug 10 16:07:48 2020
+# SYMBOL64-NEXT: Type: XFT_CT (0x1)
+# SYMBOL64-NEXT: Auxiliary Type: AUX_FILE (0xFC)
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: File Auxiliary Entry {
+# SYMBOL64-NEXT: Index: 3
+# SYMBOL64-NEXT: Name: IBM XL C for AIX, Version 16.1.0.6
+# SYMBOL64-NEXT: Type: XFT_CV (0x2)
+# SYMBOL64-NEXT: Auxiliary Type: AUX_FILE (0xFC)
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: Symbol {
+# SYMBOL64-NEXT: Index: 4
+# SYMBOL64-NEXT: Name:
+# SYMBOL64-NEXT: Value (RelocatableAddress): 0x0
+# SYMBOL64-NEXT: Section: .text
+# SYMBOL64-NEXT: Type: 0x0
+# SYMBOL64-NEXT: StorageClass: C_HIDEXT (0x6B)
+# SYMBOL64-NEXT: NumberOfAuxEntries: 1
+# SYMBOL64-NEXT: CSECT Auxiliary Entry {
+# SYMBOL64-NEXT: Index: 5
+# SYMBOL64-NEXT: SectionLen: 256
+# SYMBOL64-NEXT: ParameterHashIndex: 0x0
+# SYMBOL64-NEXT: TypeChkSectNum: 0x0
+# SYMBOL64-NEXT: SymbolAlignmentLog2: 7
+# SYMBOL64-NEXT: SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT: StorageMappingClass: XMC_PR (0x0)
+# SYMBOL64-NEXT: Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: Symbol {
+# SYMBOL64-NEXT: Index: 6
+# SYMBOL64-NEXT: Name: .fun1
+# SYMBOL64-NEXT: Value (RelocatableAddress): 0x0
+# SYMBOL64-NEXT: Section: .text
+# SYMBOL64-NEXT: Type: 0x20
+# SYMBOL64-NEXT: StorageClass: C_EXT (0x2)
+# SYMBOL64-NEXT: NumberOfAuxEntries: 1
+# SYMBOL64-NEXT: CSECT Auxiliary Entry {
+# SYMBOL64-NEXT: Index: 7
+# SYMBOL64-NEXT: ContainingCsectSymbolIndex: 4
+# SYMBOL64-NEXT: ParameterHashIndex: 0x0
+# SYMBOL64-NEXT: TypeChkSectNum: 0x0
+# SYMBOL64-NEXT: SymbolAlignmentLog2: 0
+# SYMBOL64-NEXT: SymbolType: XTY_LD (0x2)
+# SYMBOL64-NEXT: StorageMappingClass: XMC_PR (0x0)
+# SYMBOL64-NEXT: Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: Symbol {
+# SYMBOL64-NEXT: Index: 8
+# SYMBOL64-NEXT: Name: .main
+# SYMBOL64-NEXT: Value (RelocatableAddress): 0x80
+# SYMBOL64-NEXT: Section: .text
+# SYMBOL64-NEXT: Type: 0x20
+# SYMBOL64-NEXT: StorageClass: C_EXT (0x2)
+# SYMBOL64-NEXT: NumberOfAuxEntries: 1
+# SYMBOL64-NEXT: CSECT Auxiliary Entry {
+# SYMBOL64-NEXT: Index: 9
+# SYMBOL64-NEXT: ContainingCsectSymbolIndex: 4
+# SYMBOL64-NEXT: ParameterHashIndex: 0x0
+# SYMBOL64-NEXT: TypeChkSectNum: 0x0
+# SYMBOL64-NEXT: SymbolAlignmentLog2: 0
+# SYMBOL64-NEXT: SymbolType: XTY_LD (0x2)
+# SYMBOL64-NEXT: StorageMappingClass: XMC_PR (0x0)
+# SYMBOL64-NEXT: Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: Symbol {
+# SYMBOL64-NEXT: Index: 10
+# SYMBOL64-NEXT: Name: TOC
+# SYMBOL64-NEXT: Value (RelocatableAddress): 0x100
+# SYMBOL64-NEXT: Section: .data
+# SYMBOL64-NEXT: Type: 0x0
+# SYMBOL64-NEXT: StorageClass: C_HIDEXT (0x6B)
+# SYMBOL64-NEXT: NumberOfAuxEntries: 1
+# SYMBOL64-NEXT: CSECT Auxiliary Entry {
+# SYMBOL64-NEXT: Index: 11
+# SYMBOL64-NEXT: SectionLen: 0
+# SYMBOL64-NEXT: ParameterHashIndex: 0x0
+# SYMBOL64-NEXT: TypeChkSectNum: 0x0
+# SYMBOL64-NEXT: SymbolAlignmentLog2: 2
+# SYMBOL64-NEXT: SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT: StorageMappingClass: XMC_TC0 (0xF)
+# SYMBOL64-NEXT: Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: Symbol {
+# SYMBOL64-NEXT: Index: 12
+# SYMBOL64-NEXT: Name:
+# SYMBOL64-NEXT: Value (RelocatableAddress): 0x128
+# SYMBOL64-NEXT: Section: .data
+# SYMBOL64-NEXT: Type: 0x0
+# SYMBOL64-NEXT: StorageClass: C_HIDEXT (0x6B)
+# SYMBOL64-NEXT: NumberOfAuxEntries: 1
+# SYMBOL64-NEXT: CSECT Auxiliary Entry {
+# SYMBOL64-NEXT: Index: 13
+# SYMBOL64-NEXT: SectionLen: 8
+# SYMBOL64-NEXT: ParameterHashIndex: 0x0
+# SYMBOL64-NEXT: TypeChkSectNum: 0x0
+# SYMBOL64-NEXT: SymbolAlignmentLog2: 3
+# SYMBOL64-NEXT: SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT: StorageMappingClass: XMC_TC (0x3)
+# SYMBOL64-NEXT: Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: Symbol {
+# SYMBOL64-NEXT: Index: 14
+# SYMBOL64-NEXT: Name:
+# SYMBOL64-NEXT: Value (RelocatableAddress): 0x168
+# SYMBOL64-NEXT: Section: .data
+# SYMBOL64-NEXT: Type: 0x0
+# SYMBOL64-NEXT: StorageClass: C_HIDEXT (0x6B)
+# SYMBOL64-NEXT: NumberOfAuxEntries: 1
+# SYMBOL64-NEXT: CSECT Auxiliary Entry {
+# SYMBOL64-NEXT: Index: 15
+# SYMBOL64-NEXT: SectionLen: 5
+# SYMBOL64-NEXT: ParameterHashIndex: 0x0
+# SYMBOL64-NEXT: TypeChkSectNum: 0x0
+# SYMBOL64-NEXT: SymbolAlignmentLog2: 3
+# SYMBOL64-NEXT: SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT: StorageMappingClass: XMC_RO (0x1)
+# SYMBOL64-NEXT: Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: Symbol {
+# SYMBOL64-NEXT: Index: 16
+# SYMBOL64-NEXT: Name: _$STATIC_BSS
+# SYMBOL64-NEXT: Value (RelocatableAddress): 0x170
+# SYMBOL64-NEXT: Section: .bss
+# SYMBOL64-NEXT: Type: 0x0
+# SYMBOL64-NEXT: StorageClass: C_HIDEXT (0x6B)
+# SYMBOL64-NEXT: NumberOfAuxEntries: 1
+# SYMBOL64-NEXT: CSECT Auxiliary Entry {
+# SYMBOL64-NEXT: Index: 17
+# SYMBOL64-NEXT: SectionLen: 4
+# SYMBOL64-NEXT: ParameterHashIndex: 0x0
+# SYMBOL64-NEXT: TypeChkSectNum: 0x0
+# SYMBOL64-NEXT: SymbolAlignmentLog2: 2
+# SYMBOL64-NEXT: SymbolType: XTY_CM (0x3)
+# SYMBOL64-NEXT: StorageMappingClass: XMC_RW (0x5)
+# SYMBOL64-NEXT: Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: Symbol {
+# SYMBOL64-NEXT: Index: 18
+# SYMBOL64-NEXT: Name: _$STATIC_BSS
+# SYMBOL64-NEXT: Value (RelocatableAddress): 0x108
+# SYMBOL64-NEXT: Section: .data
+# SYMBOL64-NEXT: Type: 0x0
+# SYMBOL64-NEXT: StorageClass: C_HIDEXT (0x6B)
+# SYMBOL64-NEXT: NumberOfAuxEntries: 1
+# SYMBOL64-NEXT: CSECT Auxiliary Entry {
+# SYMBOL64-NEXT: Index: 19
+# SYMBOL64-NEXT: SectionLen: 8
+# SYMBOL64-NEXT: ParameterHashIndex: 0x0
+# SYMBOL64-NEXT: TypeChkSectNum: 0x0
+# SYMBOL64-NEXT: SymbolAlignmentLog2: 3
+# SYMBOL64-NEXT: SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT: StorageMappingClass: XMC_TC (0x3)
+# SYMBOL64-NEXT: Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: Symbol {
+# SYMBOL64-NEXT: Index: 20
+# SYMBOL64-NEXT: Name: fun1
+# SYMBOL64-NEXT: Value (RelocatableAddress): 0x130
+# SYMBOL64-NEXT: Section: .data
+# SYMBOL64-NEXT: Type: 0x0
+# SYMBOL64-NEXT: StorageClass: C_EXT (0x2)
+# SYMBOL64-NEXT: NumberOfAuxEntries: 1
+# SYMBOL64-NEXT: CSECT Auxiliary Entry {
+# SYMBOL64-NEXT: Index: 21
+# SYMBOL64-NEXT: SectionLen: 24
+# SYMBOL64-NEXT: ParameterHashIndex: 0x0
+# SYMBOL64-NEXT: TypeChkSectNum: 0x0
+# SYMBOL64-NEXT: SymbolAlignmentLog2: 3
+# SYMBOL64-NEXT: SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT: StorageMappingClass: XMC_DS (0xA)
+# SYMBOL64-NEXT: Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: Symbol {
+# SYMBOL64-NEXT: Index: 22
+# SYMBOL64-NEXT: Name: fun1
+# SYMBOL64-NEXT: Value (RelocatableAddress): 0x100
+# SYMBOL64-NEXT: Section: .data
+# SYMBOL64-NEXT: Type: 0x0
+# SYMBOL64-NEXT: StorageClass: C_HIDEXT (0x6B)
+# SYMBOL64-NEXT: NumberOfAuxEntries: 1
+# SYMBOL64-NEXT: CSECT Auxiliary Entry {
+# SYMBOL64-NEXT: Index: 23
+# SYMBOL64-NEXT: SectionLen: 8
+# SYMBOL64-NEXT: ParameterHashIndex: 0x0
+# SYMBOL64-NEXT: TypeChkSectNum: 0x0
+# SYMBOL64-NEXT: SymbolAlignmentLog2: 3
+# SYMBOL64-NEXT: SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT: StorageMappingClass: XMC_TC (0x3)
+# SYMBOL64-NEXT: Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: Symbol {
+# SYMBOL64-NEXT: Index: 24
+# SYMBOL64-NEXT: Name: p
+# SYMBOL64-NEXT: Value (RelocatableAddress): 0x160
+# SYMBOL64-NEXT: Section: .data
+# SYMBOL64-NEXT: Type: 0x0
+# SYMBOL64-NEXT: StorageClass: C_EXT (0x2)
+# SYMBOL64-NEXT: NumberOfAuxEntries: 1
+# SYMBOL64-NEXT: CSECT Auxiliary Entry {
+# SYMBOL64-NEXT: Index: 25
+# SYMBOL64-NEXT: SectionLen: 8
+# SYMBOL64-NEXT: ParameterHashIndex: 0x0
+# SYMBOL64-NEXT: TypeChkSectNum: 0x0
+# SYMBOL64-NEXT: SymbolAlignmentLog2: 3
+# SYMBOL64-NEXT: SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT: StorageMappingClass: XMC_RW (0x5)
+# SYMBOL64-NEXT: Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: Symbol {
+# SYMBOL64-NEXT: Index: 26
+# SYMBOL64-NEXT: Name: p
+# SYMBOL64-NEXT: Value (RelocatableAddress): 0x110
+# SYMBOL64-NEXT: Section: .data
+# SYMBOL64-NEXT: Type: 0x0
+# SYMBOL64-NEXT: StorageClass: C_HIDEXT (0x6B)
+# SYMBOL64-NEXT: NumberOfAuxEntries: 1
+# SYMBOL64-NEXT: CSECT Auxiliary Entry {
+# SYMBOL64-NEXT: Index: 27
+# SYMBOL64-NEXT: SectionLen: 8
+# SYMBOL64-NEXT: ParameterHashIndex: 0x0
+# SYMBOL64-NEXT: TypeChkSectNum: 0x0
+# SYMBOL64-NEXT: SymbolAlignmentLog2: 3
+# SYMBOL64-NEXT: SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT: StorageMappingClass: XMC_TC (0x3)
+# SYMBOL64-NEXT: Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: Symbol {
+# SYMBOL64-NEXT: Index: 28
+# SYMBOL64-NEXT: Name: main
+# SYMBOL64-NEXT: Value (RelocatableAddress): 0x148
+# SYMBOL64-NEXT: Section: .data
+# SYMBOL64-NEXT: Type: 0x0
+# SYMBOL64-NEXT: StorageClass: C_EXT (0x2)
+# SYMBOL64-NEXT: NumberOfAuxEntries: 1
+# SYMBOL64-NEXT: CSECT Auxiliary Entry {
+# SYMBOL64-NEXT: Index: 29
+# SYMBOL64-NEXT: SectionLen: 24
+# SYMBOL64-NEXT: ParameterHashIndex: 0x0
+# SYMBOL64-NEXT: TypeChkSectNum: 0x0
+# SYMBOL64-NEXT: SymbolAlignmentLog2: 3
+# SYMBOL64-NEXT: SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT: StorageMappingClass: XMC_DS (0xA)
+# SYMBOL64-NEXT: Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: Symbol {
+# SYMBOL64-NEXT: Index: 30
+# SYMBOL64-NEXT: Name: main
+# SYMBOL64-NEXT: Value (RelocatableAddress): 0x118
+# SYMBOL64-NEXT: Section: .data
+# SYMBOL64-NEXT: Type: 0x0
+# SYMBOL64-NEXT: StorageClass: C_HIDEXT (0x6B)
+# SYMBOL64-NEXT: NumberOfAuxEntries: 1
+# SYMBOL64-NEXT: CSECT Auxiliary Entry {
+# SYMBOL64-NEXT: Index: 31
+# SYMBOL64-NEXT: SectionLen: 8
+# SYMBOL64-NEXT: ParameterHashIndex: 0x0
+# SYMBOL64-NEXT: TypeChkSectNum: 0x0
+# SYMBOL64-NEXT: SymbolAlignmentLog2: 3
+# SYMBOL64-NEXT: SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT: StorageMappingClass: XMC_TC (0x3)
+# SYMBOL64-NEXT: Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: Symbol {
+# SYMBOL64-NEXT: Index: 32
+# SYMBOL64-NEXT: Name: i
+# SYMBOL64-NEXT: Value (RelocatableAddress): 0x0
+# SYMBOL64-NEXT: Section: N_UNDEF
+# SYMBOL64-NEXT: Type: 0x0
+# SYMBOL64-NEXT: StorageClass: C_EXT (0x2)
+# SYMBOL64-NEXT: NumberOfAuxEntries: 1
+# SYMBOL64-NEXT: CSECT Auxiliary Entry {
+# SYMBOL64-NEXT: Index: 33
+# SYMBOL64-NEXT: SectionLen: 0
+# SYMBOL64-NEXT: ParameterHashIndex: 0x0
+# SYMBOL64-NEXT: TypeChkSectNum: 0x0
+# SYMBOL64-NEXT: SymbolAlignmentLog2: 0
+# SYMBOL64-NEXT: SymbolType: XTY_ER (0x0)
+# SYMBOL64-NEXT: StorageMappingClass: XMC_UA (0x4)
+# SYMBOL64-NEXT: Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: Symbol {
+# SYMBOL64-NEXT: Index: 34
+# SYMBOL64-NEXT: Name: i
+# SYMBOL64-NEXT: Value (RelocatableAddress): 0x120
+# SYMBOL64-NEXT: Section: .data
+# SYMBOL64-NEXT: Type: 0x0
+# SYMBOL64-NEXT: StorageClass: C_HIDEXT (0x6B)
+# SYMBOL64-NEXT: NumberOfAuxEntries: 1
+# SYMBOL64-NEXT: CSECT Auxiliary Entry {
+# SYMBOL64-NEXT: Index: 35
+# SYMBOL64-NEXT: SectionLen: 8
+# SYMBOL64-NEXT: ParameterHashIndex: 0x0
+# SYMBOL64-NEXT: TypeChkSectNum: 0x0
+# SYMBOL64-NEXT: SymbolAlignmentLog2: 3
+# SYMBOL64-NEXT: SymbolType: XTY_SD (0x1)
+# SYMBOL64-NEXT: StorageMappingClass: XMC_TC (0x3)
+# SYMBOL64-NEXT: Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: Symbol {
+# SYMBOL64-NEXT: Index: 36
+# SYMBOL64-NEXT: Name: .fun
+# SYMBOL64-NEXT: Value (RelocatableAddress): 0x0
+# SYMBOL64-NEXT: Section: N_UNDEF
+# SYMBOL64-NEXT: Type: 0x0
+# SYMBOL64-NEXT: StorageClass: C_EXT (0x2)
+# SYMBOL64-NEXT: NumberOfAuxEntries: 1
+# SYMBOL64-NEXT: CSECT Auxiliary Entry {
+# SYMBOL64-NEXT: Index: 37
+# SYMBOL64-NEXT: SectionLen: 0
+# SYMBOL64-NEXT: ParameterHashIndex: 0x0
+# SYMBOL64-NEXT: TypeChkSectNum: 0x0
+# SYMBOL64-NEXT: SymbolAlignmentLog2: 0
+# SYMBOL64-NEXT: SymbolType: XTY_ER (0x0)
+# SYMBOL64-NEXT: StorageMappingClass: XMC_PR (0x0)
+# SYMBOL64-NEXT: Auxiliary Type: AUX_CSECT (0xFB)
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: }
+# SYMBOL64-NEXT: ]
diff --git a/llvm/tools/llvm-objdump/XCOFFDump.cpp b/llvm/tools/llvm-objdump/XCOFFDump.cpp
index df37abbd38813..c4cc5fe7e21c7 100644
--- a/llvm/tools/llvm-objdump/XCOFFDump.cpp
+++ b/llvm/tools/llvm-objdump/XCOFFDump.cpp
@@ -46,22 +46,30 @@ Error objdump::getXCOFFRelocationValueString(const XCOFFObjectFile *Obj,
Optional<XCOFF::StorageMappingClass>
objdump::getXCOFFSymbolCsectSMC(const XCOFFObjectFile *Obj,
const SymbolRef &Sym) {
- XCOFFSymbolRef SymRef(Sym.getRawDataRefImpl(), Obj);
+ const XCOFFSymbolRef SymRef = Obj->toSymbolRef(Sym.getRawDataRefImpl());
- if (SymRef.hasCsectAuxEnt())
- return SymRef.getXCOFFCsectAuxEnt32()->StorageMappingClass;
+ if (!SymRef.isCsectSymbol())
+ return None;
- return None;
+ auto CsectAuxEntOrErr = SymRef.getXCOFFCsectAuxRef();
+ if (!CsectAuxEntOrErr)
+ return None;
+
+ return CsectAuxEntOrErr.get().getStorageMappingClass();
}
bool objdump::isLabel(const XCOFFObjectFile *Obj, const SymbolRef &Sym) {
- XCOFFSymbolRef SymRef(Sym.getRawDataRefImpl(), Obj);
+ const XCOFFSymbolRef SymRef = Obj->toSymbolRef(Sym.getRawDataRefImpl());
+
+ if (!SymRef.isCsectSymbol())
+ return false;
- if (SymRef.hasCsectAuxEnt())
- return SymRef.getXCOFFCsectAuxEnt32()->isLabel();
+ auto CsectAuxEntOrErr = SymRef.getXCOFFCsectAuxRef();
+ if (!CsectAuxEntOrErr)
+ return false;
- return false;
+ return CsectAuxEntOrErr.get().isLabel();
}
std::string objdump::getXCOFFSymbolDescription(const SymbolInfoTy &SymbolInfo,
diff --git a/llvm/tools/llvm-readobj/XCOFFDumper.cpp b/llvm/tools/llvm-readobj/XCOFFDumper.cpp
index 5c4bfbd309562..bff2fecfb5d57 100644
--- a/llvm/tools/llvm-readobj/XCOFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/XCOFFDumper.cpp
@@ -40,7 +40,7 @@ class XCOFFDumper : public ObjDumper {
template <typename T> void printGenericSectionHeader(T &Sec) const;
template <typename T> void printOverflowSectionHeader(T &Sec) const;
void printFileAuxEnt(const XCOFFFileAuxEnt *AuxEntPtr);
- void printCsectAuxEnt32(const XCOFFCsectAuxEnt32 *AuxEntPtr);
+ void printCsectAuxEnt(XCOFFCsectAuxRef AuxEntRef);
void printSectAuxEntForStat(const XCOFFSectAuxEntForStat *AuxEntPtr);
void printSymbol(const SymbolRef &);
void printRelocations(ArrayRef<XCOFFSectionHeader32> Sections);
@@ -164,10 +164,17 @@ static const EnumEntry<XCOFF::CFileStringType> FileStringType[] = {
#undef ECase
};
+static const EnumEntry<XCOFF::SymbolAuxType> SymAuxType[] = {
+#define ECase(X) \
+ { #X, XCOFF::X }
+ ECase(AUX_EXCEPT), ECase(AUX_FCN), ECase(AUX_SYM), ECase(AUX_FILE),
+ ECase(AUX_CSECT), ECase(AUX_SECT)
+#undef ECase
+};
+
void XCOFFDumper::printFileAuxEnt(const XCOFFFileAuxEnt *AuxEntPtr) {
- if (Obj.is64Bit())
- report_fatal_error(
- "Printing for File Auxiliary Entry in 64-bit is unimplemented.");
+ assert((!Obj.is64Bit() || AuxEntPtr->AuxType == XCOFF::AUX_FILE) &&
+ "Mismatched auxiliary type!");
StringRef FileName =
unwrapOrError(Obj.getFileName(), Obj.getCFileName(AuxEntPtr));
DictScope SymDs(W, "File Auxiliary Entry");
@@ -176,6 +183,10 @@ void XCOFFDumper::printFileAuxEnt(const XCOFFFileAuxEnt *AuxEntPtr) {
W.printString("Name", FileName);
W.printEnum("Type", static_cast<uint8_t>(AuxEntPtr->Type),
makeArrayRef(FileStringType));
+ if (Obj.is64Bit()) {
+ W.printEnum("Auxiliary Type", static_cast<uint8_t>(AuxEntPtr->AuxType),
+ makeArrayRef(SymAuxType));
+ }
}
static const EnumEntry<XCOFF::StorageMappingClass> CsectStorageMappingClass[] =
@@ -198,27 +209,32 @@ static const EnumEntry<XCOFF::SymbolType> CsectSymbolTypeClass[] = {
#undef ECase
};
-void XCOFFDumper::printCsectAuxEnt32(const XCOFFCsectAuxEnt32 *AuxEntPtr) {
- assert(!Obj.is64Bit() && "32-bit interface called on 64-bit object file.");
+void XCOFFDumper::printCsectAuxEnt(XCOFFCsectAuxRef AuxEntRef) {
+ assert((!Obj.is64Bit() || AuxEntRef.getAuxType64() == XCOFF::AUX_CSECT) &&
+ "Mismatched auxiliary type!");
DictScope SymDs(W, "CSECT Auxiliary Entry");
- W.printNumber("Index",
- Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr)));
- if (AuxEntPtr->isLabel())
- W.printNumber("ContainingCsectSymbolIndex", AuxEntPtr->SectionOrLength);
- else
- W.printNumber("SectionLen", AuxEntPtr->SectionOrLength);
- W.printHex("ParameterHashIndex", AuxEntPtr->ParameterHashIndex);
- W.printHex("TypeChkSectNum", AuxEntPtr->TypeChkSectNum);
+ W.printNumber("Index", Obj.getSymbolIndex(AuxEntRef.getEntryAddress()));
+ W.printNumber(AuxEntRef.isLabel() ? "ContainingCsectSymbolIndex"
+ : "SectionLen",
+ AuxEntRef.getSectionOrLength());
+ W.printHex("ParameterHashIndex", AuxEntRef.getParameterHashIndex());
+ W.printHex("TypeChkSectNum", AuxEntRef.getTypeChkSectNum());
// Print out symbol alignment and type.
- W.printNumber("SymbolAlignmentLog2", AuxEntPtr->getAlignmentLog2());
- W.printEnum("SymbolType", AuxEntPtr->getSymbolType(),
+ W.printNumber("SymbolAlignmentLog2", AuxEntRef.getAlignmentLog2());
+ W.printEnum("SymbolType", AuxEntRef.getSymbolType(),
makeArrayRef(CsectSymbolTypeClass));
W.printEnum("StorageMappingClass",
- static_cast<uint8_t>(AuxEntPtr->StorageMappingClass),
+ static_cast<uint8_t>(AuxEntRef.getStorageMappingClass()),
makeArrayRef(CsectStorageMappingClass));
- W.printHex("StabInfoIndex", AuxEntPtr->StabInfoIndex);
- W.printHex("StabSectNum", AuxEntPtr->StabSectNum);
+
+ if (Obj.is64Bit()) {
+ W.printEnum("Auxiliary Type", static_cast<uint8_t>(XCOFF::AUX_CSECT),
+ makeArrayRef(SymAuxType));
+ } else {
+ W.printHex("StabInfoIndex", AuxEntRef.getStabInfoIndex32());
+ W.printHex("StabSectNum", AuxEntRef.getStabSectNum32());
+ }
}
void XCOFFDumper::printSectAuxEntForStat(
@@ -300,53 +316,62 @@ static const EnumEntry<XCOFF::CFileCpuId> CFileCpuIdClass[] = {
};
void XCOFFDumper::printSymbol(const SymbolRef &S) {
- if (Obj.is64Bit())
- report_fatal_error("64-bit support is unimplemented.");
-
DataRefImpl SymbolDRI = S.getRawDataRefImpl();
- const XCOFFSymbolEntry *SymbolEntPtr = Obj.toSymbolEntry(SymbolDRI);
+ XCOFFSymbolRef SymbolEntRef = Obj.toSymbolRef(SymbolDRI);
- XCOFFSymbolRef XCOFFSymRef(SymbolDRI, &Obj);
- uint8_t NumberOfAuxEntries = XCOFFSymRef.getNumberOfAuxEntries();
+ uint8_t NumberOfAuxEntries = SymbolEntRef.getNumberOfAuxEntries();
DictScope SymDs(W, "Symbol");
StringRef SymbolName =
- unwrapOrError(Obj.getFileName(), Obj.getSymbolName(SymbolDRI));
+ unwrapOrError(Obj.getFileName(), SymbolEntRef.getName());
- W.printNumber("Index",
- Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(SymbolEntPtr)));
+ W.printNumber("Index", Obj.getSymbolIndex(SymbolEntRef.getEntryAddress()));
W.printString("Name", SymbolName);
- W.printHex(GetSymbolValueName(SymbolEntPtr->StorageClass),
- SymbolEntPtr->Value);
+ W.printHex(GetSymbolValueName(SymbolEntRef.getStorageClass()),
+ SymbolEntRef.getValue());
StringRef SectionName =
- unwrapOrError(Obj.getFileName(), Obj.getSymbolSectionName(SymbolEntPtr));
+ unwrapOrError(Obj.getFileName(), Obj.getSymbolSectionName(SymbolEntRef));
W.printString("Section", SectionName);
- if (XCOFFSymRef.getStorageClass() == XCOFF::C_FILE) {
- W.printEnum("Source Language ID",
- SymbolEntPtr->CFileLanguageIdAndTypeId.LanguageId,
+ if (SymbolEntRef.getStorageClass() == XCOFF::C_FILE) {
+ W.printEnum("Source Language ID", SymbolEntRef.getLanguageIdForCFile(),
makeArrayRef(CFileLangIdClass));
- W.printEnum("CPU Version ID",
- SymbolEntPtr->CFileLanguageIdAndTypeId.CpuTypeId,
+ W.printEnum("CPU Version ID", SymbolEntRef.getCPUTypeIddForCFile(),
makeArrayRef(CFileCpuIdClass));
} else
- W.printHex("Type", SymbolEntPtr->SymbolType);
+ W.printHex("Type", SymbolEntRef.getSymbolType());
- W.printEnum("StorageClass", static_cast<uint8_t>(SymbolEntPtr->StorageClass),
+ W.printEnum("StorageClass",
+ static_cast<uint8_t>(SymbolEntRef.getStorageClass()),
makeArrayRef(SymStorageClass));
- W.printNumber("NumberOfAuxEntries", SymbolEntPtr->NumberOfAuxEntries);
+ W.printNumber("NumberOfAuxEntries", NumberOfAuxEntries);
if (NumberOfAuxEntries == 0)
return;
- switch (XCOFFSymRef.getStorageClass()) {
+ switch (SymbolEntRef.getStorageClass()) {
case XCOFF::C_FILE:
// If the symbol is C_FILE and has auxiliary entries...
- for (int i = 1; i <= NumberOfAuxEntries; i++) {
+ for (int I = 1; I <= NumberOfAuxEntries; I++) {
+ uintptr_t AuxAddress = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
+ SymbolEntRef.getEntryAddress(), I);
+
+ if (Obj.is64Bit() &&
+ *Obj.getSymbolAuxType(AuxAddress) != XCOFF::SymbolAuxType::AUX_FILE) {
+ W.startLine() << "!Unexpected raw auxiliary entry data:\n";
+ W.startLine() << format_bytes(
+ ArrayRef<uint8_t>(
+ reinterpret_cast<const uint8_t *>(AuxAddress),
+ XCOFF::SymbolTableEntrySize),
+ 0, XCOFF::SymbolTableEntrySize)
+ << "\n";
+ continue;
+ }
+
const XCOFFFileAuxEnt *FileAuxEntPtr =
- reinterpret_cast<const XCOFFFileAuxEnt *>(SymbolEntPtr + i);
+ reinterpret_cast<const XCOFFFileAuxEnt *>(AuxAddress);
#ifndef NDEBUG
Obj.checkSymbolEntryPointer(reinterpret_cast<uintptr_t>(FileAuxEntPtr));
#endif
@@ -355,34 +380,52 @@ void XCOFFDumper::printSymbol(const SymbolRef &S) {
break;
case XCOFF::C_EXT:
case XCOFF::C_WEAKEXT:
- case XCOFF::C_HIDEXT:
+ case XCOFF::C_HIDEXT: {
// If the symbol is for a function, and it has more than 1 auxiliary entry,
// then one of them must be function auxiliary entry which we do not
// support yet.
- if (XCOFFSymRef.isFunction() && NumberOfAuxEntries >= 2)
+ if (SymbolEntRef.isFunction() && NumberOfAuxEntries >= 2)
report_fatal_error("Function auxiliary entry printing is unimplemented.");
// If there is more than 1 auxiliary entry, instead of printing out
- // error information, print out the raw Auxiliary entry from 1st till
- // the last - 1. The last one must be a CSECT Auxiliary Entry.
- for (int i = 1; i < NumberOfAuxEntries; i++) {
+ // error information, print out the raw Auxiliary entry.
+ // For 32-bit object, print from first to the last - 1. The last one must be
+ // a CSECT Auxiliary Entry.
+ // For 64-bit object, print from first to last and skips if SymbolAuxType is
+ // AUX_CSECT.
+ for (int I = 1; I <= NumberOfAuxEntries; I++) {
+ if (I == NumberOfAuxEntries && !Obj.is64Bit())
+ break;
+
+ uintptr_t AuxAddress = XCOFFObjectFile::getAdvancedSymbolEntryAddress(
+ SymbolEntRef.getEntryAddress(), I);
+ if (Obj.is64Bit() &&
+ *Obj.getSymbolAuxType(AuxAddress) == XCOFF::SymbolAuxType::AUX_CSECT)
+ continue;
+
W.startLine() << "!Unexpected raw auxiliary entry data:\n";
W.startLine() << format_bytes(
- ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(SymbolEntPtr + i),
+ ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(AuxAddress),
XCOFF::SymbolTableEntrySize));
}
- // The symbol's last auxiliary entry is a CSECT Auxiliary Entry.
- printCsectAuxEnt32(XCOFFSymRef.getXCOFFCsectAuxEnt32());
+ auto ErrOrCsectAuxRef = SymbolEntRef.getXCOFFCsectAuxRef();
+ if (!ErrOrCsectAuxRef)
+ reportUniqueWarning(ErrOrCsectAuxRef.takeError());
+ else
+ printCsectAuxEnt(*ErrOrCsectAuxRef);
+
break;
+ }
case XCOFF::C_STAT:
if (NumberOfAuxEntries > 1)
report_fatal_error(
"C_STAT symbol should not have more than 1 auxiliary entry.");
const XCOFFSectAuxEntForStat *StatAuxEntPtr;
- StatAuxEntPtr =
- reinterpret_cast<const XCOFFSectAuxEntForStat *>(SymbolEntPtr + 1);
+ StatAuxEntPtr = reinterpret_cast<const XCOFFSectAuxEntForStat *>(
+ XCOFFObjectFile::getAdvancedSymbolEntryAddress(
+ SymbolEntRef.getEntryAddress(), 1));
#ifndef NDEBUG
Obj.checkSymbolEntryPointer(reinterpret_cast<uintptr_t>(StatAuxEntPtr));
#endif
@@ -398,7 +441,9 @@ void XCOFFDumper::printSymbol(const SymbolRef &S) {
for (int i = 1; i <= NumberOfAuxEntries; i++) {
W.startLine() << "!Unexpected raw auxiliary entry data:\n";
W.startLine() << format_bytes(
- ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(SymbolEntPtr + i),
+ ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(
+ XCOFFObjectFile::getAdvancedSymbolEntryAddress(
+ SymbolEntRef.getEntryAddress(), i)),
XCOFF::SymbolTableEntrySize));
}
break;
diff --git a/llvm/tools/obj2yaml/xcoff2yaml.cpp b/llvm/tools/obj2yaml/xcoff2yaml.cpp
index dd9d8e8750965..0309856556baf 100644
--- a/llvm/tools/obj2yaml/xcoff2yaml.cpp
+++ b/llvm/tools/obj2yaml/xcoff2yaml.cpp
@@ -55,7 +55,7 @@ std::error_code XCOFFDumper::dumpSymbols() {
for (const SymbolRef &S : Obj.symbols()) {
DataRefImpl SymbolDRI = S.getRawDataRefImpl();
- const XCOFFSymbolEntry *SymbolEntPtr = Obj.toSymbolEntry(SymbolDRI);
+ const XCOFFSymbolRef SymbolEntRef = Obj.toSymbolRef(SymbolDRI);
XCOFFYAML::Symbol Sym;
Expected<StringRef> SymNameRefOrErr = Obj.getSymbolName(SymbolDRI);
@@ -64,18 +64,18 @@ std::error_code XCOFFDumper::dumpSymbols() {
}
Sym.SymbolName = SymNameRefOrErr.get();
- Sym.Value = SymbolEntPtr->Value;
+ Sym.Value = SymbolEntRef.getValue();
Expected<StringRef> SectionNameRefOrErr =
- Obj.getSymbolSectionName(SymbolEntPtr);
+ Obj.getSymbolSectionName(SymbolEntRef);
if (!SectionNameRefOrErr)
return errorToErrorCode(SectionNameRefOrErr.takeError());
Sym.SectionName = SectionNameRefOrErr.get();
- Sym.Type = SymbolEntPtr->SymbolType;
- Sym.StorageClass = SymbolEntPtr->StorageClass;
- Sym.NumberOfAuxEntries = SymbolEntPtr->NumberOfAuxEntries;
+ Sym.Type = SymbolEntRef.getSymbolType();
+ Sym.StorageClass = SymbolEntRef.getStorageClass();
+ Sym.NumberOfAuxEntries = SymbolEntRef.getNumberOfAuxEntries();
Symbols.push_back(Sym);
}
diff --git a/llvm/unittests/Object/XCOFFObjectFileTest.cpp b/llvm/unittests/Object/XCOFFObjectFileTest.cpp
index cb1cfe44e077f..71b902c93e3dd 100644
--- a/llvm/unittests/Object/XCOFFObjectFileTest.cpp
+++ b/llvm/unittests/Object/XCOFFObjectFileTest.cpp
@@ -384,3 +384,115 @@ TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtExtLongTBTable) {
"unexpected end of data at offset 0x2c while reading [0x2c, 0x2d)"));
EXPECT_EQ(Size, 44u);
}
+
+TEST(XCOFFObjectFileTest, XCOFFGetCsectAuxRef32) {
+ uint8_t XCOFF32Binary[] = {
+ // File header.
+ 0x01, 0xdf, 0x00, 0x01, 0x5f, 0x58, 0xf8, 0x95, 0x00, 0x00, 0x00, 0x3c,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+
+ // Section header for empty .data section.
+ 0x2e, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40,
+
+ // Start of symbol table.
+ // C_File symbol.
+ 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xfe, 0x00, 0x03, 0x67, 0x01,
+ // File Auxiliary Entry.
+ 0x61, 0x2e, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ // Csect symbol.
+ 0x2e, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x6b, 0x01,
+ // Csect auxiliary entry.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x05,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+ ArrayRef<uint8_t> XCOFF32Ref(XCOFF32Binary, sizeof(XCOFF32Binary));
+ Expected<std::unique_ptr<ObjectFile>> XCOFFObjOrErr =
+ object::ObjectFile::createObjectFile(
+ MemoryBufferRef(toStringRef(XCOFF32Ref), "dummyXCOFF"),
+ file_magic::xcoff_object_32);
+ ASSERT_THAT_EXPECTED(XCOFFObjOrErr, Succeeded());
+
+ const XCOFFObjectFile &File = *cast<XCOFFObjectFile>((*XCOFFObjOrErr).get());
+ DataRefImpl Ref;
+ Ref.p = File.getSymbolEntryAddressByIndex(2);
+ XCOFFSymbolRef SymRef = File.toSymbolRef(Ref);
+ Expected<XCOFFCsectAuxRef> CsectRefOrErr = SymRef.getXCOFFCsectAuxRef();
+ ASSERT_THAT_EXPECTED(CsectRefOrErr, Succeeded());
+
+ // Set csect symbol's auxiliary entry count to 0.
+ XCOFF32Binary[113] = 0;
+ Expected<XCOFFCsectAuxRef> ExpectErr = SymRef.getXCOFFCsectAuxRef();
+ EXPECT_THAT_ERROR(
+ ExpectErr.takeError(),
+ FailedWithMessage("csect symbol \".data\" contains no auxiliary entry"));
+}
+
+TEST(XCOFFObjectFileTest, XCOFFGetCsectAuxRef64) {
+ uint8_t XCOFF64Binary[] = {
+ // File header.
+ 0x01, 0xf7, 0x00, 0x01, 0x5f, 0x59, 0x25, 0xeb, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+
+ // Section header for empty .data section.
+ 0x2e, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+
+ // Start of symbol table.
+ // C_File symbol.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0xff, 0xfe, 0x00, 0x02, 0x67, 0x01,
+ // File Auxiliary Entry.
+ 0x61, 0x2e, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
+
+ // Csect symbol.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
+ 0x00, 0x01, 0x00, 0x00, 0x6b, 0x01,
+ // Csect auxiliary entry.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x05,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb,
+
+ // String table.
+ 0x00, 0x00, 0x00, 0x10, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x2e, 0x64,
+ 0x61, 0x74, 0x61, 0x00};
+
+ ArrayRef<uint8_t> XCOFF64Ref(XCOFF64Binary, sizeof(XCOFF64Binary));
+ Expected<std::unique_ptr<ObjectFile>> XCOFFObjOrErr =
+ object::ObjectFile::createObjectFile(
+ MemoryBufferRef(toStringRef(XCOFF64Ref), "dummyXCOFF"),
+ file_magic::xcoff_object_64);
+ ASSERT_THAT_EXPECTED(XCOFFObjOrErr, Succeeded());
+
+ const XCOFFObjectFile &File = *cast<XCOFFObjectFile>((*XCOFFObjOrErr).get());
+ DataRefImpl Ref;
+ Ref.p = File.getSymbolEntryAddressByIndex(2);
+ XCOFFSymbolRef SymRef = File.toSymbolRef(Ref);
+ Expected<XCOFFCsectAuxRef> CsectRefOrErr = SymRef.getXCOFFCsectAuxRef();
+ ASSERT_THAT_EXPECTED(CsectRefOrErr, Succeeded());
+
+ // Inject incorrect auxiliary type value.
+ XCOFF64Binary[167] = static_cast<uint8_t>(XCOFF::AUX_SYM);
+ Expected<XCOFFCsectAuxRef> NotFoundErr = SymRef.getXCOFFCsectAuxRef();
+ EXPECT_THAT_ERROR(
+ NotFoundErr.takeError(),
+ FailedWithMessage(
+ "a csect auxiliary entry is not found for symbol \".data\""));
+
+ // Set csect symbol's auxiliary entry count to 0.
+ XCOFF64Binary[149] = 0;
+ Expected<XCOFFCsectAuxRef> ExpectErr = SymRef.getXCOFFCsectAuxRef();
+ EXPECT_THAT_ERROR(
+ ExpectErr.takeError(),
+ FailedWithMessage("csect symbol \".data\" contains no auxiliary entry"));
+}
More information about the llvm-commits
mailing list