mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-14 09:25:25 +00:00
[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
This commit is contained in:
parent
30de816da1
commit
c03aed5d1b
@ -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);
|
||||
|
@ -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 @@ public:
|
||||
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 @@ private:
|
||||
// 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 @@ public:
|
||||
// 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 @@ public:
|
||||
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 @@ public:
|
||||
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!");
|
||||
|
||||
XCOFF::StorageClass getStorageClass() const;
|
||||
uint8_t getNumberOfAuxEntries() const;
|
||||
const XCOFFCsectAuxEnt32 *getXCOFFCsectAuxEnt32() const;
|
||||
uint16_t getType() const;
|
||||
int16_t getSectionNumber() const;
|
||||
if (OwningObjectPtr->is64Bit())
|
||||
Entry64 = reinterpret_cast<const XCOFFSymbolEntry64 *>(SymEntDataRef.p);
|
||||
else
|
||||
Entry32 = reinterpret_cast<const XCOFFSymbolEntry32 *>(SymEntDataRef.p);
|
||||
}
|
||||
|
||||
bool hasCsectAuxEnt() const;
|
||||
uint64_t getValue() const { return Entry32 ? getValue32() : getValue64(); }
|
||||
|
||||
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 {
|
||||
|
@ -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;
|
||||
|
||||
if (getSymbolType() & FunctionSym)
|
||||
return true;
|
||||
|
||||
Expected<XCOFFCsectAuxRef> ExpCsectAuxEnt = getXCOFFCsectAuxRef();
|
||||
if (!ExpCsectAuxEnt)
|
||||
return false;
|
||||
|
||||
const XCOFFCsectAuxRef CsectAuxRef = ExpCsectAuxEnt.get();
|
||||
|
||||
// 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;
|
||||
|
||||
if (CsectAuxRef.getStorageMappingClass() != XCOFF::XMC_PR)
|
||||
return false;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return (OwningObjectPtr->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT);
|
||||
}
|
||||
|
||||
uint8_t XCOFFSymbolRef::getNumberOfAuxEntries() const {
|
||||
return OwningObjectPtr->toSymbolEntry(SymEntDataRef)->NumberOfAuxEntries;
|
||||
}
|
||||
|
||||
// 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.");
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
BIN
test/tools/llvm-objdump/XCOFF/Inputs/xcoff-section-headers64.o
Normal file
BIN
test/tools/llvm-objdump/XCOFF/Inputs/xcoff-section-headers64.o
Normal file
Binary file not shown.
@ -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: ...
|
BIN
test/tools/llvm-readobj/XCOFF/Inputs/file-aux-wrong64.o
Normal file
BIN
test/tools/llvm-readobj/XCOFF/Inputs/file-aux-wrong64.o
Normal file
Binary file not shown.
BIN
test/tools/llvm-readobj/XCOFF/Inputs/symbol64.o
Normal file
BIN
test/tools/llvm-readobj/XCOFF/Inputs/symbol64.o
Normal file
Binary file not shown.
19
test/tools/llvm-readobj/XCOFF/file-aux-wrong64.test
Normal file
19
test/tools/llvm-readobj/XCOFF/file-aux-wrong64.test
Normal file
@ -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: ]
|
387
test/tools/llvm-readobj/XCOFF/symbols64.test
Normal file
387
test/tools/llvm-readobj/XCOFF/symbols64.test
Normal file
@ -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: ]
|
@ -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.hasCsectAuxEnt())
|
||||
return SymRef.getXCOFFCsectAuxEnt32()->isLabel();
|
||||
if (!SymRef.isCsectSymbol())
|
||||
return false;
|
||||
|
||||
return false;
|
||||
auto CsectAuxEntOrErr = SymRef.getXCOFFCsectAuxRef();
|
||||
if (!CsectAuxEntOrErr)
|
||||
return false;
|
||||
|
||||
return CsectAuxEntOrErr.get().isLabel();
|
||||
}
|
||||
|
||||
std::string objdump::getXCOFFSymbolDescription(const SymbolInfoTy &SymbolInfo,
|
||||
|
@ -40,7 +40,7 @@ private:
|
||||
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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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"));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user