From 1875dcc47887b2ba582e26b7014ba1eaa82ea1de Mon Sep 17 00:00:00 2001 From: Digger Lin Date: Tue, 15 Oct 2019 19:28:11 +0000 Subject: [PATCH] [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 llvm-svn: 374941 --- .../llvm-readobj/Inputs/xcoff-reloc-overflow.o | Bin 0 -> 558 bytes .../tools/llvm-readobj/xcoff-overflow-section.test | 47 ++++++++++++ llvm/tools/llvm-readobj/XCOFFDumper.cpp | 80 +++++++++++++++------ 3 files changed, 107 insertions(+), 20 deletions(-) create mode 100644 llvm/test/tools/llvm-readobj/Inputs/xcoff-reloc-overflow.o create mode 100644 llvm/test/tools/llvm-readobj/xcoff-overflow-section.test diff --git a/llvm/test/tools/llvm-readobj/Inputs/xcoff-reloc-overflow.o b/llvm/test/tools/llvm-readobj/Inputs/xcoff-reloc-overflow.o new file mode 100644 index 0000000000000000000000000000000000000000..16f058a29860e5d5695b31c311a8bf8a32650498 GIT binary patch literal 558 zcmZ8e!AiqG5PjKH!CI)ntI#dp_nd=J!K0u(Cn%`BT)k?V{j!Uv%w zprW93YL<@=^Tm=S-+?(tDXW443cP(+KkH#tK8^PCDHWcN&+~8u{X+Uh0WDtWY2m>m zuAx@(z>2&^Ep1qRua5XmNbd<76H^12`Q0LM=4u1~*2|JKGuO?2B7deq=ic+#+?OJ- z31$^LMv3Z*J@ii;E@8_OvM7Ce))RDX{_l}KySApBXKU)?rccLuhC4P#muHsnRO+*w d67=hmWZoI^yU2Z9pToVz)1Syl;xwJ0`wIzLJH7w_ literal 0 HcmV?d00001 diff --git a/llvm/test/tools/llvm-readobj/xcoff-overflow-section.test b/llvm/test/tools/llvm-readobj/xcoff-overflow-section.test new file mode 100644 index 0000000..8ff911b --- /dev/null +++ b/llvm/test/tools/llvm-readobj/xcoff-overflow-section.test @@ -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: ] diff --git a/llvm/tools/llvm-readobj/XCOFFDumper.cpp b/llvm/tools/llvm-readobj/XCOFFDumper.cpp index c48d7ed..219ee58 100644 --- a/llvm/tools/llvm-readobj/XCOFFDumper.cpp +++ b/llvm/tools/llvm-readobj/XCOFFDumper.cpp @@ -43,6 +43,8 @@ public: private: template void printSectionHeaders(ArrayRef Sections); + template void printGenericSectionHeader(T &Sec) const; + template 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 @@ -397,6 +403,39 @@ static const EnumEntry SectionTypeFlagsNames[] = { }; template +void XCOFFDumper::printOverflowSectionHeader(T &Sec) const { + if (Obj.is64Bit()) { + reportWarning(make_error("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 +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 void XCOFFDumper::printSectionHeaders(ArrayRef Sections) { ListScope Group(W, "Sections"); @@ -405,27 +444,28 @@ void XCOFFDumper::printSectionHeaders(ArrayRef 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) -- 2.7.4