Skip to content

Commit

Permalink
Improve the handling of missing elf symtab and missing symbol sizes
Browse files Browse the repository at this point in the history
* Generate artificial symbol names from eh_fame during symbol parsing
  so these symbols are already present when we calcualte the size of
  the symbols where 0 is specified.
* Fix symbol size calculation for the last symbol in the file where
  it have to last until the end of the parent section.

Differential revision: http://reviews.llvm.org/D16996

llvm-svn: 260369
  • Loading branch information
Tamas Berghammer committed Feb 10, 2016
1 parent 10e9923 commit ed844cb
Show file tree
Hide file tree
Showing 10 changed files with 151 additions and 145 deletions.
20 changes: 19 additions & 1 deletion lldb/include/lldb/Core/RangeMap.h
Expand Up @@ -1123,7 +1123,7 @@ namespace lldb_private {
// Calculate the byte size of ranges with zero byte sizes by finding
// the next entry with a base address > the current base address
void
CalculateSizesOfZeroByteSizeRanges ()
CalculateSizesOfZeroByteSizeRanges (S full_size = 0)
{
#ifdef ASSERT_RANGEMAP_ARE_SORTED
assert (IsSorted());
Expand All @@ -1148,6 +1148,8 @@ namespace lldb_private {
break;
}
}
if (next == end && full_size > curr_base)
pos->SetByteSize (full_size - curr_base);
}
}
}
Expand Down Expand Up @@ -1305,6 +1307,22 @@ namespace lldb_private {
return nullptr;
}

const Entry*
FindEntryStartsAt (B addr) const
{
#ifdef ASSERT_RANGEMAP_ARE_SORTED
assert (IsSorted());
#endif
if (!m_entries.empty())
{
auto begin = m_entries.begin(), end = m_entries.end();
auto pos = std::lower_bound (begin, end, Entry(addr, 1), BaseLessThan);
if (pos != end && pos->base == addr)
return &(*pos);
}
return nullptr;
}

Entry *
Back()
{
Expand Down
3 changes: 3 additions & 0 deletions lldb/include/lldb/Symbol/DWARFCallFrameInfo.h
Expand Up @@ -73,6 +73,9 @@ class DWARFCallFrameInfo
void
GetFunctionAddressAndSizeVector (FunctionAddressAndSizeVector &function_info);

void
ForEachFDEEntries(const std::function<bool(lldb::addr_t, uint32_t, dw_offset_t)>& callback);

private:
enum
{
Expand Down
7 changes: 6 additions & 1 deletion lldb/include/lldb/Symbol/ObjectFile.h
Expand Up @@ -860,6 +860,7 @@ friend class lldb_private::Module;
const lldb::addr_t m_memory_addr;
std::unique_ptr<lldb_private::SectionList> m_sections_ap;
std::unique_ptr<lldb_private::Symtab> m_symtab_ap;
uint32_t m_synthetic_symbol_idx;

//------------------------------------------------------------------
/// Sets the architecture for a module. At present the architecture
Expand All @@ -873,7 +874,11 @@ friend class lldb_private::Module;
/// Returns \b true if the architecture was changed, \b
/// false otherwise.
//------------------------------------------------------------------
bool SetModulesArchitecture (const ArchSpec &new_arch);
bool
SetModulesArchitecture (const ArchSpec &new_arch);

ConstString
GetNextSyntheticSymbolName();

private:
DISALLOW_COPY_AND_ASSIGN (ObjectFile);
Expand Down
2 changes: 1 addition & 1 deletion lldb/include/lldb/Symbol/Symtab.h
Expand Up @@ -79,7 +79,7 @@ class Symtab
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 * FindSymbolContainingFileAddress (lldb::addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes);
Symbol * FindSymbolAtFileAddress (lldb::addr_t file_addr);
Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr);
void ForEachSymbolContainingFileAddress(lldb::addr_t file_addr, std::function<bool(Symbol *)> const &callback);
size_t FindFunctionSymbols (const ConstString &name, uint32_t name_type_mask, SymbolContextList& sc_list);
Expand Down
107 changes: 61 additions & 46 deletions lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
Expand Up @@ -2332,11 +2332,11 @@ ObjectFileELF::ParseSymbols (Symtab *symtab,
mangled.SetDemangledName( ConstString((demangled_name + suffix).str()) );
}

// In ELF all symbol should have a valid size but it is not true for some code symbols
// coming from hand written assembly. As none of the code symbol should have 0 size we try
// to calculate the size for these symbols in the symtab with saying that their original
// In ELF all symbol should have a valid size but it is not true for some function symbols
// coming from hand written assembly. As none of the function symbol should have 0 size we
// try to calculate the size for these symbols in the symtab with saying that their original
// size is not valid.
bool symbol_size_valid = symbol.st_size != 0 || symbol_type != eSymbolTypeCode;
bool symbol_size_valid = symbol.st_size != 0 || symbol.getType() != STT_FUNC;

Symbol dc_symbol(
i + start_id, // ID is the original symbol table index.
Expand Down Expand Up @@ -2863,6 +2863,14 @@ ObjectFileELF::GetSymtab()
}
}

DWARFCallFrameInfo* eh_frame = GetUnwindTable().GetEHFrameInfo();
if (eh_frame)
{
if (m_symtab_ap == nullptr)
m_symtab_ap.reset(new Symtab(this));
ParseUnwindSymbols (m_symtab_ap.get(), eh_frame);
}

// If we still don't have any symtab then create an empty instance to avoid do the section
// lookup next time.
if (m_symtab_ap == nullptr)
Expand Down Expand Up @@ -2892,57 +2900,64 @@ ObjectFileELF::GetSymtab()
return m_symtab_ap.get();
}

Symbol *
ObjectFileELF::ResolveSymbolForAddress(const Address& so_addr, bool verify_unique)
void
ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table, DWARFCallFrameInfo* eh_frame)
{
if (!m_symtab_ap.get())
return nullptr; // GetSymtab() should be called first.

const SectionList *section_list = GetSectionList();
SectionList* section_list = GetSectionList();
if (!section_list)
return nullptr;
return;

if (DWARFCallFrameInfo *eh_frame = GetUnwindTable().GetEHFrameInfo())
{
AddressRange range;
if (eh_frame->GetAddressRange (so_addr, range))
// First we save the new symbols into a separate list and add them to the symbol table after
// we colleced all symbols we want to add. This is neccessary because adding a new symbol
// invalidates the internal index of the symtab what causing the next lookup to be slow because
// it have to recalculate the index first.
std::vector<Symbol> new_symbols;

eh_frame->ForEachFDEEntries(
[this, symbol_table, section_list, &new_symbols](lldb::addr_t file_addr,
uint32_t size,
dw_offset_t) {
Symbol* symbol = symbol_table->FindSymbolAtFileAddress(file_addr);
if (symbol)
{
const addr_t file_addr = range.GetBaseAddress().GetFileAddress();
Symbol * symbol = verify_unique ? m_symtab_ap->FindSymbolContainingFileAddress(file_addr) : nullptr;
if (symbol)
return symbol;

// Note that a (stripped) symbol won't be found by GetSymtab()...
lldb::SectionSP eh_sym_section_sp = section_list->FindSectionContainingFileAddress(file_addr);
if (eh_sym_section_sp.get())
if (!symbol->GetByteSizeIsValid())
{
addr_t section_base = eh_sym_section_sp->GetFileAddress();
addr_t offset = file_addr - section_base;
uint64_t symbol_id = m_symtab_ap->GetNumSymbols();

symbol->SetByteSize(size);
symbol->SetSizeIsSynthesized(true);
}
}
else
{
SectionSP section_sp = section_list->FindSectionContainingFileAddress(file_addr);
if (section_sp)
{
addr_t offset = file_addr - section_sp->GetFileAddress();
const char* symbol_name = GetNextSyntheticSymbolName().GetCString();
uint64_t symbol_id = symbol_table->GetNumSymbols();
Symbol eh_symbol(
symbol_id, // Symbol table index.
"???", // Symbol name.
false, // Is the symbol name mangled?
eSymbolTypeCode, // Type of this symbol.
true, // Is this globally visible?
false, // Is this symbol debug info?
false, // Is this symbol a trampoline?
true, // Is this symbol artificial?
eh_sym_section_sp, // Section in which this symbol is defined or null.
offset, // Offset in section or symbol value.
range.GetByteSize(), // Size in bytes of this symbol.
true, // Size is valid.
false, // Contains linker annotations?
0); // Symbol flags.
if (symbol_id == m_symtab_ap->AddSymbol(eh_symbol))
return m_symtab_ap->SymbolAtIndex(symbol_id);
symbol_id, // Symbol table index.
symbol_name, // Symbol name.
false, // Is the symbol name mangled?
eSymbolTypeCode, // Type of this symbol.
true, // Is this globally visible?
false, // Is this symbol debug info?
false, // Is this symbol a trampoline?
true, // Is this symbol artificial?
section_sp, // Section in which this symbol is defined or null.
offset, // Offset in section or symbol value.
0, // Size: Don't specify the size as an FDE can
false, // Size is valid: cover multiple symbols.
false, // Contains linker annotations?
0); // Symbol flags.
new_symbols.push_back(eh_symbol);
}
}
}
return nullptr;
}
return true;
});

for (const Symbol& s : new_symbols)
symbol_table->AddSymbol(s);
}

bool
ObjectFileELF::IsStripped ()
Expand Down
7 changes: 4 additions & 3 deletions lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
Expand Up @@ -150,9 +150,6 @@ class ObjectFileELF :
lldb_private::Symtab *
GetSymtab() override;

lldb_private::Symbol *
ResolveSymbolForAddress(const lldb_private::Address& so_addr, bool verify_unique) override;

bool
IsStripped () override;

Expand Down Expand Up @@ -349,6 +346,10 @@ class ObjectFileELF :
const ELFSectionHeaderInfo *rela_hdr,
lldb::user_id_t section_id);

void
ParseUnwindSymbols(lldb_private::Symtab *symbol_table,
lldb_private::DWARFCallFrameInfo* eh_frame);

/// Relocates debug sections
unsigned
RelocateDebugSections(const elf::ELFSectionHeader *rel_hdr, lldb::user_id_t rel_id);
Expand Down
9 changes: 1 addition & 8 deletions lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
Expand Up @@ -4517,7 +4517,6 @@ ObjectFileMachO::ParseSymtab ()

if (function_starts_count > 0)
{
char synthetic_function_symbol[PATH_MAX];
uint32_t num_synthetic_function_symbols = 0;
for (i=0; i<function_starts_count; ++i)
{
Expand All @@ -4532,7 +4531,6 @@ ObjectFileMachO::ParseSymtab ()
num_syms = sym_idx + num_synthetic_function_symbols;
sym = symtab->Resize (num_syms);
}
uint32_t synthetic_function_symbol_idx = 0;
for (i=0; i<function_starts_count; ++i)
{
const FunctionStarts::Entry *func_start_entry = function_starts.GetEntryAtIndex (i);
Expand Down Expand Up @@ -4567,13 +4565,8 @@ ObjectFileMachO::ParseSymtab ()
{
symbol_byte_size = section_end_file_addr - symbol_file_addr;
}
snprintf (synthetic_function_symbol,
sizeof(synthetic_function_symbol),
"___lldb_unnamed_function%u$$%s",
++synthetic_function_symbol_idx,
module_sp->GetFileSpec().GetFilename().GetCString());
sym[sym_idx].SetID (synthetic_sym_id++);
sym[sym_idx].GetMangled().SetDemangledName(ConstString(synthetic_function_symbol));
sym[sym_idx].GetMangled().SetDemangledName(GetNextSyntheticSymbolName());
sym[sym_idx].SetType (eSymbolTypeCode);
sym[sym_idx].SetIsSynthetic (true);
sym[sym_idx].GetAddressRef() = symbol_addr;
Expand Down
14 changes: 14 additions & 0 deletions lldb/source/Symbol/DWARFCallFrameInfo.cpp
Expand Up @@ -899,3 +899,17 @@ DWARFCallFrameInfo::HandleCommonDwarfOpcode(uint8_t primary_opcode,
}
return false;
}

void
DWARFCallFrameInfo::ForEachFDEEntries(
const std::function<bool(lldb::addr_t, uint32_t, dw_offset_t)>& callback)
{
GetFDEIndex();

for (size_t i = 0, c = m_fde_index.GetSize(); i < c; ++i)
{
const FDEEntryMap::Entry& entry = m_fde_index.GetEntryRef(i);
if (!callback(entry.base, entry.size, entry.data))
break;
}
}
19 changes: 15 additions & 4 deletions lldb/source/Symbol/ObjectFile.cpp
Expand Up @@ -241,8 +241,7 @@ ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp,
lldb::offset_t file_offset,
lldb::offset_t length,
const lldb::DataBufferSP& data_sp,
lldb::offset_t data_offset
) :
lldb::offset_t data_offset) :
ModuleChild (module_sp),
m_file (), // This file could be different from the original module's file
m_type (eTypeInvalid),
Expand All @@ -254,7 +253,8 @@ ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp,
m_process_wp(),
m_memory_addr (LLDB_INVALID_ADDRESS),
m_sections_ap(),
m_symtab_ap ()
m_symtab_ap (),
m_synthetic_symbol_idx (0)
{
if (file_spec_ptr)
m_file = *file_spec_ptr;
Expand Down Expand Up @@ -286,7 +286,8 @@ ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp,
m_process_wp (process_sp),
m_memory_addr (header_addr),
m_sections_ap(),
m_symtab_ap ()
m_symtab_ap (),
m_synthetic_symbol_idx (0)
{
if (header_data_sp)
m_data.SetData (header_data_sp, 0, header_data_sp->GetByteSize());
Expand Down Expand Up @@ -653,3 +654,13 @@ ObjectFile::GetSymbolTypeFromName (llvm::StringRef name,
}
return symbol_type_hint;
}

ConstString
ObjectFile::GetNextSyntheticSymbolName()
{
StreamString ss;
ConstString file_name = GetModule()->GetFileSpec().GetFilename();
ss.Printf("___lldb_unnamed_symbol%u$$%s", ++m_synthetic_symbol_idx, file_name.GetCString());
return ConstString(ss.GetData());
}

0 comments on commit ed844cb

Please sign in to comment.