Skip to content

Commit c1055f0

Browse files
committed
[lldb/DWARF] Don't create lldb_private::Functions for gc'ed DW_TAG_subprograms
Front-load the first_valid_code_address check, so that we avoid creating the function object (instead of simply refusing to use it in queries). Differential Revision: https://reviews.llvm.org/D112310
1 parent 477551f commit c1055f0

File tree

5 files changed

+115
-93
lines changed

5 files changed

+115
-93
lines changed

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ class DWARFASTParser {
3232

3333
virtual lldb_private::Function *
3434
ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit,
35-
const DWARFDIE &die) = 0;
35+
const DWARFDIE &die,
36+
const lldb_private::AddressRange &range) = 0;
3637

3738
virtual bool
3839
CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type,

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

Lines changed: 70 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -2342,8 +2342,11 @@ size_t DWARFASTParserClang::ParseChildEnumerators(
23422342
return enumerators_added;
23432343
}
23442344

2345-
Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
2346-
const DWARFDIE &die) {
2345+
Function *
2346+
DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
2347+
const DWARFDIE &die,
2348+
const AddressRange &func_range) {
2349+
assert(func_range.GetBaseAddress().IsValid());
23472350
DWARFRangeList func_ranges;
23482351
const char *name = nullptr;
23492352
const char *mangled = nullptr;
@@ -2363,94 +2366,75 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
23632366
if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
23642367
decl_column, call_file, call_line, call_column,
23652368
&frame_base)) {
2369+
Mangled func_name;
2370+
if (mangled)
2371+
func_name.SetValue(ConstString(mangled), true);
2372+
else if ((die.GetParent().Tag() == DW_TAG_compile_unit ||
2373+
die.GetParent().Tag() == DW_TAG_partial_unit) &&
2374+
Language::LanguageIsCPlusPlus(
2375+
SymbolFileDWARF::GetLanguage(*die.GetCU())) &&
2376+
!Language::LanguageIsObjC(
2377+
SymbolFileDWARF::GetLanguage(*die.GetCU())) &&
2378+
name && strcmp(name, "main") != 0) {
2379+
// If the mangled name is not present in the DWARF, generate the
2380+
// demangled name using the decl context. We skip if the function is
2381+
// "main" as its name is never mangled.
2382+
bool is_static = false;
2383+
bool is_variadic = false;
2384+
bool has_template_params = false;
2385+
unsigned type_quals = 0;
2386+
std::vector<CompilerType> param_types;
2387+
std::vector<clang::ParmVarDecl *> param_decls;
2388+
StreamString sstr;
2389+
2390+
DWARFDeclContext decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die);
2391+
sstr << decl_ctx.GetQualifiedName();
23662392

2367-
// Union of all ranges in the function DIE (if the function is
2368-
// discontiguous)
2369-
AddressRange func_range;
2370-
lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
2371-
lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
2372-
if (lowest_func_addr != LLDB_INVALID_ADDRESS &&
2373-
lowest_func_addr <= highest_func_addr) {
2374-
ModuleSP module_sp(die.GetModule());
2375-
func_range.GetBaseAddress().ResolveAddressUsingFileSections(
2376-
lowest_func_addr, module_sp->GetSectionList());
2377-
if (func_range.GetBaseAddress().IsValid())
2378-
func_range.SetByteSize(highest_func_addr - lowest_func_addr);
2379-
}
2380-
2381-
if (func_range.GetBaseAddress().IsValid()) {
2382-
Mangled func_name;
2383-
if (mangled)
2384-
func_name.SetValue(ConstString(mangled), true);
2385-
else if ((die.GetParent().Tag() == DW_TAG_compile_unit ||
2386-
die.GetParent().Tag() == DW_TAG_partial_unit) &&
2387-
Language::LanguageIsCPlusPlus(
2388-
SymbolFileDWARF::GetLanguage(*die.GetCU())) &&
2389-
!Language::LanguageIsObjC(
2390-
SymbolFileDWARF::GetLanguage(*die.GetCU())) &&
2391-
name && strcmp(name, "main") != 0) {
2392-
// If the mangled name is not present in the DWARF, generate the
2393-
// demangled name using the decl context. We skip if the function is
2394-
// "main" as its name is never mangled.
2395-
bool is_static = false;
2396-
bool is_variadic = false;
2397-
bool has_template_params = false;
2398-
unsigned type_quals = 0;
2399-
std::vector<CompilerType> param_types;
2400-
std::vector<clang::ParmVarDecl *> param_decls;
2401-
StreamString sstr;
2402-
2403-
DWARFDeclContext decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die);
2404-
sstr << decl_ctx.GetQualifiedName();
2405-
2406-
clang::DeclContext *containing_decl_ctx =
2407-
GetClangDeclContextContainingDIE(die, nullptr);
2408-
ParseChildParameters(containing_decl_ctx, die, true, is_static,
2409-
is_variadic, has_template_params, param_types,
2410-
param_decls, type_quals);
2411-
sstr << "(";
2412-
for (size_t i = 0; i < param_types.size(); i++) {
2413-
if (i > 0)
2414-
sstr << ", ";
2415-
sstr << param_types[i].GetTypeName();
2416-
}
2417-
if (is_variadic)
2418-
sstr << ", ...";
2419-
sstr << ")";
2420-
if (type_quals & clang::Qualifiers::Const)
2421-
sstr << " const";
2422-
2423-
func_name.SetValue(ConstString(sstr.GetString()), false);
2424-
} else
2425-
func_name.SetValue(ConstString(name), false);
2426-
2427-
FunctionSP func_sp;
2428-
std::unique_ptr<Declaration> decl_up;
2429-
if (decl_file != 0 || decl_line != 0 || decl_column != 0)
2430-
decl_up = std::make_unique<Declaration>(die.GetCU()->GetFile(decl_file),
2431-
decl_line, decl_column);
2432-
2433-
SymbolFileDWARF *dwarf = die.GetDWARF();
2434-
// Supply the type _only_ if it has already been parsed
2435-
Type *func_type = dwarf->GetDIEToType().lookup(die.GetDIE());
2436-
2437-
assert(func_type == nullptr || func_type != DIE_IS_BEING_PARSED);
2438-
2439-
if (dwarf->FixupAddress(func_range.GetBaseAddress())) {
2440-
const user_id_t func_user_id = die.GetID();
2441-
func_sp =
2442-
std::make_shared<Function>(&comp_unit,
2393+
clang::DeclContext *containing_decl_ctx =
2394+
GetClangDeclContextContainingDIE(die, nullptr);
2395+
ParseChildParameters(containing_decl_ctx, die, true, is_static,
2396+
is_variadic, has_template_params, param_types,
2397+
param_decls, type_quals);
2398+
sstr << "(";
2399+
for (size_t i = 0; i < param_types.size(); i++) {
2400+
if (i > 0)
2401+
sstr << ", ";
2402+
sstr << param_types[i].GetTypeName();
2403+
}
2404+
if (is_variadic)
2405+
sstr << ", ...";
2406+
sstr << ")";
2407+
if (type_quals & clang::Qualifiers::Const)
2408+
sstr << " const";
2409+
2410+
func_name.SetValue(ConstString(sstr.GetString()), false);
2411+
} else
2412+
func_name.SetValue(ConstString(name), false);
2413+
2414+
FunctionSP func_sp;
2415+
std::unique_ptr<Declaration> decl_up;
2416+
if (decl_file != 0 || decl_line != 0 || decl_column != 0)
2417+
decl_up = std::make_unique<Declaration>(die.GetCU()->GetFile(decl_file),
2418+
decl_line, decl_column);
2419+
2420+
SymbolFileDWARF *dwarf = die.GetDWARF();
2421+
// Supply the type _only_ if it has already been parsed
2422+
Type *func_type = dwarf->GetDIEToType().lookup(die.GetDIE());
2423+
2424+
assert(func_type == nullptr || func_type != DIE_IS_BEING_PARSED);
2425+
2426+
const user_id_t func_user_id = die.GetID();
2427+
func_sp =
2428+
std::make_shared<Function>(&comp_unit,
24432429
func_user_id, // UserID is the DIE offset
24442430
func_user_id, func_name, func_type,
2445-
func_range); // first address range
2431+
func_range); // first address range
24462432

2447-
if (func_sp.get() != nullptr) {
2448-
if (frame_base.IsValid())
2449-
func_sp->GetFrameBaseExpression() = frame_base;
2450-
comp_unit.AddFunction(func_sp);
2451-
return func_sp.get();
2452-
}
2453-
}
2433+
if (func_sp.get() != nullptr) {
2434+
if (frame_base.IsValid())
2435+
func_sp->GetFrameBaseExpression() = frame_base;
2436+
comp_unit.AddFunction(func_sp);
2437+
return func_sp.get();
24542438
}
24552439
}
24562440
return nullptr;

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ class DWARFASTParserClang : public DWARFASTParser {
4747

4848
lldb_private::Function *
4949
ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit,
50-
const DWARFDIE &die) override;
50+
const DWARFDIE &die,
51+
const lldb_private::AddressRange &func_range) override;
5152

5253
bool
5354
CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type,

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,32 @@ Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit,
856856
if (!dwarf_ast)
857857
return nullptr;
858858

859-
return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die);
859+
DWARFRangeList ranges;
860+
if (die.GetDIE()->GetAttributeAddressRanges(die.GetCU(), ranges,
861+
/*check_hi_lo_pc=*/true) == 0)
862+
return nullptr;
863+
864+
// Union of all ranges in the function DIE (if the function is
865+
// discontiguous)
866+
AddressRange func_range;
867+
lldb::addr_t lowest_func_addr = ranges.GetMinRangeBase(0);
868+
lldb::addr_t highest_func_addr = ranges.GetMaxRangeEnd(0);
869+
if (lowest_func_addr == LLDB_INVALID_ADDRESS ||
870+
lowest_func_addr >= highest_func_addr ||
871+
lowest_func_addr < m_first_code_address)
872+
return nullptr;
873+
874+
ModuleSP module_sp(die.GetModule());
875+
func_range.GetBaseAddress().ResolveAddressUsingFileSections(
876+
lowest_func_addr, module_sp->GetSectionList());
877+
if (!func_range.GetBaseAddress().IsValid())
878+
return nullptr;
879+
880+
func_range.SetByteSize(highest_func_addr - lowest_func_addr);
881+
if (!FixupAddress(func_range.GetBaseAddress()))
882+
return nullptr;
883+
884+
return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die, func_range);
860885
}
861886

862887
lldb::addr_t SymbolFileDWARF::FixupAddress(lldb::addr_t file_addr) {
@@ -2263,10 +2288,8 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die,
22632288
addr = sc.function->GetAddressRange().GetBaseAddress();
22642289
}
22652290

2266-
if (addr.IsValid() && addr.GetFileAddress() >= m_first_code_address) {
2267-
sc_list.Append(sc);
2268-
return true;
2269-
}
2291+
sc_list.Append(sc);
2292+
return true;
22702293
}
22712294

22722295
return false;

lldb/test/Shell/SymbolFile/DWARF/x86/dead-code-filtering.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
# RUN: yaml2obj %s > %t
2+
# RUN: lldb-test symbols %t | FileCheck %s --check-prefix=TEST
23
# RUN: %lldb %t -o "image dump line-table a.c" -o "image lookup -n _start" -o "image lookup -n f" -o exit | FileCheck %s
34

5+
# TEST: Compile units:
6+
# TEST-NEXT: CompileUnit{0x00000000}, language = "c", file = 'a.c'
7+
# TEST-NEXT: Function{0x00000043}, demangled = _start, type_uid = 0x00000043
8+
# TEST-NEXT: Block{0x00000043}, ranges = [0x00000080-0x00000086)
9+
# TEST-EMPTY:
10+
# TEST-EMPTY:
11+
# TEST-NEXT: Symtab
12+
13+
414
# CHECK-LABEL: image dump line-table a.c
515
# CHECK-NEXT: Line table for a.c
616
# CHECK-NEXT: 0x0000000000000080: a.c:1
@@ -59,6 +69,8 @@ DWARF:
5969
Attributes:
6070
- Attribute: DW_AT_producer
6171
Form: DW_FORM_string
72+
- Attribute: DW_AT_language
73+
Form: DW_FORM_data1
6274
- Attribute: DW_AT_name
6375
Form: DW_FORM_string
6476
- Attribute: DW_AT_stmt_list
@@ -86,6 +98,7 @@ DWARF:
8698
- AbbrCode: 0x00000001
8799
Values:
88100
- CStr: Hand-written DWARF
101+
- Value: 2
89102
- CStr: a.c
90103
- Value: 0x0000000000000000
91104
- Value: 0x0000000000000000

0 commit comments

Comments
 (0)