Skip to content

Commit 1da9e27

Browse files
labathGroverkss
authored andcommitted
[lldb] (Begin to) support discontinuous lldb_private::Functions (llvm#115730)
This is the beginning of a different, more fundamental approach to handling. This PR tries to tries to minimize functional changes. It only makes sure that we store the true set of ranges inside the function object, so that subsequent patches can make use of it.
1 parent b00e4fd commit 1da9e27

File tree

12 files changed

+233
-58
lines changed

12 files changed

+233
-58
lines changed

lldb/include/lldb/Symbol/Function.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ class Function : public UserID, public SymbolContextScope {
428428
/// The section offset based address for this function.
429429
Function(CompileUnit *comp_unit, lldb::user_id_t func_uid,
430430
lldb::user_id_t func_type_uid, const Mangled &mangled,
431-
Type *func_type, const AddressRange &range);
431+
Type *func_type, AddressRanges ranges);
432432

433433
/// Destructor.
434434
~Function() override;
@@ -649,8 +649,12 @@ class Function : public UserID, public SymbolContextScope {
649649
/// All lexical blocks contained in this function.
650650
Block m_block;
651651

652+
/// List of address ranges belonging to the function.
653+
AddressRanges m_ranges;
654+
652655
/// The function address range that covers the widest range needed to contain
653-
/// all blocks
656+
/// all blocks. DEPRECATED: do not use this field in new code as the range may
657+
/// include addresses belonging to other functions.
654658
AddressRange m_range;
655659

656660
/// The frame base expression for variables that are relative to the frame

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ FunctionSP SymbolFileBreakpad::GetOrCreateFunction(CompileUnit &comp_unit) {
255255
section_sp, address - section_sp->GetFileAddress(), record->Size);
256256
// Use the CU's id because every CU has only one function inside.
257257
func_sp = std::make_shared<Function>(&comp_unit, id, 0, func_name,
258-
nullptr, func_range);
258+
nullptr, AddressRanges{func_range});
259259
comp_unit.AddFunction(func_sp);
260260
}
261261
}

lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,7 @@ size_t SymbolFileCTF::ParseFunctions(CompileUnit &cu) {
829829
lldb::user_id_t func_uid = m_functions.size();
830830
FunctionSP function_sp = std::make_shared<Function>(
831831
&cu, func_uid, function_type_uid, symbol->GetMangled(), type_sp.get(),
832-
func_range);
832+
AddressRanges{func_range});
833833
m_functions.emplace_back(function_sp);
834834
cu.AddFunction(function_sp);
835835
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class DWARFASTParser {
4242

4343
virtual Function *ParseFunctionFromDWARF(CompileUnit &comp_unit,
4444
const DWARFDIE &die,
45-
const AddressRange &range) = 0;
45+
AddressRanges ranges) = 0;
4646

4747
virtual bool CompleteTypeFromDWARF(const DWARFDIE &die, Type *type,
4848
const CompilerType &compiler_type) = 0;

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

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2340,12 +2340,9 @@ DWARFASTParserClang::ConstructDemangledNameFromDWARF(const DWARFDIE &die) {
23402340
return ConstString(sstr.GetString());
23412341
}
23422342

2343-
Function *
2344-
DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
2345-
const DWARFDIE &die,
2346-
const AddressRange &func_range) {
2347-
assert(func_range.GetBaseAddress().IsValid());
2348-
DWARFRangeList func_ranges;
2343+
Function *DWARFASTParserClang::ParseFunctionFromDWARF(
2344+
CompileUnit &comp_unit, const DWARFDIE &die, AddressRanges func_ranges) {
2345+
DWARFRangeList unused_func_ranges;
23492346
const char *name = nullptr;
23502347
const char *mangled = nullptr;
23512348
std::optional<int> decl_file;
@@ -2361,9 +2358,9 @@ DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
23612358
if (tag != DW_TAG_subprogram)
23622359
return nullptr;
23632360

2364-
if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
2365-
decl_column, call_file, call_line, call_column,
2366-
&frame_base)) {
2361+
if (die.GetDIENamesAndRanges(name, mangled, unused_func_ranges, decl_file,
2362+
decl_line, decl_column, call_file, call_line,
2363+
call_column, &frame_base)) {
23672364
Mangled func_name;
23682365
if (mangled)
23692366
func_name.SetValue(ConstString(mangled));
@@ -2395,11 +2392,10 @@ DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
23952392
assert(func_type == nullptr || func_type != DIE_IS_BEING_PARSED);
23962393

23972394
const user_id_t func_user_id = die.GetID();
2398-
func_sp =
2399-
std::make_shared<Function>(&comp_unit,
2400-
func_user_id, // UserID is the DIE offset
2401-
func_user_id, func_name, func_type,
2402-
func_range); // first address range
2395+
func_sp = std::make_shared<Function>(
2396+
&comp_unit,
2397+
func_user_id, // UserID is the DIE offset
2398+
func_user_id, func_name, func_type, std::move(func_ranges));
24032399

24042400
if (func_sp.get() != nullptr) {
24052401
if (frame_base.IsValid())

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
5959
lldb_private::Function *
6060
ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit,
6161
const lldb_private::plugin::dwarf::DWARFDIE &die,
62-
const lldb_private::AddressRange &func_range) override;
62+
lldb_private::AddressRanges func_ranges) override;
6363

6464
bool CompleteTypeFromDWARF(
6565
const lldb_private::plugin::dwarf::DWARFDIE &die,

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

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -918,32 +918,20 @@ Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit,
918918
if (!dwarf_ast)
919919
return nullptr;
920920

921-
DWARFRangeList ranges = die.GetDIE()->GetAttributeAddressRanges(
922-
die.GetCU(), /*check_hi_lo_pc=*/true);
923-
if (ranges.IsEmpty())
924-
return nullptr;
925-
926-
// Union of all ranges in the function DIE (if the function is
927-
// discontiguous)
928-
lldb::addr_t lowest_func_addr = ranges.GetMinRangeBase(0);
929-
lldb::addr_t highest_func_addr = ranges.GetMaxRangeEnd(0);
930-
if (lowest_func_addr == LLDB_INVALID_ADDRESS ||
931-
lowest_func_addr >= highest_func_addr ||
932-
lowest_func_addr < m_first_code_address)
933-
return nullptr;
934-
921+
AddressRanges ranges;
935922
ModuleSP module_sp(die.GetModule());
936-
AddressRange func_range;
937-
func_range.GetBaseAddress().ResolveAddressUsingFileSections(
938-
lowest_func_addr, module_sp->GetSectionList());
939-
if (!func_range.GetBaseAddress().IsValid())
940-
return nullptr;
941-
942-
func_range.SetByteSize(highest_func_addr - lowest_func_addr);
943-
if (!FixupAddress(func_range.GetBaseAddress()))
923+
for (const auto &range : die.GetDIE()->GetAttributeAddressRanges(
924+
die.GetCU(), /*check_hi_lo_pc=*/true)) {
925+
if (range.base < m_first_code_address)
926+
continue;
927+
if (Address base_addr(range.base, module_sp->GetSectionList());
928+
base_addr.IsValid() && FixupAddress(base_addr))
929+
ranges.emplace_back(std::move(base_addr), range.size);
930+
}
931+
if (ranges.empty())
944932
return nullptr;
945933

946-
return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die, func_range);
934+
return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die, std::move(ranges));
947935
}
948936

949937
ConstString

lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbCompilandSymId func_id,
504504
Mangled mangled(proc.Name);
505505
FunctionSP func_sp = std::make_shared<Function>(
506506
&comp_unit, toOpaqueUid(func_id), toOpaqueUid(sig_id), mangled,
507-
func_type.get(), func_range);
507+
func_type.get(), AddressRanges{func_range});
508508

509509
comp_unit.AddFunction(func_sp);
510510

lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,9 +310,9 @@ SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func,
310310

311311
Mangled mangled = GetMangledForPDBFunc(pdb_func);
312312

313-
FunctionSP func_sp =
314-
std::make_shared<Function>(&comp_unit, pdb_func.getSymIndexId(),
315-
func_type_uid, mangled, func_type, func_range);
313+
FunctionSP func_sp = std::make_shared<Function>(
314+
&comp_unit, pdb_func.getSymIndexId(), func_type_uid, mangled, func_type,
315+
AddressRanges{func_range});
316316

317317
comp_unit.AddFunction(func_sp);
318318

lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ size_t SymbolFileSymtab::ParseFunctions(CompileUnit &comp_unit) {
186186
// for this function
187187
curr_symbol->GetMangled(), // Linker/mangled name
188188
nullptr, // no return type for a code symbol...
189-
func_range)); // first address range
189+
AddressRanges{func_range}));
190190

191191
if (func_sp.get() != nullptr) {
192192
comp_unit.AddFunction(func_sp);

lldb/source/Symbol/Function.cpp

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -254,12 +254,32 @@ Function *IndirectCallEdge::GetCallee(ModuleList &images,
254254

255255
/// @}
256256

257+
AddressRange CollapseRanges(llvm::ArrayRef<AddressRange> ranges) {
258+
if (ranges.empty())
259+
return AddressRange();
260+
if (ranges.size() == 1)
261+
return ranges[0];
262+
263+
Address lowest_addr = ranges[0].GetBaseAddress();
264+
addr_t highest_addr = lowest_addr.GetFileAddress() + ranges[0].GetByteSize();
265+
for (const AddressRange &range : ranges.drop_front()) {
266+
Address range_begin = range.GetBaseAddress();
267+
addr_t range_end = range_begin.GetFileAddress() + range.GetByteSize();
268+
if (range_begin.GetFileAddress() < lowest_addr.GetFileAddress())
269+
lowest_addr = range_begin;
270+
if (range_end > highest_addr)
271+
highest_addr = range_end;
272+
}
273+
return AddressRange(lowest_addr, highest_addr - lowest_addr.GetFileAddress());
274+
}
275+
257276
//
258277
Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid,
259278
lldb::user_id_t type_uid, const Mangled &mangled, Type *type,
260-
const AddressRange &range)
279+
AddressRanges ranges)
261280
: UserID(func_uid), m_comp_unit(comp_unit), m_type_uid(type_uid),
262-
m_type(type), m_mangled(mangled), m_block(func_uid), m_range(range),
281+
m_type(type), m_mangled(mangled), m_block(func_uid),
282+
m_ranges(std::move(ranges)), m_range(CollapseRanges(m_ranges)),
263283
m_frame_base(), m_flags(), m_prologue_byte_size(0) {
264284
m_block.SetParentScope(this);
265285
assert(comp_unit != nullptr);
@@ -406,14 +426,13 @@ void Function::GetDescription(Stream *s, lldb::DescriptionLevel level,
406426
llvm::interleaveComma(decl_context, *s, [&](auto &ctx) { ctx.Dump(*s); });
407427
*s << "}";
408428
}
409-
*s << ", range = ";
410-
Address::DumpStyle fallback_style;
411-
if (level == eDescriptionLevelVerbose)
412-
fallback_style = Address::DumpStyleModuleWithFileAddress;
413-
else
414-
fallback_style = Address::DumpStyleFileAddress;
415-
GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress,
416-
fallback_style);
429+
*s << ", range" << (m_ranges.size() > 1 ? "s" : "") << " = ";
430+
Address::DumpStyle fallback_style =
431+
level == eDescriptionLevelVerbose
432+
? Address::DumpStyleModuleWithFileAddress
433+
: Address::DumpStyleFileAddress;
434+
for (const AddressRange &range : m_ranges)
435+
range.Dump(s, target, Address::DumpStyleLoadAddress, fallback_style);
417436
}
418437

419438
void Function::Dump(Stream *s, bool show_context) const {

0 commit comments

Comments
 (0)