Skip to content

Commit 2526d5b

Browse files
committed
Revert "[lldb] Use the function block as a source for function ranges (llvm#117996)"
This reverts commit ba14dac. I guess "has no conflicts" doesn't mean "it will build".
1 parent ba14dac commit 2526d5b

File tree

9 files changed

+163
-109
lines changed

9 files changed

+163
-109
lines changed

lldb/include/lldb/Symbol/Function.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,9 @@ 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+
656659
/// The function address range that covers the widest range needed to contain
657660
/// all blocks. DEPRECATED: do not use this field in new code as the range may
658661
/// include addresses belonging to other functions.

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,9 @@ 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-
blocks.push_back(&func.GetBlock(false));
302+
Block &block = func.GetBlock(false);
303+
block.AddRange(Block::Range(0, func.GetAddressRange().GetByteSize()));
304+
blocks.push_back(&block);
303305

304306
size_t blocks_added = 0;
305307
addr_t func_base = func.GetAddressRange().GetBaseAddress().GetOffset();

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

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

1308-
size_t SymbolFileDWARF::ParseBlocksRecursive(CompileUnit &comp_unit,
1309-
Block *parent_block, DWARFDIE die,
1310-
addr_t subprogram_low_pc) {
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) {
13111311
size_t blocks_added = 0;
1312-
for (; die; die = die.GetSibling()) {
1312+
DWARFDIE die = orig_die;
1313+
while (die) {
13131314
dw_tag_t tag = die.Tag();
13141315

1315-
if (tag != DW_TAG_inlined_subroutine && tag != DW_TAG_lexical_block)
1316-
continue;
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.
13171325

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);
1347-
}
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());
1326+
if (depth > 0)
1327+
break;
1328+
1329+
block = parent_block;
1330+
} else {
1331+
block = parent_block->CreateChild(die.GetID()).get();
13691332
}
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+
}
13701362

1371-
++blocks_added;
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());
1400+
}
1401+
1402+
++blocks_added;
13721403

1373-
if (die.HasChildren()) {
1374-
blocks_added += ParseBlocksRecursive(
1375-
comp_unit, block, die.GetFirstChild(), subprogram_low_pc);
1404+
if (die.HasChildren()) {
1405+
blocks_added +=
1406+
ParseBlocksRecursive(comp_unit, block, die.GetFirstChild(),
1407+
subprogram_low_pc, depth + 1);
1408+
}
13761409
}
1410+
} break;
1411+
default:
1412+
break;
13771413
}
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();
13781423
}
13791424
return blocks_added;
13801425
}
@@ -3195,16 +3240,8 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) {
31953240
DWARFDIE function_die =
31963241
dwarf_cu->GetNonSkeletonUnit().GetDIE(function_die_offset);
31973242
if (function_die) {
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);
3243+
ParseBlocksRecursive(*comp_unit, &func.GetBlock(false), function_die,
3244+
LLDB_INVALID_ADDRESS, 0);
32083245
}
32093246

32103247
return functions_added;

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,8 @@ 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-
DWARFDIE die, lldb::addr_t subprogram_low_pc);
398+
const DWARFDIE &die,
399+
lldb::addr_t subprogram_low_pc, uint32_t depth);
399400

400401
size_t ParseTypes(const SymbolContext &sc, const DWARFDIE &die,
401402
bool parse_siblings, bool parse_children);

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -394,12 +394,18 @@ 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-
if (FunctionSP func = GetOrCreateFunction(block_id, *comp_unit))
401-
return &func->GetBlock(false);
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+
}
402407
break;
408+
}
403409
case S_BLOCK32: {
404410
// This is a block. Its parent is either a function or another block. In
405411
// either case, its parent can be viewed as a block (e.g. a function

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

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -402,32 +402,44 @@ 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;
405423

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;
424+
block = parent_block->CreateChild(pdb_symbol->getSymIndexId()).get();
425+
} else
426+
llvm_unreachable("Unexpected PDB symbol!");
410427

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();
420428
block->AddRange(Block::Range(
421429
raw_sym.getVirtualAddress() - func_file_vm_addr, raw_sym.getLength()));
422430
block->FinalizeRanges();
423-
}
424-
auto results_up = pdb_symbol->findAllChildren();
425-
if (!results_up)
426-
return num_added;
431+
++num_added;
427432

428-
while (auto symbol_up = results_up->getNext()) {
429-
num_added += ParseFunctionBlocksForPDBSymbol(
430-
func_file_vm_addr, symbol_up.get(), parent_block, false);
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;
431443
}
432444
return num_added;
433445
}

lldb/source/Symbol/Function.cpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -279,14 +279,9 @@ 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_range(CollapseRanges(ranges)), m_prologue_byte_size(0) {
282+
m_ranges(std::move(ranges)), m_range(CollapseRanges(m_ranges)),
283+
m_frame_base(), m_flags(), m_prologue_byte_size(0) {
283284
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();
290285
}
291286

292287
Function::~Function() = default;
@@ -431,16 +426,13 @@ void Function::GetDescription(Stream *s, lldb::DescriptionLevel level,
431426
llvm::interleaveComma(decl_context, *s, [&](auto &ctx) { ctx.Dump(*s); });
432427
*s << "}";
433428
}
434-
*s << ", range" << (m_block.GetNumRanges() > 1 ? "s" : "") << " = ";
429+
*s << ", range" << (m_ranges.size() > 1 ? "s" : "") << " = ";
435430
Address::DumpStyle fallback_style =
436431
level == eDescriptionLevelVerbose
437432
? Address::DumpStyleModuleWithFileAddress
438433
: Address::DumpStyleFileAddress;
439-
for (unsigned idx = 0; idx < m_block.GetNumRanges(); ++idx) {
440-
AddressRange range;
441-
m_block.GetRangeAtIndex(idx, range);
434+
for (const AddressRange &range : m_ranges)
442435
range.Dump(s, target, Address::DumpStyleLoadAddress, fallback_style);
443-
}
444436
}
445437

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

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

Lines changed: 1 addition & 1 deletion
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-0x000000000000000e)[0x0000000000000014-0x000000000000001c)
13+
# CHECK: Function: id = {{.*}}, name = "foo", ranges = [0x0000000000000000-0x0000000000000007)[0x0000000000000007-0x000000000000000e)[0x0000000000000014-0x000000000000001b)[0x000000000000001b-0x000000000000001c)
1414

1515
.text
1616

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ 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: *
56

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

0 commit comments

Comments
 (0)