From 9594f4c8183ec59f8c9e35620fe52540060eb8aa Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Sat, 13 Apr 2013 23:17:23 +0000 Subject: [PATCH] Fixed issues with the way ELF symbols are parsed: - Do not add symbols with no names - Make sure that symbols from ELF symbol tables know that the byte size is correct. Previously the symbols would calculate their sizes by looking for the next symbol and take symbols that had zero size and make them have invalid sizes. - Added the ability to dump raw ELF symbols by adding a Dump method to ELFSymbol Also removed some unused code from lldb_private::Symtab. llvm-svn: 179466 --- lldb/include/lldb/Symbol/Symbol.h | 2 + lldb/include/lldb/Symbol/Symtab.h | 1 - lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp | 86 ++++++++++++++++++++++ lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h | 16 ++++ .../Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 14 +++- lldb/source/Symbol/Symbol.cpp | 6 +- lldb/source/Symbol/Symtab.cpp | 32 +------- 7 files changed, 122 insertions(+), 35 deletions(-) diff --git a/lldb/include/lldb/Symbol/Symbol.h b/lldb/include/lldb/Symbol/Symbol.h index 8235a88..95b5c72 100644 --- a/lldb/include/lldb/Symbol/Symbol.h +++ b/lldb/include/lldb/Symbol/Symbol.h @@ -38,6 +38,7 @@ public: const lldb::SectionSP §ion_sp, lldb::addr_t value, lldb::addr_t size, + bool size_is_valid, uint32_t flags); Symbol (uint32_t symID, @@ -49,6 +50,7 @@ public: bool is_trampoline, bool is_artificial, const AddressRange &range, + bool size_is_valid, uint32_t flags); Symbol (const Symbol& rhs); diff --git a/lldb/include/lldb/Symbol/Symtab.h b/lldb/include/lldb/Symbol/Symtab.h index 868b015..4f7a24f 100644 --- a/lldb/include/lldb/Symbol/Symtab.h +++ b/lldb/include/lldb/Symbol/Symtab.h @@ -69,7 +69,6 @@ public: size_t FindAllSymbolsWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector& symbol_indexes); size_t FindAllSymbolsMatchingRexExAndType (const RegularExpression ®ex, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector& symbol_indexes); Symbol * FindFirstSymbolWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility); - Symbol * FindSymbolWithFileAddress (lldb::addr_t file_addr); Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes); Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr); size_t FindFunctionSymbols (const ConstString &name, uint32_t name_type_mask, SymbolContextList& sc_list); diff --git a/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp b/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp index d9cac0d..9387e5d 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp @@ -10,6 +10,8 @@ #include #include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Section.h" +#include "lldb/Core/Stream.h" #include "ELFHeader.h" @@ -233,6 +235,90 @@ ELFSymbol::ELFSymbol() memset(this, 0, sizeof(ELFSymbol)); } +#define ENUM_TO_CSTR(e) case e: return #e + +const char * +ELFSymbol::bindingToCString(unsigned char binding) +{ + switch (binding) + { + ENUM_TO_CSTR(STB_LOCAL); + ENUM_TO_CSTR(STB_GLOBAL); + ENUM_TO_CSTR(STB_WEAK); + ENUM_TO_CSTR(STB_LOOS); + ENUM_TO_CSTR(STB_HIOS); + ENUM_TO_CSTR(STB_LOPROC); + ENUM_TO_CSTR(STB_HIPROC); + } + return ""; +} + +const char * +ELFSymbol::typeToCString(unsigned char type) +{ + switch (type) + { + ENUM_TO_CSTR(STT_NOTYPE); + ENUM_TO_CSTR(STT_OBJECT); + ENUM_TO_CSTR(STT_FUNC); + ENUM_TO_CSTR(STT_SECTION); + ENUM_TO_CSTR(STT_FILE); + ENUM_TO_CSTR(STT_COMMON); + ENUM_TO_CSTR(STT_TLS); + ENUM_TO_CSTR(STT_LOOS); + ENUM_TO_CSTR(STT_HIOS); + ENUM_TO_CSTR(STT_GNU_IFUNC); + ENUM_TO_CSTR(STT_LOPROC); + ENUM_TO_CSTR(STT_HIPROC); + } + return ""; +} + +const char * +ELFSymbol::sectionIndexToCString (elf_half shndx, + const lldb_private::SectionList *section_list) +{ + switch (shndx) + { + ENUM_TO_CSTR(SHN_UNDEF); + ENUM_TO_CSTR(SHN_LOPROC); + ENUM_TO_CSTR(SHN_HIPROC); + ENUM_TO_CSTR(SHN_LOOS); + ENUM_TO_CSTR(SHN_HIOS); + ENUM_TO_CSTR(SHN_ABS); + ENUM_TO_CSTR(SHN_COMMON); + ENUM_TO_CSTR(SHN_XINDEX); + default: + { + const lldb_private::Section *section = section_list->GetSectionAtIndex(shndx).get(); + if (section) + return section->GetName().AsCString(""); + } + break; + } + return ""; +} + +void +ELFSymbol::Dump (lldb_private::Stream *s, + uint32_t idx, + const lldb_private::DataExtractor *strtab_data, + const lldb_private::SectionList *section_list) +{ + s->Printf("[%3u] 0x%16.16llx 0x%16.16llx 0x%8.8x 0x%2.2x (%-10s %-13s) 0x%2.2x 0x%4.4x (%-10s) %s\n", + idx, + st_value, + st_size, + st_name, + st_info, + bindingToCString (getBinding()), + typeToCString (getType()), + st_other, + st_shndx, + sectionIndexToCString (st_shndx, section_list), + strtab_data ? strtab_data->PeekCStr(st_name) : ""); +} + bool ELFSymbol::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset) { diff --git a/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h b/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h index 77e5cda..11ab1dc 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h +++ b/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h @@ -244,6 +244,16 @@ struct ELFSymbol st_info = (binding << 4) + (type & 0x0F); } + static const char * + bindingToCString(unsigned char binding); + + static const char * + typeToCString(unsigned char type); + + static const char * + sectionIndexToCString(elf_half shndx, + const lldb_private::SectionList *section_list); + /// Parse an ELFSymbol entry from the given DataExtractor starting at /// position \p offset. The address size of the DataExtractor determines if /// a 32 or 64 bit object is to be parsed. @@ -260,6 +270,12 @@ struct ELFSymbol /// True if the ELFSymbol was successfully read and false otherwise. bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); + + void + Dump (lldb_private::Stream *s, + uint32_t idx, + const lldb_private::DataExtractor *strtab_data, + const lldb_private::SectionList *section_list); }; //------------------------------------------------------------------------------ diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 37434be..517c8a1 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -725,11 +725,20 @@ ParseSymbols(Symtab *symtab, static ConstString data2_section_name(".data1"); static ConstString bss_section_name(".bss"); + //StreamFile strm(stdout, false); unsigned i; for (i = 0; i < num_symbols; ++i) { if (symbol.Parse(symtab_data, &offset) == false) break; + + const char *symbol_name = strtab_data.PeekCStr(symbol.st_name); + + // No need to add symbols that have no names + if (symbol_name == NULL || symbol_name[0] == '\0') + continue; + + //symbol.Dump (&strm, i, &strtab_data, section_list); SectionSP symbol_section_sp; SymbolType symbol_type = eSymbolTypeInvalid; @@ -780,7 +789,7 @@ ParseSymbols(Symtab *symtab, // file associated with the object file. A file symbol has STB_LOCAL // binding, its section index is SHN_ABS, and it precedes the other // STB_LOCAL symbols for the file, if it is present. - symbol_type = eSymbolTypeObjectFile; + symbol_type = eSymbolTypeSourceFile; break; case STT_GNU_IFUNC: @@ -818,7 +827,6 @@ ParseSymbols(Symtab *symtab, uint64_t symbol_value = symbol.st_value; if (symbol_section_sp) symbol_value -= symbol_section_sp->GetFileAddress(); - const char *symbol_name = strtab_data.PeekCStr(symbol.st_name); bool is_global = symbol.getBinding() == STB_GLOBAL; uint32_t flags = symbol.st_other << 8 | symbol.st_info; bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false; @@ -834,6 +842,7 @@ ParseSymbols(Symtab *symtab, symbol_section_sp, // Section in which this symbol is defined or null. symbol_value, // Offset in section or symbol value. symbol.st_size, // Size in bytes of this symbol. + true, // Size is valid flags); // Symbol flags. symtab->AddSymbol(dc_symbol); } @@ -1027,6 +1036,7 @@ ParsePLTRelocations(Symtab *symbol_table, plt_section_sp, // Section in which this symbol is defined or null. plt_index, // Offset in section or symbol value. plt_entsize, // Size in bytes of this symbol. + true, // Size is valid 0); // Symbol flags. symbol_table->AddSymbol(jump_symbol); diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp index 0fe0ceb..63551d2 100644 --- a/lldb/source/Symbol/Symbol.cpp +++ b/lldb/source/Symbol/Symbol.cpp @@ -53,6 +53,7 @@ Symbol::Symbol const lldb::SectionSP §ion_sp, addr_t offset, addr_t size, + bool size_is_valid, uint32_t flags ) : SymbolContextScope (), @@ -65,7 +66,7 @@ Symbol::Symbol m_is_external (external), m_size_is_sibling (false), m_size_is_synthesized (false), - m_calculated_size (size > 0), + m_calculated_size (size_is_valid || size > 0), m_demangled_is_synthesized (false), m_type (type), m_flags (flags), @@ -84,6 +85,7 @@ Symbol::Symbol bool is_trampoline, bool is_artificial, const AddressRange &range, + bool size_is_valid, uint32_t flags ) : SymbolContextScope (), @@ -96,7 +98,7 @@ Symbol::Symbol m_is_external (external), m_size_is_sibling (false), m_size_is_synthesized (false), - m_calculated_size (range.GetByteSize() > 0), + m_calculated_size (size_is_valid || range.GetByteSize() > 0), m_demangled_is_synthesized (false), m_type (type), m_flags (flags), diff --git a/lldb/source/Symbol/Symtab.cpp b/lldb/source/Symbol/Symtab.cpp index ac39e5a..3d91b50 100644 --- a/lldb/source/Symbol/Symtab.cpp +++ b/lldb/source/Symbol/Symtab.cpp @@ -947,14 +947,7 @@ Symtab::InitAddressIndexes() if (!m_addr_indexes_computed && !m_symbols.empty()) { m_addr_indexes_computed = true; -#if 0 - // The old was to add only code, trampoline or data symbols... - AppendSymbolIndexesWithType (eSymbolTypeCode, m_addr_indexes); - AppendSymbolIndexesWithType (eSymbolTypeTrampoline, m_addr_indexes); - AppendSymbolIndexesWithType (eSymbolTypeData, m_addr_indexes); -#else - // The new way adds all symbols with valid addresses that are section - // offset. + const_iterator begin = m_symbols.begin(); const_iterator end = m_symbols.end(); for (const_iterator pos = m_symbols.begin(); pos != end; ++pos) @@ -962,7 +955,7 @@ Symtab::InitAddressIndexes() if (pos->ValueIsAddress()) m_addr_indexes.push_back (std::distance(begin, pos)); } -#endif + SortSymbolIndexesByValue (m_addr_indexes, false); m_addr_indexes.push_back (UINT32_MAX); // Terminator for bsearch since we might need to look at the next symbol } @@ -1047,27 +1040,6 @@ Symtab::CalculateSymbolSize (Symbol *symbol) } Symbol * -Symtab::FindSymbolWithFileAddress (addr_t file_addr) -{ - Mutex::Locker locker (m_mutex); - - if (!m_addr_indexes_computed) - InitAddressIndexes(); - - SymbolSearchInfo info = { this, file_addr, NULL, NULL, 0 }; - - uint32_t* match = (uint32_t*)::bsearch (&info, - &m_addr_indexes[0], - m_addr_indexes.size(), - sizeof(uint32_t), - (ComparisonFunction)SymbolWithFileAddress); - if (match) - return SymbolAtIndex (*match); - return NULL; -} - - -Symbol * Symtab::FindSymbolContainingFileAddress (addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes) { Mutex::Locker locker (m_mutex); -- 2.7.4