]> granicus.if.org Git - llvm/commitdiff
[llvm-readobj][xcoff] implement parsing overflow section header.
authorDigger Lin <digger.llvm@gmail.com>
Tue, 15 Oct 2019 19:28:11 +0000 (19:28 +0000)
committerDigger Lin <digger.llvm@gmail.com>
Tue, 15 Oct 2019 19:28:11 +0000 (19:28 +0000)
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

test/tools/llvm-readobj/Inputs/xcoff-reloc-overflow.o [new file with mode: 0644]
test/tools/llvm-readobj/xcoff-overflow-section.test [new file with mode: 0644]
tools/llvm-readobj/XCOFFDumper.cpp

diff --git a/test/tools/llvm-readobj/Inputs/xcoff-reloc-overflow.o b/test/tools/llvm-readobj/Inputs/xcoff-reloc-overflow.o
new file mode 100644 (file)
index 0000000..16f058a
Binary files /dev/null and b/test/tools/llvm-readobj/Inputs/xcoff-reloc-overflow.o differ
diff --git a/test/tools/llvm-readobj/xcoff-overflow-section.test b/test/tools/llvm-readobj/xcoff-overflow-section.test
new file mode 100644 (file)
index 0000000..8ff911b
--- /dev/null
@@ -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: ]
index c48d7ed78e0c44cfaadc34d638e44d4153f74a44..219ee58be0ad7f827ddfacd80b9aec367a3e6873 100644 (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)