diff options
author | Virgile Bello <virgile.bello@gmail.com> | 2013-08-25 13:27:20 +0000 |
---|---|---|
committer | Virgile Bello <virgile.bello@gmail.com> | 2013-08-25 13:27:20 +0000 |
commit | a4fe3a12599ce204c3ef16b7b0742c80dc4ea4ed (patch) | |
tree | d247b8192dc2d85fa6523cb9572ba01a0a3ea92b /lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp | |
parent | 8452cb54862b3655cb8fa37ac9ba683b76971e2b (diff) | |
download | bcm5719-llvm-a4fe3a12599ce204c3ef16b7b0742c80dc4ea4ed.tar.gz bcm5719-llvm-a4fe3a12599ce204c3ef16b7b0742c80dc4ea4ed.zip |
PECOFF: Add support for export table.
llvm-svn: 189192
Diffstat (limited to 'lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp')
-rw-r--r-- | lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp index 7afcd6f49a7..566057d829b 100644 --- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp +++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp @@ -591,6 +591,59 @@ ObjectFilePECOFF::GetSymtab() } } + + // Read export header + if (coff_data_dir_export_table < m_coff_header_opt.data_dirs.size() + && m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmsize > 0 && m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr > 0) + { + 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()); + lldb::offset_t offset = 0; + + // Read export_table header + export_table.characteristics = symtab_data.GetU32(&offset); + export_table.time_date_stamp = symtab_data.GetU32(&offset); + export_table.major_version = symtab_data.GetU16(&offset); + export_table.minor_version = symtab_data.GetU16(&offset); + export_table.name = symtab_data.GetU32(&offset); + export_table.base = symtab_data.GetU32(&offset); + export_table.number_of_functions = symtab_data.GetU32(&offset); + export_table.number_of_names = symtab_data.GetU32(&offset); + export_table.address_of_functions = symtab_data.GetU32(&offset); + export_table.address_of_names = symtab_data.GetU32(&offset); + export_table.address_of_name_ordinals = symtab_data.GetU32(&offset); + + bool has_ordinal = export_table.address_of_name_ordinals != 0; + + lldb::offset_t name_offset = export_table.address_of_names - data_start; + lldb::offset_t name_ordinal_offset = export_table.address_of_name_ordinals - data_start; + + Symbol *symbols = m_symtab_ap->Resize(export_table.number_of_names); + + std::string symbol_name; + + // Read each export table entry + for (size_t i = 0; i < export_table.number_of_names; ++i) + { + uint32_t name_ordinal = has_ordinal ? symtab_data.GetU16(&name_ordinal_offset) : i; + uint32_t name_address = symtab_data.GetU32(&name_offset); + + const char* symbol_name_cstr = symtab_data.PeekCStr(name_address - data_start); + symbol_name.assign(symbol_name_cstr); + + lldb::offset_t function_offset = export_table.address_of_functions - data_start + sizeof(uint32_t) * name_ordinal; + uint32_t function_rva = symtab_data.GetU32(&function_offset); + + Address symbol_addr(m_coff_header_opt.image_base + function_rva, sect_list); + symbols[i].GetMangled().SetValue(ConstString(symbol_name.c_str())); + symbols[i].GetAddress() = symbol_addr; + symbols[i].SetType(lldb::eSymbolTypeCode); + symbols[i].SetDebug(true); + } + } } } return m_symtab_ap.get(); |