Fixed issues with the way ELF symbols are parsed:
authorGreg Clayton <gclayton@apple.com>
Sat, 13 Apr 2013 23:17:23 +0000 (23:17 +0000)
committerGreg Clayton <gclayton@apple.com>
Sat, 13 Apr 2013 23:17:23 +0000 (23:17 +0000)
- 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
lldb/include/lldb/Symbol/Symtab.h
lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp
lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h
lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
lldb/source/Symbol/Symbol.cpp
lldb/source/Symbol/Symtab.cpp

index 8235a8875bee3a7f7ccc5af661c5f6e6f9b8db7f..95b5c7269f5462cb587a7cd326770e4883b60b3f 100644 (file)
@@ -38,6 +38,7 @@ public:
             const lldb::SectionSP &section_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);
index 868b0150489ffc92800960d8e99de0433f1a8abe..4f7a24fc47e89fff7f83d31f0d979e26c52e6aaa 100644 (file)
@@ -69,7 +69,6 @@ public:
             size_t      FindAllSymbolsWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes);
             size_t      FindAllSymbolsMatchingRexExAndType (const RegularExpression &regex, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& 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);
index d9cac0d06b3e08dafa64d155fc0caddbe683c681..9387e5d7e1d68f772abdd19735512a0ac48191ac 100644 (file)
@@ -10,6 +10,8 @@
 #include <cstring>
 
 #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)
 {
index 77e5cda398007b1b32b69d93910deed59604b6bc..11ab1dcef445540d7e7b74e1c0d40e2b3197e33e 100644 (file)
@@ -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);
 };
 
 //------------------------------------------------------------------------------
index 37434beac43444a135d29a399da6a2f232f4128a..517c8a1b869a73cb149b02b6a857b21ae01c7217 100644 (file)
@@ -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);
index 0fe0ceb57d7c0d28a6726bb596049174e6de2496..63551d25e604982c54dd7f7d1aad43ff4433a19e 100644 (file)
@@ -53,6 +53,7 @@ Symbol::Symbol
     const lldb::SectionSP &section_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),
index ac39e5a1519331ccb27039e27ba0e52f7e9028e1..3d91b507dbddadbc5df3d2e6e78cb323589916d6 100644 (file)
@@ -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
     }
@@ -1046,27 +1039,6 @@ Symtab::CalculateSymbolSize (Symbol *symbol)
     return byte_size;
 }
 
-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)
 {