--- /dev/null
+# 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: ]
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);
// 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
#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");
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)