Skip to content

Commit 51b74bb

Browse files
committed
Reapply "[lldb] Use the function block as a source for function ranges (llvm#117996)"
This reverts commit 2526d5b, reapplying ba14dac after fixing the conflict with llvm#117532. The change is that Function::GetAddressRanges now recomputes the returned value instead of returning the member. This means it now returns a value instead of a reference type.
1 parent 3f39c5d commit 51b74bb

File tree

11 files changed

+112
-166
lines changed

11 files changed

+112
-166
lines changed

lldb/include/lldb/Symbol/Function.h

+1-4
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ class Function : public UserID, public SymbolContextScope {
447447
/// DEPRECATED: Use GetAddressRanges instead.
448448
const AddressRange &GetAddressRange() { return m_range; }
449449

450-
const AddressRanges &GetAddressRanges() const { return m_ranges; }
450+
AddressRanges GetAddressRanges() { return m_block.GetRanges(); }
451451

452452
lldb::LanguageType GetLanguage() const;
453453
/// Find the file and line number of the source location of the start of the
@@ -653,9 +653,6 @@ class Function : public UserID, public SymbolContextScope {
653653
/// All lexical blocks contained in this function.
654654
Block m_block;
655655

656-
/// List of address ranges belonging to the function.
657-
AddressRanges m_ranges;
658-
659656
/// The function address range that covers the widest range needed to contain
660657
/// all blocks. DEPRECATED: do not use this field in new code as the range may
661658
/// include addresses belonging to other functions.

lldb/source/API/SBFunction.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ SBAddress SBFunction::GetEndAddress() {
154154

155155
SBAddress addr;
156156
if (m_opaque_ptr) {
157-
llvm::ArrayRef<AddressRange> ranges = m_opaque_ptr->GetAddressRanges();
157+
AddressRanges ranges = m_opaque_ptr->GetAddressRanges();
158158
if (!ranges.empty()) {
159159
// Return the end of the first range, use GetRanges to get all ranges.
160160
addr.SetAddress(ranges.front().GetBaseAddress());

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

+1-3
Original file line numberDiff line numberDiff line change
@@ -299,9 +299,7 @@ size_t SymbolFileBreakpad::ParseBlocksRecursive(Function &func) {
299299
// "INLINE 0 ...", the current level is 0 and its parent block is the
300300
// function block at index 0.
301301
std::vector<Block *> blocks;
302-
Block &block = func.GetBlock(false);
303-
block.AddRange(Block::Range(0, func.GetAddressRange().GetByteSize()));
304-
blocks.push_back(&block);
302+
blocks.push_back(&func.GetBlock(false));
305303

306304
size_t blocks_added = 0;
307305
addr_t func_base = func.GetAddressRange().GetBaseAddress().GetOffset();

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

+71-108
Original file line numberDiff line numberDiff line change
@@ -1305,121 +1305,76 @@ bool SymbolFileDWARF::ParseDebugMacros(CompileUnit &comp_unit) {
13051305
return true;
13061306
}
13071307

1308-
size_t SymbolFileDWARF::ParseBlocksRecursive(
1309-
lldb_private::CompileUnit &comp_unit, Block *parent_block,
1310-
const DWARFDIE &orig_die, addr_t subprogram_low_pc, uint32_t depth) {
1308+
size_t SymbolFileDWARF::ParseBlocksRecursive(CompileUnit &comp_unit,
1309+
Block *parent_block, DWARFDIE die,
1310+
addr_t subprogram_low_pc) {
13111311
size_t blocks_added = 0;
1312-
DWARFDIE die = orig_die;
1313-
while (die) {
1312+
for (; die; die = die.GetSibling()) {
13141313
dw_tag_t tag = die.Tag();
13151314

1316-
switch (tag) {
1317-
case DW_TAG_inlined_subroutine:
1318-
case DW_TAG_subprogram:
1319-
case DW_TAG_lexical_block: {
1320-
Block *block = nullptr;
1321-
if (tag == DW_TAG_subprogram) {
1322-
// Skip any DW_TAG_subprogram DIEs that are inside of a normal or
1323-
// inlined functions. These will be parsed on their own as separate
1324-
// entities.
1325-
1326-
if (depth > 0)
1327-
break;
1315+
if (tag != DW_TAG_inlined_subroutine && tag != DW_TAG_lexical_block)
1316+
continue;
13281317

1329-
block = parent_block;
1330-
} else {
1331-
block = parent_block->CreateChild(die.GetID()).get();
1332-
}
1333-
DWARFRangeList ranges;
1334-
const char *name = nullptr;
1335-
const char *mangled_name = nullptr;
1336-
1337-
std::optional<int> decl_file;
1338-
std::optional<int> decl_line;
1339-
std::optional<int> decl_column;
1340-
std::optional<int> call_file;
1341-
std::optional<int> call_line;
1342-
std::optional<int> call_column;
1343-
if (die.GetDIENamesAndRanges(name, mangled_name, ranges, decl_file,
1344-
decl_line, decl_column, call_file, call_line,
1345-
call_column, nullptr)) {
1346-
if (tag == DW_TAG_subprogram) {
1347-
assert(subprogram_low_pc == LLDB_INVALID_ADDRESS);
1348-
subprogram_low_pc = ranges.GetMinRangeBase(0);
1349-
} else if (tag == DW_TAG_inlined_subroutine) {
1350-
// We get called here for inlined subroutines in two ways. The first
1351-
// time is when we are making the Function object for this inlined
1352-
// concrete instance. Since we're creating a top level block at
1353-
// here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we
1354-
// need to adjust the containing address. The second time is when we
1355-
// are parsing the blocks inside the function that contains the
1356-
// inlined concrete instance. Since these will be blocks inside the
1357-
// containing "real" function the offset will be for that function.
1358-
if (subprogram_low_pc == LLDB_INVALID_ADDRESS) {
1359-
subprogram_low_pc = ranges.GetMinRangeBase(0);
1360-
}
1361-
}
1362-
1363-
const size_t num_ranges = ranges.GetSize();
1364-
for (size_t i = 0; i < num_ranges; ++i) {
1365-
const DWARFRangeList::Entry &range = ranges.GetEntryRef(i);
1366-
const addr_t range_base = range.GetRangeBase();
1367-
if (range_base >= subprogram_low_pc)
1368-
block->AddRange(Block::Range(range_base - subprogram_low_pc,
1369-
range.GetByteSize()));
1370-
else {
1371-
GetObjectFile()->GetModule()->ReportError(
1372-
"{0:x8}: adding range [{1:x16}-{2:x16}) which has a base "
1373-
"that is less than the function's low PC {3:x16}. Please file "
1374-
"a bug and attach the file at the "
1375-
"start of this error message",
1376-
block->GetID(), range_base, range.GetRangeEnd(),
1377-
subprogram_low_pc);
1378-
}
1379-
}
1380-
block->FinalizeRanges();
1381-
1382-
if (tag != DW_TAG_subprogram &&
1383-
(name != nullptr || mangled_name != nullptr)) {
1384-
std::unique_ptr<Declaration> decl_up;
1385-
if (decl_file || decl_line || decl_column)
1386-
decl_up = std::make_unique<Declaration>(
1387-
comp_unit.GetSupportFiles().GetFileSpecAtIndex(
1388-
decl_file ? *decl_file : 0),
1389-
decl_line ? *decl_line : 0, decl_column ? *decl_column : 0);
1390-
1391-
std::unique_ptr<Declaration> call_up;
1392-
if (call_file || call_line || call_column)
1393-
call_up = std::make_unique<Declaration>(
1394-
comp_unit.GetSupportFiles().GetFileSpecAtIndex(
1395-
call_file ? *call_file : 0),
1396-
call_line ? *call_line : 0, call_column ? *call_column : 0);
1397-
1398-
block->SetInlinedFunctionInfo(name, mangled_name, decl_up.get(),
1399-
call_up.get());
1318+
Block *block = parent_block->CreateChild(die.GetID()).get();
1319+
DWARFRangeList ranges;
1320+
const char *name = nullptr;
1321+
const char *mangled_name = nullptr;
1322+
1323+
std::optional<int> decl_file;
1324+
std::optional<int> decl_line;
1325+
std::optional<int> decl_column;
1326+
std::optional<int> call_file;
1327+
std::optional<int> call_line;
1328+
std::optional<int> call_column;
1329+
if (die.GetDIENamesAndRanges(name, mangled_name, ranges, decl_file,
1330+
decl_line, decl_column, call_file, call_line,
1331+
call_column, nullptr)) {
1332+
const size_t num_ranges = ranges.GetSize();
1333+
for (size_t i = 0; i < num_ranges; ++i) {
1334+
const DWARFRangeList::Entry &range = ranges.GetEntryRef(i);
1335+
const addr_t range_base = range.GetRangeBase();
1336+
if (range_base >= subprogram_low_pc)
1337+
block->AddRange(Block::Range(range_base - subprogram_low_pc,
1338+
range.GetByteSize()));
1339+
else {
1340+
GetObjectFile()->GetModule()->ReportError(
1341+
"{0:x8}: adding range [{1:x16}-{2:x16}) which has a base "
1342+
"that is less than the function's low PC {3:x16}. Please file "
1343+
"a bug and attach the file at the "
1344+
"start of this error message",
1345+
block->GetID(), range_base, range.GetRangeEnd(),
1346+
subprogram_low_pc);
14001347
}
1348+
}
1349+
block->FinalizeRanges();
1350+
1351+
if (tag != DW_TAG_subprogram &&
1352+
(name != nullptr || mangled_name != nullptr)) {
1353+
std::unique_ptr<Declaration> decl_up;
1354+
if (decl_file || decl_line || decl_column)
1355+
decl_up = std::make_unique<Declaration>(
1356+
comp_unit.GetSupportFiles().GetFileSpecAtIndex(
1357+
decl_file ? *decl_file : 0),
1358+
decl_line ? *decl_line : 0, decl_column ? *decl_column : 0);
1359+
1360+
std::unique_ptr<Declaration> call_up;
1361+
if (call_file || call_line || call_column)
1362+
call_up = std::make_unique<Declaration>(
1363+
comp_unit.GetSupportFiles().GetFileSpecAtIndex(
1364+
call_file ? *call_file : 0),
1365+
call_line ? *call_line : 0, call_column ? *call_column : 0);
1366+
1367+
block->SetInlinedFunctionInfo(name, mangled_name, decl_up.get(),
1368+
call_up.get());
1369+
}
14011370

1402-
++blocks_added;
1371+
++blocks_added;
14031372

1404-
if (die.HasChildren()) {
1405-
blocks_added +=
1406-
ParseBlocksRecursive(comp_unit, block, die.GetFirstChild(),
1407-
subprogram_low_pc, depth + 1);
1408-
}
1373+
if (die.HasChildren()) {
1374+
blocks_added += ParseBlocksRecursive(
1375+
comp_unit, block, die.GetFirstChild(), subprogram_low_pc);
14091376
}
1410-
} break;
1411-
default:
1412-
break;
14131377
}
1414-
1415-
// Only parse siblings of the block if we are not at depth zero. A depth of
1416-
// zero indicates we are currently parsing the top level DW_TAG_subprogram
1417-
// DIE
1418-
1419-
if (depth == 0)
1420-
die.Clear();
1421-
else
1422-
die = die.GetSibling();
14231378
}
14241379
return blocks_added;
14251380
}
@@ -3240,8 +3195,16 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) {
32403195
DWARFDIE function_die =
32413196
dwarf_cu->GetNonSkeletonUnit().GetDIE(function_die_offset);
32423197
if (function_die) {
3243-
ParseBlocksRecursive(*comp_unit, &func.GetBlock(false), function_die,
3244-
LLDB_INVALID_ADDRESS, 0);
3198+
// We can't use the file address from the Function object as (in the OSO
3199+
// case) it will already be remapped to the main module.
3200+
DWARFRangeList ranges = function_die.GetDIE()->GetAttributeAddressRanges(
3201+
function_die.GetCU(),
3202+
/*check_hi_lo_pc=*/true);
3203+
lldb::addr_t function_file_addr =
3204+
ranges.GetMinRangeBase(LLDB_INVALID_ADDRESS);
3205+
if (function_file_addr != LLDB_INVALID_ADDRESS)
3206+
ParseBlocksRecursive(*comp_unit, &func.GetBlock(false),
3207+
function_die.GetFirstChild(), function_file_addr);
32453208
}
32463209

32473210
return functions_added;

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -395,8 +395,7 @@ class SymbolFileDWARF : public SymbolFileCommon {
395395
Function *ParseFunction(CompileUnit &comp_unit, const DWARFDIE &die);
396396

397397
size_t ParseBlocksRecursive(CompileUnit &comp_unit, Block *parent_block,
398-
const DWARFDIE &die,
399-
lldb::addr_t subprogram_low_pc, uint32_t depth);
398+
DWARFDIE die, lldb::addr_t subprogram_low_pc);
400399

401400
size_t ParseTypes(const SymbolContext &sc, const DWARFDIE &die,
402401
bool parse_siblings, bool parse_children);

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

+3-9
Original file line numberDiff line numberDiff line change
@@ -394,18 +394,12 @@ Block *SymbolFileNativePDB::CreateBlock(PdbCompilandSymId block_id) {
394394

395395
switch (sym.kind()) {
396396
case S_GPROC32:
397-
case S_LPROC32: {
397+
case S_LPROC32:
398398
// This is a function. It must be global. Creating the Function entry
399399
// for it automatically creates a block for it.
400-
FunctionSP func = GetOrCreateFunction(block_id, *comp_unit);
401-
if (func) {
402-
Block &block = func->GetBlock(false);
403-
if (block.GetNumRanges() == 0)
404-
block.AddRange(Block::Range(0, func->GetAddressRange().GetByteSize()));
405-
return &block;
406-
}
400+
if (FunctionSP func = GetOrCreateFunction(block_id, *comp_unit))
401+
return &func->GetBlock(false);
407402
break;
408-
}
409403
case S_BLOCK32: {
410404
// This is a block. Its parent is either a function or another block. In
411405
// either case, its parent can be viewed as a block (e.g. a function

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

+20-32
Original file line numberDiff line numberDiff line change
@@ -402,44 +402,32 @@ static size_t ParseFunctionBlocksForPDBSymbol(
402402
assert(pdb_symbol && parent_block);
403403

404404
size_t num_added = 0;
405-
switch (pdb_symbol->getSymTag()) {
406-
case PDB_SymType::Block:
407-
case PDB_SymType::Function: {
408-
Block *block = nullptr;
409-
auto &raw_sym = pdb_symbol->getRawSymbol();
410-
if (auto *pdb_func = llvm::dyn_cast<PDBSymbolFunc>(pdb_symbol)) {
411-
if (pdb_func->hasNoInlineAttribute())
412-
break;
413-
if (is_top_parent)
414-
block = parent_block;
415-
else
416-
break;
417-
} else if (llvm::isa<PDBSymbolBlock>(pdb_symbol)) {
418-
auto uid = pdb_symbol->getSymIndexId();
419-
if (parent_block->FindBlockByID(uid))
420-
break;
421-
if (raw_sym.getVirtualAddress() < func_file_vm_addr)
422-
break;
423405

424-
block = parent_block->CreateChild(pdb_symbol->getSymIndexId()).get();
425-
} else
426-
llvm_unreachable("Unexpected PDB symbol!");
406+
if (!is_top_parent) {
407+
// Ranges for the top block were parsed together with the function.
408+
if (pdb_symbol->getSymTag() != PDB_SymType::Block)
409+
return num_added;
427410

411+
auto &raw_sym = pdb_symbol->getRawSymbol();
412+
assert(llvm::isa<PDBSymbolBlock>(pdb_symbol));
413+
auto uid = pdb_symbol->getSymIndexId();
414+
if (parent_block->FindBlockByID(uid))
415+
return num_added;
416+
if (raw_sym.getVirtualAddress() < func_file_vm_addr)
417+
return num_added;
418+
419+
Block *block = parent_block->CreateChild(pdb_symbol->getSymIndexId()).get();
428420
block->AddRange(Block::Range(
429421
raw_sym.getVirtualAddress() - func_file_vm_addr, raw_sym.getLength()));
430422
block->FinalizeRanges();
431-
++num_added;
423+
}
424+
auto results_up = pdb_symbol->findAllChildren();
425+
if (!results_up)
426+
return num_added;
432427

433-
auto results_up = pdb_symbol->findAllChildren();
434-
if (!results_up)
435-
break;
436-
while (auto symbol_up = results_up->getNext()) {
437-
num_added += ParseFunctionBlocksForPDBSymbol(
438-
func_file_vm_addr, symbol_up.get(), block, false);
439-
}
440-
} break;
441-
default:
442-
break;
428+
while (auto symbol_up = results_up->getNext()) {
429+
num_added += ParseFunctionBlocksForPDBSymbol(
430+
func_file_vm_addr, symbol_up.get(), parent_block, false);
443431
}
444432
return num_added;
445433
}

lldb/source/Symbol/Function.cpp

+12-4
Original file line numberDiff line numberDiff line change
@@ -279,9 +279,14 @@ Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid,
279279
AddressRanges ranges)
280280
: UserID(func_uid), m_comp_unit(comp_unit), m_type_uid(type_uid),
281281
m_type(type), m_mangled(mangled), m_block(*this, func_uid),
282-
m_ranges(std::move(ranges)), m_range(CollapseRanges(m_ranges)),
283-
m_frame_base(), m_flags(), m_prologue_byte_size(0) {
282+
m_range(CollapseRanges(ranges)), m_prologue_byte_size(0) {
284283
assert(comp_unit != nullptr);
284+
lldb::addr_t base_file_addr = m_range.GetBaseAddress().GetFileAddress();
285+
for (const AddressRange &range : ranges)
286+
m_block.AddRange(
287+
Block::Range(range.GetBaseAddress().GetFileAddress() - base_file_addr,
288+
range.GetByteSize()));
289+
m_block.FinalizeRanges();
285290
}
286291

287292
Function::~Function() = default;
@@ -426,13 +431,16 @@ void Function::GetDescription(Stream *s, lldb::DescriptionLevel level,
426431
llvm::interleaveComma(decl_context, *s, [&](auto &ctx) { ctx.Dump(*s); });
427432
*s << "}";
428433
}
429-
*s << ", range" << (m_ranges.size() > 1 ? "s" : "") << " = ";
434+
*s << ", range" << (m_block.GetNumRanges() > 1 ? "s" : "") << " = ";
430435
Address::DumpStyle fallback_style =
431436
level == eDescriptionLevelVerbose
432437
? Address::DumpStyleModuleWithFileAddress
433438
: Address::DumpStyleFileAddress;
434-
for (const AddressRange &range : m_ranges)
439+
for (unsigned idx = 0; idx < m_block.GetNumRanges(); ++idx) {
440+
AddressRange range;
441+
m_block.GetRangeAtIndex(idx, range);
435442
range.Dump(s, target, Address::DumpStyleLoadAddress, fallback_style);
443+
}
436444
}
437445

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

lldb/test/Shell/ScriptInterpreter/Python/sb_function_ranges.s

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# RUN: %lldb %t/input.o -o "command script import %t/script.py" -o exit | FileCheck %s
66

77
# CHECK: Found 1 function(s).
8-
# CHECK: foo: [input.o[0x0-0x7), input.o[0x7-0xe), input.o[0x14-0x1b), input.o[0x1b-0x1c)]
8+
# CHECK: foo: [input.o[0x0-0xe), input.o[0x14-0x1c)]
99

1010
#--- script.py
1111
import lldb

lldb/test/Shell/SymbolFile/DWARF/x86/discontinuous-function.s

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
# CHECK: 1 match found in {{.*}}
1212
# CHECK: Summary: {{.*}}`foo
13-
# CHECK: Function: id = {{.*}}, name = "foo", ranges = [0x0000000000000000-0x0000000000000007)[0x0000000000000007-0x000000000000000e)[0x0000000000000014-0x000000000000001b)[0x000000000000001b-0x000000000000001c)
13+
# CHECK: Function: id = {{.*}}, name = "foo", ranges = [0x0000000000000000-0x000000000000000e)[0x0000000000000014-0x000000000000001c)
1414

1515
.text
1616

lldb/test/Shell/SymbolFile/PDB/function-nested-block.test

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ REQUIRES: system-windows, lld
22
RUN: %build --compiler=clang-cl --nodefaultlib --output=%t.exe %S/Inputs/FunctionNestedBlockTest.cpp
33
RUN: lldb-test symbols -find=function -file FunctionNestedBlockTest.cpp -line 4 %t.exe | FileCheck --check-prefix=CHECK-FUNCTION %s
44
RUN: lldb-test symbols -find=block -file FunctionNestedBlockTest.cpp -line 4 %t.exe | FileCheck --check-prefix=CHECK-BLOCK %s
5-
XFAIL: *
65

76
CHECK-FUNCTION: Found 1 functions:
87
CHECK-FUNCTION: name = "{{.*}}", mangled = "{{_?}}main"

0 commit comments

Comments
 (0)