Skip to content

Commit fbf665a

Browse files
committed
[LLDB][Breakpad] Create a function for each compilation unit.
Since every FUNC record (in breakpad) is a compilation unit, creating the function for the CU allows `ResolveSymbolContext` to resolve `eSymbolContextFunction`. Differential Revision: https://reviews.llvm.org/D113163
1 parent 360d901 commit fbf665a

File tree

6 files changed

+83
-20
lines changed

6 files changed

+83
-20
lines changed

lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp

Lines changed: 61 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -219,9 +219,45 @@ CompUnitSP SymbolFileBreakpad::ParseCompileUnitAtIndex(uint32_t index) {
219219
return cu_sp;
220220
}
221221

222+
FunctionSP SymbolFileBreakpad::GetOrCreateFunction(CompileUnit &comp_unit) {
223+
user_id_t id = comp_unit.GetID();
224+
if (FunctionSP func_sp = comp_unit.FindFunctionByUID(id))
225+
return func_sp;
226+
227+
Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS);
228+
FunctionSP func_sp;
229+
addr_t base = GetBaseFileAddress();
230+
if (base == LLDB_INVALID_ADDRESS) {
231+
LLDB_LOG(log, "Unable to fetch the base address of object file. Skipping "
232+
"symtab population.");
233+
return func_sp;
234+
}
235+
236+
const SectionList *list = comp_unit.GetModule()->GetSectionList();
237+
CompUnitData &data = m_cu_data->GetEntryRef(id).data;
238+
LineIterator It(*m_objfile_sp, Record::Func, data.bookmark);
239+
assert(Record::classify(*It) == Record::Func);
240+
241+
if (auto record = FuncRecord::parse(*It)) {
242+
Mangled func_name;
243+
func_name.SetValue(ConstString(record->Name), false);
244+
addr_t address = record->Address + base;
245+
SectionSP section_sp = list->FindSectionContainingFileAddress(address);
246+
if (section_sp) {
247+
AddressRange func_range(
248+
section_sp, address - section_sp->GetFileAddress(), record->Size);
249+
// Use the CU's id because every CU has only one function inside.
250+
func_sp = std::make_shared<Function>(&comp_unit, id, 0, func_name,
251+
nullptr, func_range);
252+
comp_unit.AddFunction(func_sp);
253+
}
254+
}
255+
return func_sp;
256+
}
257+
222258
size_t SymbolFileBreakpad::ParseFunctions(CompileUnit &comp_unit) {
223-
// TODO
224-
return 0;
259+
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
260+
return GetOrCreateFunction(comp_unit) ? 1 : 0;
225261
}
226262

227263
bool SymbolFileBreakpad::ParseLineTable(CompileUnit &comp_unit) {
@@ -251,7 +287,8 @@ SymbolFileBreakpad::ResolveSymbolContext(const Address &so_addr,
251287
SymbolContextItem resolve_scope,
252288
SymbolContext &sc) {
253289
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
254-
if (!(resolve_scope & (eSymbolContextCompUnit | eSymbolContextLineEntry)))
290+
if (!(resolve_scope & (eSymbolContextCompUnit | eSymbolContextLineEntry |
291+
eSymbolContextFunction)))
255292
return 0;
256293

257294
ParseCUData();
@@ -268,6 +305,13 @@ SymbolFileBreakpad::ResolveSymbolContext(const Address &so_addr,
268305
result |= eSymbolContextLineEntry;
269306
}
270307
}
308+
if (resolve_scope & eSymbolContextFunction) {
309+
FunctionSP func_sp = GetOrCreateFunction(*sc.comp_unit);
310+
if (func_sp) {
311+
sc.function = func_sp.get();
312+
result |= eSymbolContextFunction;
313+
}
314+
}
271315

272316
return result;
273317
}
@@ -291,7 +335,20 @@ void SymbolFileBreakpad::FindFunctions(
291335
ConstString name, const CompilerDeclContext &parent_decl_ctx,
292336
FunctionNameType name_type_mask, bool include_inlines,
293337
SymbolContextList &sc_list) {
294-
// TODO
338+
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
339+
// TODO: Implement this with supported FunctionNameType.
340+
341+
for (uint32_t i = 0; i < GetNumCompileUnits(); ++i) {
342+
CompUnitSP cu_sp = GetCompileUnitAtIndex(i);
343+
FunctionSP func_sp = GetOrCreateFunction(*cu_sp);
344+
if (func_sp && name == func_sp->GetNameNoArguments()) {
345+
SymbolContext sc;
346+
sc.comp_unit = cu_sp.get();
347+
sc.function = func_sp.get();
348+
sc.module_sp = func_sp->CalculateSymbolContextModule();
349+
sc_list.Append(sc);
350+
}
351+
}
295352
}
296353

297354
void SymbolFileBreakpad::FindFunctions(const RegularExpression &regex,
@@ -346,11 +403,6 @@ void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
346403
size.hasValue(), /*contains_linker_annotations*/ false, /*flags*/ 0);
347404
};
348405

349-
for (llvm::StringRef line : lines(Record::Func)) {
350-
if (auto record = FuncRecord::parse(line))
351-
add_symbol(record->Address, record->Size, record->Name);
352-
}
353-
354406
for (llvm::StringRef line : lines(Record::Public)) {
355407
if (auto record = PublicRecord::parse(line))
356408
add_symbol(record->Address, llvm::None, record->Name);

lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ class SymbolFileBreakpad : public SymbolFile {
6363
return lldb::eLanguageTypeUnknown;
6464
}
6565

66+
lldb::FunctionSP GetOrCreateFunction(CompileUnit &comp_unit);
67+
6668
size_t ParseFunctions(CompileUnit &comp_unit) override;
6769

6870
bool ParseLineTable(CompileUnit &comp_unit) override;
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
MODULE Linux x86_64 3B285CE327C387C262DB788BF5A4078B0 linux-x86_64
22
INFO CODE_ID E35C283BC327C28762DB788BF5A4078BE2351448
3-
FUNC 3d0 18 0 crash()
4-
FUNC 3f0 10 0 _start
3+
PUBLIC 3d0 0 crash()
4+
PUBLIC 3f0 0 _start

lldb/test/Shell/Minidump/breakpad-symbols.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ image list
1515
image dump symtab /tmp/test/linux-x86_64
1616
# CHECK-LABEL: image dump symtab /tmp/test/linux-x86_64
1717
# CHECK: Symtab, file = /tmp/test/linux-x86_64, num_symbols = 2:
18-
# CHECK: [ 0] 0 X Code 0x00000000004003d0 0x00000000004003d0 0x0000000000000018 0x00000000 crash()
19-
# CHECK: [ 1] 0 X Code 0x00000000004003f0 0x00000000004003f0 0x0000000000000010 0x00000000 _start
18+
# CHECK: [ 0] 0 X Code 0x00000000004003d0 0x00000000004003d0 0x0000000000000020 0x00000000 crash()
19+
# CHECK: [ 1] 0 X Code 0x00000000004003f0 0x00000000004003f0 0x0000000000000c10 0x00000000 _start
2020

2121
image lookup -a 0x4003f3
2222
# CHECK-LABEL: image lookup -a 0x4003f3

lldb/test/Shell/SymbolFile/Breakpad/line-table.test

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,16 @@ image dump line-table d.c
3939
image lookup -a 0x4000b2 -v
4040
# CHECK-LABEL: image lookup -a 0x4000b2 -v
4141
# CHECK: Summary: line-table.out`func + 2
42+
# CHECK: Function: id = {0x00000000}, name = "func", range = [0x00000000004000b0-0x00000000004000c0)
43+
44+
image dump symfile
45+
# CHECK-LABEL: Compile units:
46+
# CHECK-NEXT: CompileUnit{0x00000000}, language = "<not loaded>", file = '/tmp/a.c'
47+
# CHECK-NEXT: Function{0x00000000}, demangled = func, type_uid = 0x00000000
48+
# CHECK: CompileUnit{0x00000001}, language = "<not loaded>", file = '/tmp/c.c'
49+
# CHECK-NEXT: CompileUnit{0x00000002}, language = "<not loaded>", file = '/tmp/d.c'
50+
# CHECK-NEXT: CompileUnit{0x00000003}, language = "<not loaded>", file = '/tmp/d.c'
4251

4352
breakpoint set -f c.c -l 2
4453
# CHECK-LABEL: breakpoint set -f c.c -l 2
45-
# CHECK: Breakpoint 1: where = line-table.out`func + 2, address = 0x00000000004000b2
54+
# CHECK: Breakpoint 1: where = line-table.out`func + 2 at c.c:2, address = 0x00000000004000b2

lldb/test/Shell/SymbolFile/Breakpad/symtab.test

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33
# RUN: -s %s | FileCheck %s
44

55
# CHECK-LABEL: (lldb) image dump symtab symtab.out
6-
# CHECK: Symtab, file = {{.*}}symtab.out, num_symbols = 5:
6+
# CHECK: Symtab, file = {{.*}}symtab.out, num_symbols = 4:
77
# CHECK: Index UserID DSX Type File Address/Value Load Address Size Flags Name
88
# CHECK: [ 0] 0 SX Code 0x0000000000400000 0x00000000000000b0 0x00000000 ___lldb_unnamed_symbol{{[0-9]*}}
9-
# CHECK: [ 1] 0 X Code 0x00000000004000b0 0x000000000000000c 0x00000000 f1_func
10-
# CHECK: [ 2] 0 X Code 0x00000000004000a0 0x000000000000000d 0x00000000 func_only
11-
# CHECK: [ 3] 0 X Code 0x00000000004000c0 0x0000000000000010 0x00000000 f2
12-
# CHECK: [ 4] 0 X Code 0x00000000004000d0 0x0000000000000022 0x00000000 _start
9+
# CHECK: [ 1] 0 X Code 0x00000000004000b0 0x0000000000000010 0x00000000 f1
10+
# CHECK: [ 2] 0 X Code 0x00000000004000c0 0x0000000000000010 0x00000000 f2
11+
# CHECK: [ 3] 0 X Code 0x00000000004000d0 0x0000000000000022 0x00000000 _start
1312

1413
# CHECK-LABEL: (lldb) image lookup -a 0x4000b0 -v
1514
# CHECK: Address: symtab.out[0x00000000004000b0] (symtab.out.PT_LOAD[0]..text2 + 0)
16-
# CHECK: Symbol: id = {0x00000000}, range = [0x00000000004000b0-0x00000000004000bc), name="f1_func"
15+
# CHECK: Function: id = {0x00000001}, name = "f1_func", range = [0x00000000004000b0-0x00000000004000bc)
16+
# CHECK: Symbol: id = {0x00000000}, range = [0x00000000004000b0-0x00000000004000c0), name="f1"
1717

1818
# CHECK-LABEL: (lldb) image lookup -n f2 -v
1919
# CHECK: Address: symtab.out[0x00000000004000c0] (symtab.out.PT_LOAD[0]..text2 + 16)

0 commit comments

Comments
 (0)