wallace created this revision.
wallace added reviewers: zturner, sas.
wallace added a subscriber: LLDB.
wallace set the repository for this revision to rL LLVM.
wallace added a project: LLDB.

When the local lldb doesn't have access to a copy of the modules in the target, 
e.g. winphone, with this change now we read these modules from memory.

There are mainly 3 changes:
1. set the correct OS when definingn the arch of pecoff files
2. create pecoff object files from memory
3. read from memory when the local file is not available


Repository:
  rL LLVM

https://reviews.llvm.org/D24284

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

Index: lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
===================================================================
--- lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
+++ lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
@@ -166,6 +166,13 @@
     bool
     IsThumb();
 
+    ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
+                     lldb::DataBufferSP& header_data_sp,
+                     const lldb::ProcessSP &process_sp,
+                     lldb::addr_t header_addr);
+
+    lldb_private::DataExtractor ReadImageData(uint32_t offset, size_t size);
+
 protected:
 	bool NeedsEndianSwap() const;    
     
Index: lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
===================================================================
--- lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ lldb/trunk/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/Host/FileSpec.h"
 #include "lldb/Core/FileSpecList.h"
 #include "lldb/Core/Module.h"
@@ -101,6 +102,12 @@
                                         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;
 }
 
@@ -205,6 +212,21 @@
     ::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()
 {
@@ -465,6 +487,33 @@
     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
@@ -477,10 +526,8 @@
     
     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 (offset, section_header_byte_size))
@@ -551,69 +598,68 @@
             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)
+                DataExtractor symtab_data = ReadImageData (m_coff_header.symoff, symbol_data_size + 4);
+                if (symtab_data.GetDataStart() != nullptr)
                 {
-                    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)
+                    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)
                     {
-                        // 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;
+                        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;
+                        }
                     }
                 }
-                
             }
 
             // Read export header
@@ -623,8 +669,7 @@
                 export_directory_entry export_table;
                 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
@@ -1087,7 +1132,7 @@
         case llvm::COFF::IMAGE_FILE_MACHINE_ARM:
         case llvm::COFF::IMAGE_FILE_MACHINE_ARMNT:
         case llvm::COFF::IMAGE_FILE_MACHINE_THUMB:
-            arch.SetArchitecture (eArchTypeCOFF, machine, LLDB_INVALID_CPUTYPE);
+            arch.SetArchitecture (eArchTypeCOFF, machine, LLDB_INVALID_CPUTYPE, llvm::Triple::Win32);
             return true;
         default:
             break;
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to