llvm-objdump/COFF: Print SEH table addresses.
authorRui Ueyama <ruiu@google.com>
Thu, 20 Feb 2014 06:51:07 +0000 (06:51 +0000)
committerRui Ueyama <ruiu@google.com>
Thu, 20 Feb 2014 06:51:07 +0000 (06:51 +0000)
SEH table addresses are VA in COFF file. In this patch we convert VA to RVA
before printing it, because dumpbin prints them as RVAs.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201760 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Object/COFF.h
lib/Object/COFFObjectFile.cpp
test/tools/llvm-objdump/coff-private-headers.test
tools/llvm-objdump/COFFDump.cpp

index a7a112a8648b53ffe45069b70d50d9f00b0e9a61..dd36067485faaf82508fdd63bb8fa45645a8f4a5 100644 (file)
@@ -397,6 +397,7 @@ public:
   error_code getSectionContents(const coff_section *Sec,
                                 ArrayRef<uint8_t> &Res) const;
 
+  error_code getVaPtr(uint32_t Rva, uintptr_t &Res) const;
   error_code getRvaPtr(uint32_t Rva, uintptr_t &Res) const;
   error_code getHintName(uint32_t Rva, uint16_t &Hint, StringRef &Name) const;
 
index a1bbc56d2be55c1ccf5250e80dafeb1c9507d9dc..85b2f0b91d7c32d94102d6acaff1c350e5a948f5 100644 (file)
@@ -381,15 +381,21 @@ error_code COFFObjectFile::initSymbolTablePtr() {
   return object_error::success;
 }
 
+// Returns the file offset for the given VA.
+error_code COFFObjectFile::getVaPtr(uint32_t Addr, uintptr_t &Res) const {
+  uint32_t ImageBase = PE32Header ? PE32Header->ImageBase : PE32PlusHeader->ImageBase;
+  return getRvaPtr(Addr - ImageBase, Res);
+}
+
 // Returns the file offset for the given RVA.
-error_code COFFObjectFile::getRvaPtr(uint32_t Rva, uintptr_t &Res) const {
+error_code COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const {
   for (section_iterator I = section_begin(), E = section_end(); I != E;
        ++I) {
     const coff_section *Section = getCOFFSection(I);
     uint32_t SectionStart = Section->VirtualAddress;
     uint32_t SectionEnd = Section->VirtualAddress + Section->VirtualSize;
-    if (SectionStart <= Rva && Rva < SectionEnd) {
-      uint32_t Offset = Rva - SectionStart;
+    if (SectionStart <= Addr && Addr < SectionEnd) {
+      uint32_t Offset = Addr - SectionStart;
       Res = uintptr_t(base()) + Section->PointerToRawData + Offset;
       return object_error::success;
     }
index cd186a44b5fcbf426aaf361d62ffaf91b3b5aa57..51bf4435389c9edd4ed190c551775f7ce9596671 100644 (file)
@@ -64,3 +64,4 @@ LOADCFG-NEXT:   CSD Version: 0
 LOADCFG-NEXT:   Security Cookie: 4206616
 LOADCFG-NEXT:   SEH Table: 4202768
 LOADCFG-NEXT:   SEH Count: 1
+LOADCFG:      SEH Table: 0x401689
index 883786d4f6645c7baf54645080a9a8432e07bec3..91ca5ba7e2e1f84222f4953bd6459abc575fd4fa 100644 (file)
@@ -233,6 +233,25 @@ static void printCOFFSymbolAddress(llvm::raw_ostream &Out,
     Out << format(" + 0x%04x", Disp);
 }
 
+static void
+printSEHTable(const COFFObjectFile *Obj, uint32_t TableVA, int Count) {
+  if (Count == 0)
+    return;
+
+  const pe32_header *PE32Header;
+  if (error(Obj->getPE32Header(PE32Header)))
+    return;
+  uint32_t ImageBase = PE32Header->ImageBase;
+  uintptr_t IntPtr = 0;
+  if (error(Obj->getVaPtr(TableVA, IntPtr)))
+    return;
+  const support::ulittle32_t *P = (const support::ulittle32_t *)IntPtr;
+  outs() << "SEH Table:";
+  for (int I = 0; I < Count; ++I)
+    outs() << format(" 0x%x", P[I] + ImageBase);
+  outs() << "\n\n";
+}
+
 static void printLoadConfiguration(const COFFObjectFile *Obj) {
   const coff_file_header *Header;
   if (error(Obj->getCOFFHeader(Header)))
@@ -249,6 +268,7 @@ static void printLoadConfiguration(const COFFObjectFile *Obj) {
     return;
   if (error(Obj->getRvaPtr(DataDir->RelativeVirtualAddress, IntPtr)))
     return;
+
   const coff_load_configuration32 *LoadConf =
       reinterpret_cast<const coff_load_configuration32 *>(IntPtr);
 
@@ -271,6 +291,8 @@ static void printLoadConfiguration(const COFFObjectFile *Obj) {
          << "\n  SEH Table: " << LoadConf->SEHandlerTable
          << "\n  SEH Count: " << LoadConf->SEHandlerCount
          << "\n\n";
+  printSEHTable(Obj, LoadConf->SEHandlerTable, LoadConf->SEHandlerCount);
+  outs() << "\n";
 }
 
 // Prints import tables. The import table is a table containing the list of