wallace updated this revision to Diff 71995.
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;
 
   //------------------------------------------------------------------
@@ -130,6 +134,8 @@
 
   bool IsWindowsSubsystem();
 
+  lldb_private::DataExtractor ReadImageData(uint32_t offset, size_t size);
+
 protected:
   bool NeedsEndianSwap() const;
 
Index: source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
===================================================================
--- source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -14,6 +14,7 @@
 
 #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 +84,13 @@
 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)) {
+    std::auto_ptr<ObjectFilePECOFF> objfile_ap(
+        new ObjectFilePECOFF(module_sp, data_sp, process_sp, header_addr));
+    if (objfile_ap.get() && objfile_ap->ParseHeader()) {
+      return objfile_ap.release();
+    }
+  }
   return NULL;
 }
 
@@ -161,6 +169,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 +416,28 @@
   return success;
 }
 
+DataExtractor ObjectFilePECOFF::ReadImageData(uint32_t offset, size_t size) {
+  DataExtractor data;
+  if (m_file) {
+    DataBufferSP buffer_sp(m_file.ReadFileContents(offset, size));
+    data = DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize());
+  } else {
+    ProcessSP process_sp(m_process_wp.lock());
+    if (process_sp) {
+      std::unique_ptr<DataBufferHeap> data_ap(new 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 +447,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 +511,63 @@
 
       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);
+
+          // 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 +580,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