mirror of
https://github.com/RPCS3/llvm.git
synced 2026-07-01 21:04:04 -04:00
[llvm-readobj][xcoff] implement parsing overflow section header.
SUMMARY: in the xcoff, if the number of relocation entries or line number entries is overflow(large than or equal 65535) , there will be overflow section for it. The interpret of overflow section is different with generic section header, the patch implement parsing the overflow section. Reviewers: hubert.reinterpretcast,sfertile,jasonliu Subscribers: rupprecht, seiya Differential Revision: https://reviews.llvm.org/D68575 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@374941 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,47 @@
|
||||
# RUN: llvm-readobj --sections %p/Inputs/xcoff-reloc-overflow.o | \
|
||||
# RUN: FileCheck --check-prefix=SECOVERFLOW %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: ]
|
||||
@@ -43,6 +43,8 @@ public:
|
||||
|
||||
private:
|
||||
template <typename T> void printSectionHeaders(ArrayRef<T> Sections);
|
||||
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 printSectAuxEntForStat(const XCOFFSectAuxEntForStat *AuxEntPtr);
|
||||
@@ -50,6 +52,10 @@ private:
|
||||
|
||||
// Least significant 3 bits are reserved.
|
||||
static constexpr unsigned SectionFlagsReservedMask = 0x7;
|
||||
|
||||
// The low order 16 bits of section flags denotes the section type.
|
||||
static constexpr unsigned SectionFlagsTypeMask = 0xffffu;
|
||||
|
||||
const XCOFFObjectFile &Obj;
|
||||
};
|
||||
} // anonymous namespace
|
||||
@@ -396,6 +402,39 @@ static const EnumEntry<XCOFF::SectionTypeFlags> SectionTypeFlagsNames[] = {
|
||||
#undef ECase
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void XCOFFDumper::printOverflowSectionHeader(T &Sec) const {
|
||||
if (Obj.is64Bit()) {
|
||||
reportWarning(make_error<StringError>("An 64-bit XCOFF object file may not "
|
||||
"contain an overflow section header.",
|
||||
object_error::parse_failed),
|
||||
Obj.getFileName());
|
||||
}
|
||||
|
||||
W.printString("Name", Sec.getName());
|
||||
W.printNumber("NumberOfRelocations", Sec.PhysicalAddress);
|
||||
W.printNumber("NumberOfLineNumbers", Sec.VirtualAddress);
|
||||
W.printHex("Size", Sec.SectionSize);
|
||||
W.printHex("RawDataOffset", Sec.FileOffsetToRawData);
|
||||
W.printHex("RelocationPointer", Sec.FileOffsetToRelocationInfo);
|
||||
W.printHex("LineNumberPointer", Sec.FileOffsetToLineNumberInfo);
|
||||
W.printNumber("IndexOfSectionOverflowed", Sec.NumberOfRelocations);
|
||||
W.printNumber("IndexOfSectionOverflowed", Sec.NumberOfLineNumbers);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void XCOFFDumper::printGenericSectionHeader(T &Sec) const {
|
||||
W.printString("Name", Sec.getName());
|
||||
W.printHex("PhysicalAddress", Sec.PhysicalAddress);
|
||||
W.printHex("VirtualAddress", Sec.VirtualAddress);
|
||||
W.printHex("Size", Sec.SectionSize);
|
||||
W.printHex("RawDataOffset", Sec.FileOffsetToRawData);
|
||||
W.printHex("RelocationPointer", Sec.FileOffsetToRelocationInfo);
|
||||
W.printHex("LineNumberPointer", Sec.FileOffsetToLineNumberInfo);
|
||||
W.printNumber("NumberOfRelocations", Sec.NumberOfRelocations);
|
||||
W.printNumber("NumberOfLineNumbers", Sec.NumberOfLineNumbers);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void XCOFFDumper::printSectionHeaders(ArrayRef<T> Sections) {
|
||||
ListScope Group(W, "Sections");
|
||||
@@ -405,27 +444,28 @@ void XCOFFDumper::printSectionHeaders(ArrayRef<T> Sections) {
|
||||
DictScope SecDS(W, "Section");
|
||||
|
||||
W.printNumber("Index", Index++);
|
||||
W.printString("Name", Sec.getName());
|
||||
|
||||
W.printHex("PhysicalAddress", Sec.PhysicalAddress);
|
||||
W.printHex("VirtualAddress", Sec.VirtualAddress);
|
||||
W.printHex("Size", Sec.SectionSize);
|
||||
W.printHex("RawDataOffset", Sec.FileOffsetToRawData);
|
||||
W.printHex("RelocationPointer", Sec.FileOffsetToRelocationInfo);
|
||||
W.printHex("LineNumberPointer", Sec.FileOffsetToLineNumberInfo);
|
||||
|
||||
// TODO Need to add overflow handling when NumberOfX == _OVERFLOW_MARKER
|
||||
// in 32-bit object files.
|
||||
W.printNumber("NumberOfRelocations", Sec.NumberOfRelocations);
|
||||
W.printNumber("NumberOfLineNumbers", Sec.NumberOfLineNumbers);
|
||||
|
||||
// The most significant 16-bits represent the DWARF section subtype. For
|
||||
// now we just dump the section type flags.
|
||||
uint16_t Flags = Sec.Flags & 0xffffu;
|
||||
if (Flags & SectionFlagsReservedMask)
|
||||
W.printHex("Flags", "Reserved", Flags);
|
||||
uint16_t SectionType = Sec.Flags & SectionFlagsTypeMask;
|
||||
switch (SectionType) {
|
||||
case XCOFF::STYP_OVRFLO:
|
||||
printOverflowSectionHeader(Sec);
|
||||
break;
|
||||
case XCOFF::STYP_LOADER:
|
||||
case XCOFF::STYP_EXCEPT:
|
||||
case XCOFF::STYP_TYPCHK:
|
||||
// TODO The interpretation of loader, exception and type check section
|
||||
// headers are different from that of generic section headers. We will
|
||||
// implement them later. We interpret them as generic section headers for
|
||||
// now.
|
||||
default:
|
||||
printGenericSectionHeader(Sec);
|
||||
break;
|
||||
}
|
||||
// For now we just dump the section type portion of the flags.
|
||||
if (SectionType & SectionFlagsReservedMask)
|
||||
W.printHex("Flags", "Reserved", SectionType);
|
||||
else
|
||||
W.printEnum("Type", Flags, makeArrayRef(SectionTypeFlagsNames));
|
||||
W.printEnum("Type", SectionType, makeArrayRef(SectionTypeFlagsNames));
|
||||
}
|
||||
|
||||
if (opts::SectionRelocations)
|
||||
|
||||
Reference in New Issue
Block a user