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