mirror of
https://github.com/RPCS3/llvm.git
synced 2026-07-01 21:04:04 -04:00
[XCOFF]implement parsing relocation information for 32-bit xcoff object file
Summary:
Parsing the relocation entry information for 32-bit xcoff object file
including deal with the relocation overflow.
Reviewers: hubert.reinterpretcast, jasonliu, sfertile, xingxue.
Subscribers: hiraditya, rupprecht, seiya
Differential Revision: https://reviews.llvm.org/D67008
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@374946 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -148,6 +148,68 @@ enum SymbolType {
|
||||
XTY_CM = 3 ///< Common csect definition. For uninitialized storage.
|
||||
};
|
||||
|
||||
// Relocation types, defined in `/usr/include/reloc.h`.
|
||||
enum RelocationType : uint8_t {
|
||||
R_POS = 0x00, ///< Positive relocation. Provides the address of the referenced
|
||||
///< symbol.
|
||||
R_RL = 0x0c, ///< Positive indirect load relocation. Modifiable instruction.
|
||||
R_RLA = 0x0d, ///< Positive load address relocation. Modifiable instruction.
|
||||
|
||||
R_NEG = 0x01, ///< Negative relocation. Provides the negative of the address
|
||||
///< of the referenced symbol.
|
||||
R_REL = 0x02, ///< Relative to self relocation. Provides a displacement value
|
||||
///< between the address of the referenced symbol and the
|
||||
///< address being relocated.
|
||||
|
||||
R_TOC = 0x03, ///< Relative to the TOC relocation. Provides a displacement
|
||||
///< that is the difference between the address of the
|
||||
///< referenced symbol and the TOC anchor csect.
|
||||
R_TRL = 0x12, ///< TOC relative indirect load relocation. Similar to R_TOC,
|
||||
///< but not modifiable instruction.
|
||||
|
||||
R_TRLA =
|
||||
0x13, ///< Relative to the TOC or to the thread-local storage base
|
||||
///< relocation. Compilers are not permitted to generate this
|
||||
///< relocation type. It is the result of a reversible
|
||||
///< transformation by the linker of an R_TOC relation that turned a
|
||||
///< load instruction into an add-immediate instruction.
|
||||
|
||||
R_GL = 0x05, ///< Global linkage-external TOC address relocation. Provides the
|
||||
///< address of the external TOC associated with a defined
|
||||
///< external symbol.
|
||||
R_TCL = 0x06, ///< Local object TOC address relocation. Provides the address
|
||||
///< of the local TOC entry of a defined external symbol.
|
||||
|
||||
R_REF = 0x0f, ///< A non-relocating relocation. Used to prevent the binder
|
||||
///< from garbage collecting a csect (such as code used for
|
||||
///< dynamic initialization of non-local statics) for which
|
||||
///< another csect has an implicit dependency.
|
||||
|
||||
R_BA = 0x08, ///< Branch absolute relocation. Provides the address of the
|
||||
///< referenced symbol. References a non-modifiable instruction.
|
||||
R_BR = 0x0a, ///< Branch relative to self relocation. Provides the
|
||||
///< displacement that is the difference between the address of
|
||||
///< the referenced symbol and the address of the referenced
|
||||
///< branch instruction. References a non-modifiable instruction.
|
||||
R_RBA = 0x18, ///< Branch absolute relocation. Similar to R_BA but
|
||||
///< references a modifiable instruction.
|
||||
R_RBR = 0x1a, ///< Branch relative to self relocation. Similar to the R_BR
|
||||
///< relocation type, but references a modifiable instruction.
|
||||
|
||||
R_TLS = 0x20, ///< General-dynamic reference to TLS symbol.
|
||||
R_TLS_IE = 0x21, ///< Initial-exec reference to TLS symbol.
|
||||
R_TLS_LD = 0x22, ///< Local-dynamic reference to TLS symbol.
|
||||
R_TLS_LE = 0x23, ///< Local-exec reference to TLS symbol.
|
||||
R_TLSM = 0x24, ///< Module reference to TLS. Provides a handle for the module
|
||||
///< containing the referenced symbol.
|
||||
R_TLSML = 0x25, ///< Module reference to the local TLS storage.
|
||||
|
||||
R_TOCU = 0x30, ///< Relative to TOC upper. Specifies the high-order 16 bits of
|
||||
///< a large code model TOC-relative relocation.
|
||||
R_TOCL = 0x31 ///< Relative to TOC lower. Specifies the low-order 16 bits of a
|
||||
///< large code model TOC-relative relocation.
|
||||
};
|
||||
|
||||
struct FileHeader32 {
|
||||
uint16_t Magic;
|
||||
uint16_t NumberOfSections;
|
||||
|
||||
@@ -149,6 +149,38 @@ struct XCOFFSectAuxEntForStat {
|
||||
uint8_t Pad[10];
|
||||
};
|
||||
|
||||
struct XCOFFRelocation32 {
|
||||
// Masks for packing/unpacking the r_rsize field of relocations.
|
||||
|
||||
// The msb is used to indicate if the bits being relocated are signed or
|
||||
// unsigned.
|
||||
static constexpr uint8_t XR_SIGN_INDICATOR_MASK = 0x80;
|
||||
|
||||
// The 2nd msb is used to indicate that the binder has replaced/modified the
|
||||
// original instruction.
|
||||
static constexpr uint8_t XR_FIXUP_INDICATOR_MASK = 0x40;
|
||||
|
||||
// The remaining bits specify the bit length of the relocatable reference
|
||||
// minus one.
|
||||
static constexpr uint8_t XR_BIASED_LENGTH_MASK = 0x3f;
|
||||
|
||||
public:
|
||||
support::ubig32_t VirtualAddress;
|
||||
support::ubig32_t SymbolIndex;
|
||||
|
||||
// Packed field, see XR_* masks for details of packing.
|
||||
uint8_t Info;
|
||||
|
||||
XCOFF::RelocationType Type;
|
||||
|
||||
public:
|
||||
bool isRelocationSigned() const;
|
||||
bool isFixupIndicated() const;
|
||||
|
||||
// Returns the number of bits being relocated.
|
||||
uint8_t getRelocatedLength() const;
|
||||
};
|
||||
|
||||
class XCOFFObjectFile : public ObjectFile {
|
||||
private:
|
||||
const void *FileHeader = nullptr;
|
||||
@@ -278,6 +310,7 @@ public:
|
||||
|
||||
uint32_t getNumberOfSymbolTableEntries64() const;
|
||||
uint32_t getSymbolIndex(uintptr_t SymEntPtr) const;
|
||||
Expected<StringRef> getSymbolNameByIndex(uint32_t SymbolTableIndex) const;
|
||||
|
||||
Expected<StringRef> getCFileName(const XCOFFFileAuxEnt *CFileEntPtr) const;
|
||||
uint16_t getOptionalHeaderSize() const;
|
||||
@@ -291,6 +324,13 @@ public:
|
||||
Expected<DataRefImpl> getSectionByNum(int16_t Num) const;
|
||||
|
||||
void checkSymbolEntryPointer(uintptr_t SymbolEntPtr) const;
|
||||
|
||||
// Relocation-related interfaces.
|
||||
Expected<uint32_t>
|
||||
getLogicalNumberOfRelocationEntries(const XCOFFSectionHeader32 &Sec) const;
|
||||
|
||||
Expected<ArrayRef<XCOFFRelocation32>>
|
||||
relocations(const XCOFFSectionHeader32 &) const;
|
||||
}; // XCOFFObjectFile
|
||||
|
||||
class XCOFFSymbolRef {
|
||||
|
||||
@@ -17,10 +17,7 @@
|
||||
namespace llvm {
|
||||
namespace object {
|
||||
|
||||
enum {
|
||||
FUNCTION_SYM = 0x20,
|
||||
SYM_TYPE_MASK = 0x07
|
||||
};
|
||||
enum { FUNCTION_SYM = 0x20, SYM_TYPE_MASK = 0x07, RELOC_OVERFLOW = 65535 };
|
||||
|
||||
// Checks that [Ptr, Ptr + Size) bytes fall inside the memory buffer
|
||||
// 'M'. Returns a pointer to the underlying object on success.
|
||||
@@ -49,6 +46,20 @@ static StringRef generateXCOFFFixedNameStringRef(const char *Name) {
|
||||
: StringRef(Name, XCOFF::NameSize);
|
||||
}
|
||||
|
||||
bool XCOFFRelocation32::isRelocationSigned() const {
|
||||
return Info & XR_SIGN_INDICATOR_MASK;
|
||||
}
|
||||
|
||||
bool XCOFFRelocation32::isFixupIndicated() const {
|
||||
return Info & XR_FIXUP_INDICATOR_MASK;
|
||||
}
|
||||
|
||||
uint8_t XCOFFRelocation32::getRelocatedLength() const {
|
||||
// The relocation encodes the bit length being relocated minus 1. Add back
|
||||
// the 1 to get the actual length being relocated.
|
||||
return (Info & XR_BIASED_LENGTH_MASK) + 1;
|
||||
}
|
||||
|
||||
void XCOFFObjectFile::checkSectionAddress(uintptr_t Addr,
|
||||
uintptr_t TableAddress) const {
|
||||
if (Addr < TableAddress)
|
||||
@@ -494,6 +505,19 @@ uint32_t XCOFFObjectFile::getSymbolIndex(uintptr_t SymbolEntPtr) const {
|
||||
XCOFF::SymbolTableEntrySize;
|
||||
}
|
||||
|
||||
Expected<StringRef>
|
||||
XCOFFObjectFile::getSymbolNameByIndex(uint32_t Index) const {
|
||||
if (is64Bit())
|
||||
report_fatal_error("64-bit symbol table support not implemented yet.");
|
||||
|
||||
if (Index >= getLogicalNumberOfSymbolTableEntries32())
|
||||
return errorCodeToError(object_error::invalid_symbol_index);
|
||||
|
||||
DataRefImpl SymDRI;
|
||||
SymDRI.p = reinterpret_cast<uintptr_t>(getPointerToSymbolTable() + Index);
|
||||
return getSymbolName(SymDRI);
|
||||
}
|
||||
|
||||
uint16_t XCOFFObjectFile::getFlags() const {
|
||||
return is64Bit() ? fileHeader64()->Flags : fileHeader32()->Flags;
|
||||
}
|
||||
@@ -529,6 +553,46 @@ ArrayRef<XCOFFSectionHeader32> XCOFFObjectFile::sections32() const {
|
||||
TablePtr + getNumberOfSections());
|
||||
}
|
||||
|
||||
// In an XCOFF32 file, when the field value is 65535, then an STYP_OVRFLO
|
||||
// section header contains the actual count of relocation entries in the s_paddr
|
||||
// field. STYP_OVRFLO headers contain the section index of their corresponding
|
||||
// sections as their raw "NumberOfRelocations" field value.
|
||||
Expected<uint32_t> XCOFFObjectFile::getLogicalNumberOfRelocationEntries(
|
||||
const XCOFFSectionHeader32 &Sec) const {
|
||||
|
||||
uint16_t SectionIndex = &Sec - sectionHeaderTable32() + 1;
|
||||
|
||||
if (Sec.NumberOfRelocations < RELOC_OVERFLOW)
|
||||
return Sec.NumberOfRelocations;
|
||||
for (const auto &Sec : sections32()) {
|
||||
if (Sec.Flags == XCOFF::STYP_OVRFLO &&
|
||||
Sec.NumberOfRelocations == SectionIndex)
|
||||
return Sec.PhysicalAddress;
|
||||
}
|
||||
return errorCodeToError(object_error::parse_failed);
|
||||
}
|
||||
|
||||
Expected<ArrayRef<XCOFFRelocation32>>
|
||||
XCOFFObjectFile::relocations(const XCOFFSectionHeader32 &Sec) const {
|
||||
uintptr_t RelocAddr = getWithOffset(reinterpret_cast<uintptr_t>(FileHeader),
|
||||
Sec.FileOffsetToRelocationInfo);
|
||||
auto NumRelocEntriesOrErr = getLogicalNumberOfRelocationEntries(Sec);
|
||||
if (Error E = NumRelocEntriesOrErr.takeError())
|
||||
return std::move(E);
|
||||
|
||||
uint32_t NumRelocEntries = NumRelocEntriesOrErr.get();
|
||||
|
||||
auto RelocationOrErr =
|
||||
getObject<XCOFFRelocation32>(Data, reinterpret_cast<void *>(RelocAddr),
|
||||
NumRelocEntries * sizeof(XCOFFRelocation32));
|
||||
if (Error E = RelocationOrErr.takeError())
|
||||
return std::move(E);
|
||||
|
||||
const XCOFFRelocation32 *StartReloc = RelocationOrErr.get();
|
||||
|
||||
return ArrayRef<XCOFFRelocation32>(StartReloc, StartReloc + NumRelocEntries);
|
||||
}
|
||||
|
||||
Expected<XCOFFStringTable>
|
||||
XCOFFObjectFile::parseStringTable(const XCOFFObjectFile *Obj, uint64_t Offset) {
|
||||
// If there is a string table, then the buffer must contain at least 4 bytes
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
# RUN: llvm-readobj --sections %p/Inputs/xcoff-reloc-overflow.o | \
|
||||
# RUN: FileCheck --check-prefix=SECOVERFLOW %s
|
||||
|
||||
# RUN: llvm-readobj --relocs --expand-relocs %p/Inputs/xcoff-reloc-overflow.o | \
|
||||
# RUN: FileCheck --check-prefix=RELOCOVERFLOW %s
|
||||
|
||||
# SECOVERFLOW: File: {{.*}}xcoff-reloc-overflow.o
|
||||
# SECOVERFLOW-NEXT: Format: aixcoff-rs6000
|
||||
# SECOVERFLOW-NEXT: Arch: powerpc
|
||||
# SECOVERFLOW-NEXT: AddressSize: 32bit
|
||||
# SECOVERFLOW-NEXT: Sections [
|
||||
# SECOVERFLOW-NEXT: Section {
|
||||
# SECOVERFLOW-NEXT: Index: 1
|
||||
# SECOVERFLOW-NEXT: Name: .text
|
||||
# SECOVERFLOW-NEXT: PhysicalAddress: 0x0
|
||||
# SECOVERFLOW-NEXT: VirtualAddress: 0x0
|
||||
# SECOVERFLOW-NEXT: Size: 0x38
|
||||
# SECOVERFLOW-NEXT: RawDataOffset: 0x8C
|
||||
# SECOVERFLOW-NEXT: RelocationPointer: 0x0
|
||||
# SECOVERFLOW-NEXT: LineNumberPointer: 0x0
|
||||
# SECOVERFLOW-NEXT: NumberOfRelocations: 0
|
||||
# SECOVERFLOW-NEXT: NumberOfLineNumbers: 0
|
||||
# SECOVERFLOW-NEXT: Type: STYP_TEXT (0x20)
|
||||
# SECOVERFLOW-NEXT: }
|
||||
# SECOVERFLOW-NEXT: Section {
|
||||
# SECOVERFLOW-NEXT: Index: 2
|
||||
# SECOVERFLOW-NEXT: Name: .data
|
||||
# SECOVERFLOW-NEXT: PhysicalAddress: 0x38
|
||||
# SECOVERFLOW-NEXT: VirtualAddress: 0x38
|
||||
# SECOVERFLOW-NEXT: Size: 0x1C
|
||||
# SECOVERFLOW-NEXT: RawDataOffset: 0xC4
|
||||
# SECOVERFLOW-NEXT: RelocationPointer: 0xE0
|
||||
# SECOVERFLOW-NEXT: LineNumberPointer: 0x0
|
||||
# SECOVERFLOW-NEXT: NumberOfRelocations: 65535
|
||||
# SECOVERFLOW-NEXT: NumberOfLineNumbers: 65535
|
||||
# SECOVERFLOW-NEXT: Type: STYP_DATA (0x40)
|
||||
# SECOVERFLOW-NEXT: }
|
||||
# SECOVERFLOW-NEXT: Section {
|
||||
# SECOVERFLOW-NEXT: Index: 3
|
||||
# SECOVERFLOW-NEXT: Name: .ovrflo
|
||||
# SECOVERFLOW-NEXT: NumberOfRelocations: 3
|
||||
# SECOVERFLOW-NEXT: NumberOfLineNumbers: 3
|
||||
# SECOVERFLOW-NEXT: Size: 0x0
|
||||
# SECOVERFLOW-NEXT: RawDataOffset: 0x0
|
||||
# SECOVERFLOW-NEXT: RelocationPointer: 0xE0
|
||||
# SECOVERFLOW-NEXT: LineNumberPointer: 0x0
|
||||
# SECOVERFLOW-NEXT: IndexOfSectionOverflowed: 2
|
||||
# SECOVERFLOW-NEXT: IndexOfSectionOverflowed: 2
|
||||
# SECOVERFLOW-NEXT: Type: STYP_OVRFLO (0x8000)
|
||||
# SECOVERFLOW-NEXT: }
|
||||
# SECOVERFLOW-NEXT: ]
|
||||
|
||||
# RELOCOVERFLOW: Relocations [
|
||||
# RELOCOVERFLOW-NEXT: Section (index: 2) .data {
|
||||
# RELOCOVERFLOW-NEXT: Relocation {
|
||||
# RELOCOVERFLOW-NEXT: Virtual Address: 0x38
|
||||
# RELOCOVERFLOW-NEXT: Symbol: .pb (4)
|
||||
# RELOCOVERFLOW-NEXT: IsSigned: No
|
||||
# RELOCOVERFLOW-NEXT: FixupBitValue: 0
|
||||
# RELOCOVERFLOW-NEXT: Length: 32
|
||||
# RELOCOVERFLOW-NEXT: Type: R_POS (0x0)
|
||||
# RELOCOVERFLOW-NEXT: }
|
||||
# RELOCOVERFLOW-NEXT: Relocation {
|
||||
# RELOCOVERFLOW-NEXT: Virtual Address: 0x3C
|
||||
# RELOCOVERFLOW-NEXT: Symbol: TOC (12)
|
||||
# RELOCOVERFLOW-NEXT: IsSigned: No
|
||||
# RELOCOVERFLOW-NEXT: FixupBitValue: 0
|
||||
# RELOCOVERFLOW-NEXT: Length: 32
|
||||
# RELOCOVERFLOW-NEXT: Type: R_POS (0x0)
|
||||
# RELOCOVERFLOW-NEXT: }
|
||||
# RELOCOVERFLOW-NEXT: Relocation {
|
||||
# RELOCOVERFLOW-NEXT: Virtual Address: 0x50
|
||||
# RELOCOVERFLOW-NEXT: Symbol: .text (2)
|
||||
# RELOCOVERFLOW-NEXT: IsSigned: No
|
||||
# RELOCOVERFLOW-NEXT: FixupBitValue: 0
|
||||
# RELOCOVERFLOW-NEXT: Length: 32
|
||||
# RELOCOVERFLOW-NEXT: Type: R_POS (0x0)
|
||||
# RELOCOVERFLOW-NEXT: }
|
||||
# RELOCOVERFLOW-NEXT: }
|
||||
# RELOCOVERFLOW-NEXT: ]
|
||||
@@ -10,6 +10,9 @@
|
||||
# RUN: llvm-readobj --file-header %p/Inputs/xcoff-basic-neg-sym-count.o | \
|
||||
# RUN: FileCheck --check-prefix=NEGSYMCOUNT %s
|
||||
|
||||
# RUN: llvm-readobj --relocs --expand-relocs %p/Inputs/xcoff-basic.o | \
|
||||
# RUN: FileCheck --check-prefix=RELOCSEXP %s
|
||||
|
||||
# FILEHEADER: File: {{.*}}xcoff-basic.o
|
||||
# FILEHEADER-NEXT: Format: aixcoff-rs6000
|
||||
# FILEHEADER-NEXT: Arch: powerpc
|
||||
@@ -81,3 +84,77 @@
|
||||
# xcoff-basic-neg-sym-count.o was stripped using the 'strip' utility, and
|
||||
# manually edited to have a negative symbol table entry count.
|
||||
|
||||
# RELOCSEXP: File: {{.*}}xcoff-basic.o
|
||||
# RELOCSEXP-NEXT: Format: aixcoff-rs6000
|
||||
# RELOCSEXP-NEXT: Arch: powerpc
|
||||
# RELOCSEXP-NEXT: AddressSize: 32bit
|
||||
# RELOCSEXP-NEXT: Relocations [
|
||||
# RELOCSEXP-NEXT: Section (index: 1) .text {
|
||||
# RELOCSEXP-NEXT: Relocation {
|
||||
# RELOCSEXP-NEXT: Virtual Address: 0x2
|
||||
# RELOCSEXP-NEXT: Symbol: a (85)
|
||||
# RELOCSEXP-NEXT: IsSigned: Yes
|
||||
# RELOCSEXP-NEXT: FixupBitValue: 0
|
||||
# RELOCSEXP-NEXT: Length: 16
|
||||
# RELOCSEXP-NEXT: Type: R_TOC (0x3)
|
||||
# RELOCSEXP-NEXT: }
|
||||
|
||||
# RELOCSEXP: Virtual Address: 0x90
|
||||
# RELOCSEXP-NEXT: Symbol: .__tls_get_addr (118)
|
||||
# RELOCSEXP-NEXT: IsSigned: Yes
|
||||
# RELOCSEXP-NEXT: FixupBitValue: 0
|
||||
# RELOCSEXP-NEXT: Length: 26
|
||||
# RELOCSEXP-NEXT: Type: R_RBA (0x18)
|
||||
# RELOCSEXP-NEXT: }
|
||||
# RELOCSEXP-NEXT: }
|
||||
# RELOCSEXP-NEXT: Section (index: 2) .data {
|
||||
# RELOCSEXP-NEXT: Relocation {
|
||||
# RELOCSEXP-NEXT: Virtual Address: 0x100
|
||||
# RELOCSEXP-NEXT: Symbol: A (78)
|
||||
# RELOCSEXP-NEXT: IsSigned: No
|
||||
# RELOCSEXP-NEXT: FixupBitValue: 0
|
||||
# RELOCSEXP-NEXT: Length: 32
|
||||
# RELOCSEXP-NEXT: Type: R_POS (0x0)
|
||||
# RELOCSEXP-NEXT: }
|
||||
|
||||
# RELOCSEXP: Virtual Address: 0x110
|
||||
# RELOCSEXP-NEXT: Symbol: J (96)
|
||||
# RELOCSEXP-NEXT: IsSigned: No
|
||||
# RELOCSEXP-NEXT: FixupBitValue: 0
|
||||
# RELOCSEXP-NEXT: Length: 32
|
||||
# RELOCSEXP-NEXT: Type: R_POS (0x0)
|
||||
# RELOCSEXP-NEXT: }
|
||||
|
||||
# RELOCSEXP: Virtual Address: 0x114
|
||||
# RELOCSEXP-NEXT: Symbol: j (100)
|
||||
# RELOCSEXP-NEXT: IsSigned: No
|
||||
# RELOCSEXP-NEXT: FixupBitValue: 0
|
||||
# RELOCSEXP-NEXT: Length: 32
|
||||
# RELOCSEXP-NEXT: Type: R_TLS (0x20)
|
||||
# RELOCSEXP-NEXT: }
|
||||
|
||||
# RELOCSEXP: Virtual Address: 0x124
|
||||
# RELOCSEXP-NEXT: Symbol: d (111)
|
||||
# RELOCSEXP-NEXT: IsSigned: No
|
||||
# RELOCSEXP-NEXT: FixupBitValue: 0
|
||||
# RELOCSEXP-NEXT: Length: 32
|
||||
# RELOCSEXP-NEXT: Type: R_TLSM (0x24)
|
||||
# RELOCSEXP-NEXT: }
|
||||
|
||||
# RELOCSEXP: Virtual Address: 0x128
|
||||
# RELOCSEXP-NEXT: Symbol: (76)
|
||||
# RELOCSEXP-NEXT: IsSigned: No
|
||||
# RELOCSEXP-NEXT: FixupBitValue: 0
|
||||
# RELOCSEXP-NEXT: Length: 32
|
||||
# RELOCSEXP-NEXT: Type: R_POS (0x0)
|
||||
# RELOCSEXP-NEXT: }
|
||||
|
||||
# RELOCSEXP: Virtual Address: 0x154
|
||||
# RELOCSEXP-NEXT: Symbol: TOC (72)
|
||||
# RELOCSEXP-NEXT: IsSigned: No
|
||||
# RELOCSEXP-NEXT: FixupBitValue: 0
|
||||
# RELOCSEXP-NEXT: Length: 32
|
||||
# RELOCSEXP-NEXT: Type: R_POS (0x0)
|
||||
# RELOCSEXP-NEXT: }
|
||||
# RELOCSEXP-NEXT: }
|
||||
# RELOCSEXP-NEXT:]
|
||||
|
||||
@@ -56,6 +56,7 @@ private:
|
||||
// The low order 16 bits of section flags denotes the section type.
|
||||
static constexpr unsigned SectionFlagsTypeMask = 0xffffu;
|
||||
|
||||
void printRelocations(ArrayRef<XCOFFSectionHeader32> Sections);
|
||||
const XCOFFObjectFile &Obj;
|
||||
};
|
||||
} // anonymous namespace
|
||||
@@ -115,7 +116,58 @@ void XCOFFDumper::printSectionHeaders() {
|
||||
}
|
||||
|
||||
void XCOFFDumper::printRelocations() {
|
||||
llvm_unreachable("Unimplemented functionality for XCOFFDumper");
|
||||
if (Obj.is64Bit())
|
||||
llvm_unreachable("64-bit relocation output not implemented!");
|
||||
else
|
||||
printRelocations(Obj.sections32());
|
||||
}
|
||||
|
||||
static const EnumEntry<XCOFF::RelocationType> RelocationTypeNameclass[] = {
|
||||
#define ECase(X) \
|
||||
{ #X, XCOFF::X }
|
||||
ECase(R_POS), ECase(R_RL), ECase(R_RLA), ECase(R_NEG),
|
||||
ECase(R_REL), ECase(R_TOC), ECase(R_TRL), ECase(R_TRLA),
|
||||
ECase(R_GL), ECase(R_TCL), ECase(R_REF), ECase(R_BA),
|
||||
ECase(R_BR), ECase(R_RBA), ECase(R_RBR), ECase(R_TLS),
|
||||
ECase(R_TLS_IE), ECase(R_TLS_LD), ECase(R_TLS_LE), ECase(R_TLSM),
|
||||
ECase(R_TLSML), ECase(R_TOCU), ECase(R_TOCL)
|
||||
#undef ECase
|
||||
};
|
||||
|
||||
void XCOFFDumper::printRelocations(ArrayRef<XCOFFSectionHeader32> Sections) {
|
||||
if (!opts::ExpandRelocs)
|
||||
report_fatal_error("Unexpanded relocation output not implemented.");
|
||||
|
||||
ListScope LS(W, "Relocations");
|
||||
uint16_t Index = 0;
|
||||
for (const auto &Sec : Sections) {
|
||||
++Index;
|
||||
// Only the .text, .data, .tdata, and STYP_DWARF sections have relocation.
|
||||
if (Sec.Flags != XCOFF::STYP_TEXT && Sec.Flags != XCOFF::STYP_DATA &&
|
||||
Sec.Flags != XCOFF::STYP_TDATA && Sec.Flags != XCOFF::STYP_DWARF)
|
||||
continue;
|
||||
auto Relocations = unwrapOrError(Obj.getFileName(), Obj.relocations(Sec));
|
||||
if (Relocations.empty())
|
||||
continue;
|
||||
|
||||
W.startLine() << "Section (index: " << Index << ") " << Sec.getName()
|
||||
<< " {\n";
|
||||
for (auto Reloc : Relocations) {
|
||||
StringRef SymbolName = unwrapOrError(
|
||||
Obj.getFileName(), Obj.getSymbolNameByIndex(Reloc.SymbolIndex));
|
||||
|
||||
DictScope RelocScope(W, "Relocation");
|
||||
W.printHex("Virtual Address", Reloc.VirtualAddress);
|
||||
W.printNumber("Symbol", SymbolName, Reloc.SymbolIndex);
|
||||
W.printString("IsSigned", Reloc.isRelocationSigned() ? "Yes" : "No");
|
||||
W.printNumber("FixupBitValue", Reloc.isFixupIndicated() ? 1 : 0);
|
||||
W.printNumber("Length", Reloc.getRelocatedLength());
|
||||
W.printEnum("Type", (uint8_t)Reloc.Type,
|
||||
makeArrayRef(RelocationTypeNameclass));
|
||||
}
|
||||
W.unindent();
|
||||
W.startLine() << "}\n";
|
||||
}
|
||||
}
|
||||
|
||||
static const EnumEntry<XCOFF::CFileStringType> FileStringType[] = {
|
||||
|
||||
Reference in New Issue
Block a user