[llvm-readobj] Dump COFF Resources section.
authorZachary Turner <zturner@google.com>
Thu, 27 Apr 2017 19:38:38 +0000 (19:38 +0000)
committerZachary Turner <zturner@google.com>
Thu, 27 Apr 2017 19:38:38 +0000 (19:38 +0000)
This patch dumps the raw bytes of the .rsrc sections that
are present in COFF object and executable files.  Subsequent
patches will parse this information and dump in a more human
readable format.

Differential Revision: https://reviews.llvm.org/D32463
Patch By: Eric Beckmann

llvm-svn: 301578

llvm/include/llvm/Object/COFF.h
llvm/test/tools/llvm-readobj/resources.test [new file with mode: 0644]
llvm/tools/llvm-readobj/COFFDumper.cpp
llvm/tools/llvm-readobj/ObjDumper.h
llvm/tools/llvm-readobj/llvm-readobj.cpp

index e0bb8f1..1b6aaf4 100644 (file)
@@ -623,6 +623,15 @@ struct coff_base_reloc_block_entry {
   int getOffset() const { return Data & ((1 << 12) - 1); }
 };
 
+struct coff_resource_dir_table {
+  support::ulittle32_t Characteristics;
+  support::ulittle32_t TimeDateStamp;
+  support::ulittle16_t MajorVersion;
+  support::ulittle16_t MinorVersion;
+  support::ulittle16_t NumberOfNameEntries;
+  support::ulittle16_t NumberOfIDEntries;
+};
+
 class COFFObjectFile : public ObjectFile {
 private:
   friend class ImportDirectoryEntryRef;
diff --git a/llvm/test/tools/llvm-readobj/resources.test b/llvm/test/tools/llvm-readobj/resources.test
new file mode 100644 (file)
index 0000000..46ee8b9
--- /dev/null
@@ -0,0 +1,19 @@
+RUN: llvm-readobj -coff-resources %p/Inputs/zero-string-table.obj.coff-i386 \
+RUN:   | FileCheck %s -check-prefix RESOURCE
+
+RESOURCE:      Resources [
+RESOURCE-NEXT:   Time/Date Stamp: 1970-01-01 00:00:00 (0x0)
+RESOURCE-NEXT:   .rsrc$01 Data (
+RESOURCE-NEXT:     0000: 00000000 00000000 00000000 00000100  |................|
+RESOURCE-NEXT:     0010: 06000000 18000080 00000000 00000000  |................|
+RESOURCE-NEXT:     0020: 00000000 00000100 01000000 30000080  |............0...|
+RESOURCE-NEXT:     0030: 00000000 00000000 00000000 00000100  |................|
+RESOURCE-NEXT:     0040: 09040000 48000000 00000000 2A000000  |....H.......*...|
+RESOURCE-NEXT:     0050: 00000000 00000000                    |........|
+RESOURCE-NEXT:   )
+RESOURCE-NEXT:   .rsrc$02 Data (
+RESOURCE-NEXT:     0000: 00000500 48006500 6C006C00 6F000000  |....H.e.l.l.o...|
+RESOURCE-NEXT:     0010: 00000000 00000000 00000000 00000000  |................|
+RESOURCE-NEXT:     0020: 00000000 00000000 00000000 00000000  |................|
+RESOURCE-NEXT:   )
+RESOURCE-NEXT: ]
index 6359497..4d8ebec 100644 (file)
@@ -79,6 +79,7 @@ public:
   void printCOFFDirectives() override;
   void printCOFFBaseReloc() override;
   void printCOFFDebugDirectory() override;
+  void printCOFFResources() override;
   void printCodeViewDebugInfo() override;
   void mergeCodeViewTypes(llvm::codeview::TypeTableBuilder &CVIDs,
                           llvm::codeview::TypeTableBuilder &CVTypes) override;
@@ -1521,6 +1522,30 @@ void COFFDumper::printCOFFBaseReloc() {
   }
 }
 
+void COFFDumper::printCOFFResources() {
+  ListScope ResourcesD(W, "Resources");
+  for (const SectionRef &S : Obj->sections()) {
+    StringRef Name;
+    error(S.getName(Name));
+    if (!Name.startswith(".rsrc"))
+      continue;
+
+    StringRef Ref;
+    error(S.getContents(Ref));
+
+    if ((Name == ".rsrc") || (Name == ".rsrc$01")) {
+      auto Table =
+          reinterpret_cast<const coff_resource_dir_table *>(Ref.data());
+      char FormattedTime[20];
+      time_t TDS = time_t(Table->TimeDateStamp);
+      strftime(FormattedTime, sizeof(FormattedTime), "%Y-%m-%d %H:%M:%S",
+               gmtime(&TDS));
+      W.printHex("Time/Date Stamp", FormattedTime, Table->TimeDateStamp);
+    }
+    W.printBinaryBlock(Name.str() + " Data", Ref);
+  }
+}
+
 void COFFDumper::printStackMap() const {
   object::SectionRef StackMapSection;
   for (auto Sec : Obj->sections()) {
index ff780da..48f825c 100644 (file)
@@ -67,6 +67,7 @@ public:
   virtual void printCOFFDirectives() { }
   virtual void printCOFFBaseReloc() { }
   virtual void printCOFFDebugDirectory() { }
+  virtual void printCOFFResources() {}
   virtual void printCodeViewDebugInfo() { }
   virtual void mergeCodeViewTypes(llvm::codeview::TypeTableBuilder &CVIDs,
                                   llvm::codeview::TypeTableBuilder &CVTypes) {}
index bc2a62e..8a9d7bc 100644 (file)
@@ -214,6 +214,10 @@ namespace opts {
   COFFDebugDirectory("coff-debug-directory",
                      cl::desc("Display the PE/COFF debug directory"));
 
+  // -coff-resources
+  cl::opt<bool> COFFResources("coff-resources",
+                              cl::desc("Display the PE/COFF .rsrc section"));
+
   // -macho-data-in-code
   cl::opt<bool>
   MachODataInCode("macho-data-in-code",
@@ -445,6 +449,8 @@ static void dumpObject(const ObjectFile *Obj) {
       Dumper->printCOFFBaseReloc();
     if (opts::COFFDebugDirectory)
       Dumper->printCOFFDebugDirectory();
+    if (opts::COFFResources)
+      Dumper->printCOFFResources();
     if (opts::CodeView)
       Dumper->printCodeViewDebugInfo();
     if (opts::CodeViewMergedTypes)