const lldb::SectionSP §ion_sp,
lldb::addr_t value,
lldb::addr_t size,
+ bool size_is_valid,
uint32_t flags);
Symbol (uint32_t symID,
bool is_trampoline,
bool is_artificial,
const AddressRange &range,
+ bool size_is_valid,
uint32_t flags);
Symbol (const Symbol& rhs);
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 ®ex, 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);
#include <cstring>
#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Core/Stream.h"
#include "ELFHeader.h"
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)
{
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.
/// 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);
};
//------------------------------------------------------------------------------
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;
// 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:
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;
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);
}
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);
const lldb::SectionSP §ion_sp,
addr_t offset,
addr_t size,
+ bool size_is_valid,
uint32_t flags
) :
SymbolContextScope (),
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),
bool is_trampoline,
bool is_artificial,
const AddressRange &range,
+ bool size_is_valid,
uint32_t flags
) :
SymbolContextScope (),
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),
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)
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
}
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)
{