diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h --- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h +++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h @@ -63,6 +63,8 @@ return lldb::eLanguageTypeUnknown; } + lldb::FunctionSP GetOrCreateFunction(CompileUnit &comp_unit); + size_t ParseFunctions(CompileUnit &comp_unit) override; bool ParseLineTable(CompileUnit &comp_unit) override; diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp --- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp +++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp @@ -219,9 +219,40 @@ return cu_sp; } +FunctionSP SymbolFileBreakpad::GetOrCreateFunction(CompileUnit &comp_unit) { + user_id_t id = comp_unit.GetID(); + if (FunctionSP func_sp = comp_unit.FindFunctionByUID(id)) + return func_sp; + + Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); + FunctionSP func_sp; + addr_t base = GetBaseFileAddress(); + if (base == LLDB_INVALID_ADDRESS) { + LLDB_LOG(log, "Unable to fetch the base address of object file. Skipping " + "symtab population."); + return func_sp; + } + + const SectionList *list = comp_unit.GetModule()->GetSectionList(); + CompUnitData &data = m_cu_data->GetEntryRef(id).data; + LineIterator It(*m_objfile_sp, Record::Func, data.bookmark); + assert(Record::classify(*It) == Record::Func); + + if (auto record = FuncRecord::parse(*It)) { + addr_t address = record->Address + base; + SectionSP section_sp = list->FindSectionContainingFileAddress(address); + AddressRange func_range(section_sp, address - section_sp->GetFileAddress(), + record->Size); + func_sp = std::make_shared( + &comp_unit, id, 0, Mangled(record->Name), nullptr, func_range); + comp_unit.AddFunction(func_sp); + } + return func_sp; +} + size_t SymbolFileBreakpad::ParseFunctions(CompileUnit &comp_unit) { - // TODO - return 0; + std::lock_guard guard(GetModuleMutex()); + return GetOrCreateFunction(comp_unit) ? 1 : 0; } bool SymbolFileBreakpad::ParseLineTable(CompileUnit &comp_unit) { @@ -251,7 +282,8 @@ SymbolContextItem resolve_scope, SymbolContext &sc) { std::lock_guard guard(GetModuleMutex()); - if (!(resolve_scope & (eSymbolContextCompUnit | eSymbolContextLineEntry))) + if (!(resolve_scope & (eSymbolContextCompUnit | eSymbolContextLineEntry | + eSymbolContextFunction))) return 0; ParseCUData(); @@ -268,6 +300,13 @@ result |= eSymbolContextLineEntry; } } + if (resolve_scope & eSymbolContextFunction) { + FunctionSP func_sp = GetOrCreateFunction(*sc.comp_unit); + if (func_sp) { + sc.function = func_sp.get(); + result |= eSymbolContextFunction; + } + } return result; } diff --git a/lldb/test/Shell/SymbolFile/Breakpad/line-table.test b/lldb/test/Shell/SymbolFile/Breakpad/line-table.test --- a/lldb/test/Shell/SymbolFile/Breakpad/line-table.test +++ b/lldb/test/Shell/SymbolFile/Breakpad/line-table.test @@ -39,7 +39,16 @@ image lookup -a 0x4000b2 -v # CHECK-LABEL: image lookup -a 0x4000b2 -v # CHECK: Summary: line-table.out`func + 2 +# CHECK: Function: id = {0x00000000}, name = "func", range = [0x00000000004000b0-0x00000000004000c0) + +image dump symfile +# CHECK-LABEL: Compile units: +# CHECK-NEXT: CompileUnit{0x00000000}, language = "", file = '/tmp/a.c' +# CHECK-NEXT: Function{0x00000000}, demangled = func, type_uid = 0x00000000 +# CHECK: CompileUnit{0x00000001}, language = "", file = '/tmp/c.c' +# CHECK-NEXT: CompileUnit{0x00000002}, language = "", file = '/tmp/d.c' +# CHECK-NEXT: CompileUnit{0x00000003}, language = "", file = '/tmp/d.c' breakpoint set -f c.c -l 2 # CHECK-LABEL: breakpoint set -f c.c -l 2 -# CHECK: Breakpoint 1: where = line-table.out`func + 2, address = 0x00000000004000b2 +# CHECK: Breakpoint 1: where = line-table.out`func + 2 at c.c:2, address = 0x00000000004000b2 diff --git a/lldb/test/Shell/SymbolFile/Breakpad/symtab.test b/lldb/test/Shell/SymbolFile/Breakpad/symtab.test --- a/lldb/test/Shell/SymbolFile/Breakpad/symtab.test +++ b/lldb/test/Shell/SymbolFile/Breakpad/symtab.test @@ -13,6 +13,7 @@ # CHECK-LABEL: (lldb) image lookup -a 0x4000b0 -v # CHECK: Address: symtab.out[0x00000000004000b0] (symtab.out.PT_LOAD[0]..text2 + 0) +# CHECK: Function: id = {0x00000001}, name = "f1_func", range = [0x00000000004000b0-0x00000000004000bc) # CHECK: Symbol: id = {0x00000000}, range = [0x00000000004000b0-0x00000000004000bc), name="f1_func" # CHECK-LABEL: (lldb) image lookup -n f2 -v