[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:
Digger Lin
2019-10-15 19:28:11 +00:00
parent 62e7137cb9
commit 382c1a971c
3 changed files with 106 additions and 19 deletions
@@ -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: ]
+59 -19
View File
@@ -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)