wallace updated this revision to Diff 71409.
wallace added a comment.

rebase


https://reviews.llvm.org/D24284

Files:
  source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
  source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h

Index: source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
===================================================================
--- source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
+++ source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
@@ -50,6 +50,10 @@
                    const lldb_private::FileSpec *file,
                    lldb::offset_t file_offset, lldb::offset_t length);
 
+  ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
+                   lldb::DataBufferSP &header_data_sp,
+                   const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);
+
   ~ObjectFilePECOFF() override;
 
   //------------------------------------------------------------------
@@ -128,29 +132,31 @@
 
   uint32_t GetPluginVersion() override;
 
-protected:
-  bool NeedsEndianSwap() const;
-
-  typedef struct dos_header { // DOS .EXE header
-    uint16_t e_magic;         // Magic number
-    uint16_t e_cblp;          // Bytes on last page of file
-    uint16_t e_cp;            // Pages in file
-    uint16_t e_crlc;          // Relocations
-    uint16_t e_cparhdr;       // Size of header in paragraphs
-    uint16_t e_minalloc;      // Minimum extra paragraphs needed
-    uint16_t e_maxalloc;      // Maximum extra paragraphs needed
-    uint16_t e_ss;            // Initial (relative) SS value
-    uint16_t e_sp;            // Initial SP value
-    uint16_t e_csum;          // Checksum
-    uint16_t e_ip;            // Initial IP value
-    uint16_t e_cs;            // Initial (relative) CS value
-    uint16_t e_lfarlc;        // File address of relocation table
-    uint16_t e_ovno;          // Overlay number
-    uint16_t e_res[4];        // Reserved words
-    uint16_t e_oemid;         // OEM identifier (for e_oeminfo)
-    uint16_t e_oeminfo;       // OEM information; e_oemid specific
-    uint16_t e_res2[10];      // Reserved words
-    uint32_t e_lfanew;        // File address of new exe header
+    lldb_private::DataExtractor ReadImageData(uint32_t offset, size_t size);
+
+  protected:
+    bool NeedsEndianSwap() const;
+
+    typedef struct dos_header { // DOS .EXE header
+      uint16_t e_magic;         // Magic number
+      uint16_t e_cblp;          // Bytes on last page of file
+      uint16_t e_cp;            // Pages in file
+      uint16_t e_crlc;          // Relocations
+      uint16_t e_cparhdr;       // Size of header in paragraphs
+      uint16_t e_minalloc;      // Minimum extra paragraphs needed
+      uint16_t e_maxalloc;      // Maximum extra paragraphs needed
+      uint16_t e_ss;            // Initial (relative) SS value
+      uint16_t e_sp;            // Initial SP value
+      uint16_t e_csum;          // Checksum
+      uint16_t e_ip;            // Initial IP value
+      uint16_t e_cs;            // Initial (relative) CS value
+      uint16_t e_lfarlc;        // File address of relocation table
+      uint16_t e_ovno;          // Overlay number
+      uint16_t e_res[4];        // Reserved words
+      uint16_t e_oemid;         // OEM identifier (for e_oeminfo)
+      uint16_t e_oeminfo;       // OEM information; e_oemid specific
+      uint16_t e_res2[10];      // Reserved words
+      uint32_t e_lfanew;        // File address of new exe header
   } dos_header_t;
 
   typedef struct coff_header {
Index: source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
===================================================================
--- source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -10,10 +10,12 @@
 #include "ObjectFilePECOFF.h"
 #include "WindowsMiniDump.h"
 
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/COFF.h"
 
 #include "lldb/Core/ArchSpec.h"
 #include "lldb/Core/DataBuffer.h"
+#include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/FileSpecList.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
@@ -83,6 +85,14 @@
 ObjectFile *ObjectFilePECOFF::CreateMemoryInstance(
     const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
     const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) {
+  if (!data_sp || !ObjectFilePECOFF::MagicBytesMatch(data_sp)) {
+    return NULL;
+  }
+  auto objfile_ap = llvm::make_unique<ObjectFilePECOFF>(
+      module_sp, data_sp, process_sp, header_addr);
+  if (objfile_ap.get() && objfile_ap->ParseHeader()) {
+    return objfile_ap.release();
+  }
   return NULL;
 }
 
@@ -161,6 +171,18 @@
   ::memset(&m_coff_header_opt, 0, sizeof(m_coff_header_opt));
 }
 
+ObjectFilePECOFF::ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
+                                   DataBufferSP &header_data_sp,
+                                   const lldb::ProcessSP &process_sp,
+                                   addr_t header_addr)
+    : ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
+      m_dos_header(), m_coff_header(), m_coff_header_opt(), m_sect_headers(),
+      m_entry_point_address() {
+  ::memset(&m_dos_header, 0, sizeof(m_dos_header));
+  ::memset(&m_coff_header, 0, sizeof(m_coff_header));
+  ::memset(&m_coff_header_opt, 0, sizeof(m_coff_header_opt));
+}
+
 ObjectFilePECOFF::~ObjectFilePECOFF() {}
 
 bool ObjectFilePECOFF::ParseHeader() {
@@ -396,6 +418,28 @@
   return success;
 }
 
+DataExtractor ObjectFilePECOFF::ReadImageData(uint32_t offset, size_t size) {
+  if (m_file) {
+    DataBufferSP buffer_sp(m_file.ReadFileContents(offset, size));
+    return DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize());
+  }
+
+  DataExtractor data;
+  ProcessSP process_sp(m_process_wp.lock());
+  if (process_sp) {
+    auto data_ap = llvm::make_unique<DataBufferHeap>(size, 0);
+    Error readmem_error;
+    size_t bytes_read =
+        process_sp->ReadMemory(m_image_base + offset, data_ap->GetBytes(),
+                               data_ap->GetByteSize(), readmem_error);
+    if (bytes_read == size) {
+      DataBufferSP buffer_sp(data_ap.release());
+      data.SetData(buffer_sp, 0, buffer_sp->GetByteSize());
+    }
+  }
+  return data;
+}
+
 //----------------------------------------------------------------------
 // ParseSectionHeaders
 //----------------------------------------------------------------------
@@ -405,12 +449,9 @@
   m_sect_headers.clear();
 
   if (nsects > 0) {
-    const uint32_t addr_byte_size = GetAddressByteSize();
     const size_t section_header_byte_size = nsects * sizeof(section_header_t);
-    DataBufferSP section_header_data_sp(m_file.ReadFileContents(
-        section_header_data_offset, section_header_byte_size));
-    DataExtractor section_header_data(section_header_data_sp, GetByteOrder(),
-                                      addr_byte_size);
+    DataExtractor section_header_data =
+        ReadImageData(section_header_data_offset, section_header_byte_size);
 
     lldb::offset_t offset = 0;
     if (section_header_data.ValidOffsetForDataOfSize(
@@ -472,66 +513,67 @@
 
       if (num_syms > 0 && m_coff_header.symoff > 0) {
         const uint32_t symbol_size = 18;
-        const uint32_t addr_byte_size = GetAddressByteSize();
         const size_t symbol_data_size = num_syms * symbol_size;
         // Include the 4-byte string table size at the end of the symbols
-        DataBufferSP symtab_data_sp(m_file.ReadFileContents(
-            m_coff_header.symoff, symbol_data_size + 4));
-        DataExtractor symtab_data(symtab_data_sp, GetByteOrder(),
-                                  addr_byte_size);
-        lldb::offset_t offset = symbol_data_size;
-        const uint32_t strtab_size = symtab_data.GetU32(&offset);
-        DataBufferSP strtab_data_sp(m_file.ReadFileContents(
-            m_coff_header.symoff + symbol_data_size, strtab_size));
-        DataExtractor strtab_data(strtab_data_sp, GetByteOrder(),
-                                  addr_byte_size);
-
-        // First 4 bytes should be zeroed after strtab_size has been read,
-        // because it is used as offset 0 to encode a NULL string.
-        uint32_t *strtab_data_start = (uint32_t *)strtab_data_sp->GetBytes();
-        strtab_data_start[0] = 0;
-
-        offset = 0;
-        std::string symbol_name;
-        Symbol *symbols = m_symtab_ap->Resize(num_syms);
-        for (uint32_t i = 0; i < num_syms; ++i) {
-          coff_symbol_t symbol;
-          const uint32_t symbol_offset = offset;
-          const char *symbol_name_cstr = NULL;
-          // If the first 4 bytes of the symbol string are zero, then they
-          // are followed by a 4-byte string table offset. Else these
-          // 8 bytes contain the symbol name
-          if (symtab_data.GetU32(&offset) == 0) {
-            // Long string that doesn't fit into the symbol table name,
-            // so now we must read the 4 byte string table offset
-            uint32_t strtab_offset = symtab_data.GetU32(&offset);
-            symbol_name_cstr = strtab_data.PeekCStr(strtab_offset);
-            symbol_name.assign(symbol_name_cstr);
-          } else {
-            // Short string that fits into the symbol table name which is 8
-            // bytes
-            offset += sizeof(symbol.name) - 4; // Skip remaining
-            symbol_name_cstr = symtab_data.PeekCStr(symbol_offset);
-            if (symbol_name_cstr == NULL)
-              break;
-            symbol_name.assign(symbol_name_cstr, sizeof(symbol.name));
-          }
-          symbol.value = symtab_data.GetU32(&offset);
-          symbol.sect = symtab_data.GetU16(&offset);
-          symbol.type = symtab_data.GetU16(&offset);
-          symbol.storage = symtab_data.GetU8(&offset);
-          symbol.naux = symtab_data.GetU8(&offset);
-          symbols[i].GetMangled().SetValue(ConstString(symbol_name.c_str()));
-          if ((int16_t)symbol.sect >= 1) {
-            Address symbol_addr(sect_list->GetSectionAtIndex(symbol.sect - 1),
-                                symbol.value);
-            symbols[i].GetAddressRef() = symbol_addr;
-            symbols[i].SetType(MapSymbolType(symbol.type));
-          }
-
-          if (symbol.naux > 0) {
-            i += symbol.naux;
-            offset += symbol_size;
+        DataExtractor symtab_data =
+            ReadImageData(m_coff_header.symoff, symbol_data_size + 4);
+        if (symtab_data.GetDataStart() != nullptr) {
+          lldb::offset_t offset = symbol_data_size;
+          const uint32_t strtab_size = symtab_data.GetU32(&offset);
+          DataExtractor strtab_data = ReadImageData(
+              m_coff_header.symoff + symbol_data_size, strtab_size);
+          if (strtab_data.GetDataStart() != nullptr) {
+            // First 4 bytes should be zeroed after strtab_size has been read,
+            // because it is used as offset 0 to encode a NULL string.
+            uint32_t *strtab_data_start =
+                (uint32_t *)strtab_data.GetDataStart();
+            strtab_data_start[0] = 0;
+
+            offset = 0;
+            std::string symbol_name;
+            Symbol *symbols = m_symtab_ap->Resize(num_syms);
+            for (uint32_t i = 0; i < num_syms; ++i) {
+              coff_symbol_t symbol;
+              const uint32_t symbol_offset = offset;
+              const char *symbol_name_cstr = NULL;
+              // If the first 4 bytes of the symbol string are zero, then they
+              // are followed by a 4-byte string table offset. Else these
+              // 8 bytes contain the symbol name
+              if (symtab_data.GetU32(&offset) == 0) {
+                // Long string that doesn't fit into the symbol table name,
+                // so now we must read the 4 byte string table offset
+                uint32_t strtab_offset = symtab_data.GetU32(&offset);
+                symbol_name_cstr = strtab_data.PeekCStr(strtab_offset);
+                symbol_name.assign(symbol_name_cstr);
+              } else {
+                // Short string that fits into the symbol table name which is 8
+                // bytes
+                offset += sizeof(symbol.name) - 4; // Skip remaining
+                symbol_name_cstr = symtab_data.PeekCStr(symbol_offset);
+                if (symbol_name_cstr == NULL)
+                  break;
+                symbol_name.assign(symbol_name_cstr, sizeof(symbol.name));
+              }
+              symbol.value = symtab_data.GetU32(&offset);
+              symbol.sect = symtab_data.GetU16(&offset);
+              symbol.type = symtab_data.GetU16(&offset);
+              symbol.storage = symtab_data.GetU8(&offset);
+              symbol.naux = symtab_data.GetU8(&offset);
+              symbols[i].GetMangled().SetValue(
+                  ConstString(symbol_name.c_str()));
+              if ((int16_t)symbol.sect >= 1) {
+                Address symbol_addr(
+                    sect_list->GetSectionAtIndex(symbol.sect - 1),
+                    symbol.value);
+                symbols[i].GetAddressRef() = symbol_addr;
+                symbols[i].SetType(MapSymbolType(symbol.type));
+              }
+
+              if (symbol.naux > 0) {
+                i += symbol.naux;
+                offset += symbol_size;
+              }
+            }
           }
         }
       }
@@ -544,11 +586,10 @@
         uint32_t data_start =
             m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr;
         Address address(m_coff_header_opt.image_base + data_start, sect_list);
-        DataBufferSP symtab_data_sp(m_file.ReadFileContents(
-            address.GetSection()->GetFileOffset() + address.GetOffset(),
-            m_coff_header_opt.data_dirs[0].vmsize));
-        DataExtractor symtab_data(symtab_data_sp, GetByteOrder(),
-                                  GetAddressByteSize());
+        DataExtractor symtab_data = ReadImageData(
+            address.GetSection()->GetFileOffset() + address.GetOffset() -
+                m_coff_header_opt.image_base,
+            m_coff_header_opt.data_dirs[0].vmsize);
         lldb::offset_t offset = 0;
 
         // Read export_table header
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to