Skip to content

Commit be424b1

Browse files
committed
[lldb] Use the first address range as the function address
This is the behavior expected by DWARF. It also requires some fixups to algorithms which were storing the addresses of some objects (Blocks and Variables) relative to the beginning of the function. There are plenty of things that still don't work in this setups, but this change is sufficient for the expression evaluator to correctly recognize the entry point of a function in this case.
1 parent 66a88f6 commit be424b1

File tree

11 files changed

+65
-47
lines changed

11 files changed

+65
-47
lines changed

lldb/include/lldb/Symbol/Function.h

Lines changed: 1 addition & 1 deletion
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, AddressRanges ranges);
431+
Type *func_type, Address address, AddressRanges ranges);
432432

433433
/// Destructor.
434434
~Function() override;

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -251,11 +251,11 @@ FunctionSP SymbolFileBreakpad::GetOrCreateFunction(CompileUnit &comp_unit) {
251251
addr_t address = record->Address + base;
252252
SectionSP section_sp = list->FindSectionContainingFileAddress(address);
253253
if (section_sp) {
254-
AddressRange func_range(
255-
section_sp, address - section_sp->GetFileAddress(), record->Size);
254+
Address func_addr(section_sp, address-section_sp->GetFileAddress());
256255
// Use the CU's id because every CU has only one function inside.
257-
func_sp = std::make_shared<Function>(&comp_unit, id, 0, func_name,
258-
nullptr, AddressRanges{func_range});
256+
func_sp = std::make_shared<Function>(
257+
&comp_unit, id, 0, func_name, nullptr, func_addr,
258+
AddressRanges{AddressRange(func_addr, record->Size)});
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-
AddressRanges{func_range});
832+
symbol->GetAddress(), AddressRanges{func_range});
833833
m_functions.emplace_back(function_sp);
834834
cu.AddFunction(function_sp);
835835
}

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

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2393,10 +2393,29 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(
23932393
assert(func_type == nullptr || func_type != DIE_IS_BEING_PARSED);
23942394

23952395
const user_id_t func_user_id = die.GetID();
2396+
2397+
// The base address of the scope for any of the debugging information
2398+
// entries listed above is given by either the DW_AT_low_pc attribute or the
2399+
// first address in the first range entry in the list of ranges given by the
2400+
// DW_AT_ranges attribute.
2401+
// -- DWARFv5, Section 2.17 Code Addresses, Ranges and Base Addresses
2402+
//
2403+
// If no DW_AT_entry_pc attribute is present, then the entry address is
2404+
// assumed to be the same as the base address of the containing scope.
2405+
// -- DWARFv5, Section 2.18 Entry Address
2406+
//
2407+
// We currently don't support Debug Info Entries with
2408+
// DW_AT_low_pc/DW_AT_entry_pc and DW_AT_ranges attributes (the latter
2409+
// attributes are ignored even though they should be used for the address of
2410+
// the function), but compilers also don't emit that kind of information. If
2411+
// this becomes a problem we need to plumb these attributes separately.
2412+
Address func_addr = func_ranges[0].GetBaseAddress();
2413+
23962414
func_sp = std::make_shared<Function>(
23972415
&comp_unit,
23982416
func_user_id, // UserID is the DIE offset
2399-
func_user_id, func_name, func_type, std::move(func_ranges));
2417+
func_user_id, func_name, func_type, std::move(func_addr),
2418+
std::move(func_ranges));
24002419

24012420
if (func_sp.get() != nullptr) {
24022421
if (frame_base.IsValid())

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,10 +263,9 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
263263
}
264264

265265
if (set_frame_base_loclist_addr && !ranges.empty()) {
266-
// TODO: Use the first range instead.
267-
dw_addr_t lowest_range_pc = llvm::min_element(ranges)->LowPC;
268-
assert(lowest_range_pc >= cu->GetBaseAddress());
269-
frame_base->SetFuncFileAddress(lowest_range_pc);
266+
dw_addr_t file_addr = ranges.begin()->LowPC;
267+
assert(file_addr >= cu->GetBaseAddress());
268+
frame_base->SetFuncFileAddress(file_addr);
270269
}
271270

272271
if (ranges.empty() || name == nullptr || mangled == nullptr) {

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3183,8 +3183,7 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) {
31833183
/*check_hi_lo_pc=*/true)) {
31843184
if (ranges->empty())
31853185
return 0;
3186-
// TODO: Use the first range instead.
3187-
dw_addr_t function_file_addr = llvm::min_element(*ranges)->LowPC;
3186+
dw_addr_t function_file_addr = ranges->begin()->LowPC;
31883187
if (function_file_addr != LLDB_INVALID_ADDRESS)
31893188
ParseBlocksRecursive(*comp_unit, &func.GetBlock(false),
31903189
function_die.GetFirstChild(), function_file_addr);
@@ -3223,9 +3222,8 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) {
32233222
if (llvm::Expected<llvm::DWARFAddressRangesVector> ranges =
32243223
function_die.GetDIE()->GetAttributeAddressRanges(
32253224
function_die.GetCU(), /*check_hi_lo_pc=*/true)) {
3226-
// TODO: Use the first range element instead.
32273225
if (!ranges->empty())
3228-
func_lo_pc = llvm::min_element(*ranges)->LowPC;
3226+
func_lo_pc = ranges->begin()->LowPC;
32293227
} else {
32303228
LLDB_LOG_ERROR(GetLog(DWARFLog::DebugInfo), ranges.takeError(),
32313229
"DIE({1:x}): {0}", function_die.GetID());

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

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -483,9 +483,8 @@ lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbCompilandSymId func_id,
483483
if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)
484484
return nullptr;
485485

486-
AddressRange func_range(file_vm_addr, sol.length,
487-
comp_unit.GetModule()->GetSectionList());
488-
if (!func_range.GetBaseAddress().IsValid())
486+
Address func_addr(file_vm_addr, comp_unit.GetModule()->GetSectionList());
487+
if (!func_addr.IsValid())
489488
return nullptr;
490489

491490
ProcSym proc(static_cast<SymbolRecordKind>(sym_record.kind()));
@@ -500,7 +499,8 @@ lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbCompilandSymId func_id,
500499
Mangled mangled(proc.Name);
501500
FunctionSP func_sp = std::make_shared<Function>(
502501
&comp_unit, toOpaqueUid(func_id), toOpaqueUid(sig_id), mangled,
503-
func_type.get(), AddressRanges{func_range});
502+
func_type.get(), func_addr,
503+
AddressRanges{AddressRange(func_addr, sol.length)});
504504

505505
comp_unit.AddFunction(func_sp);
506506

@@ -1279,9 +1279,7 @@ bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) {
12791279
if (file_vm_addr == LLDB_INVALID_ADDRESS)
12801280
continue;
12811281

1282-
AddressRange func_range(file_vm_addr, sol.length,
1283-
comp_unit.GetModule()->GetSectionList());
1284-
Address func_base = func_range.GetBaseAddress();
1282+
Address func_base(file_vm_addr, comp_unit.GetModule()->GetSectionList());
12851283
PdbCompilandSymId func_id{modi, record_offset};
12861284

12871285
// Iterate all S_INLINESITEs in the function.

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -296,10 +296,9 @@ SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func,
296296
return nullptr;
297297

298298
auto func_length = pdb_func.getLength();
299-
AddressRange func_range =
300-
AddressRange(file_vm_addr, func_length,
301-
GetObjectFile()->GetModule()->GetSectionList());
302-
if (!func_range.GetBaseAddress().IsValid())
299+
Address func_addr(file_vm_addr,
300+
GetObjectFile()->GetModule()->GetSectionList());
301+
if (!func_addr.IsValid())
303302
return nullptr;
304303

305304
lldb_private::Type *func_type = ResolveTypeUID(pdb_func.getSymIndexId());
@@ -312,7 +311,7 @@ SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func,
312311

313312
FunctionSP func_sp = std::make_shared<Function>(
314313
&comp_unit, pdb_func.getSymIndexId(), func_type_uid, mangled, func_type,
315-
AddressRanges{func_range});
314+
func_addr, AddressRanges{AddressRange(func_addr, func_length)});
316315

317316
comp_unit.AddFunction(func_sp);
318317

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -179,14 +179,14 @@ size_t SymbolFileSymtab::ParseFunctions(CompileUnit &comp_unit) {
179179
}
180180
}
181181

182-
FunctionSP func_sp(
183-
new Function(&comp_unit,
184-
symbol_idx, // UserID is the DIE offset
185-
LLDB_INVALID_UID, // We don't have any type info
186-
// for this function
187-
curr_symbol->GetMangled(), // Linker/mangled name
188-
nullptr, // no return type for a code symbol...
189-
AddressRanges{func_range}));
182+
FunctionSP func_sp(new Function(
183+
&comp_unit,
184+
symbol_idx, // UserID is the DIE offset
185+
LLDB_INVALID_UID, // We don't have any type info
186+
// for this function
187+
curr_symbol->GetMangled(), // Linker/mangled name
188+
nullptr, // no return type for a code symbol...
189+
curr_symbol->GetAddress(), AddressRanges{func_range}));
190190

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

lldb/source/Symbol/Function.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,10 +276,10 @@ AddressRange CollapseRanges(llvm::ArrayRef<AddressRange> ranges) {
276276
//
277277
Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid,
278278
lldb::user_id_t type_uid, const Mangled &mangled, Type *type,
279-
AddressRanges ranges)
279+
Address address, 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_address(m_range.GetBaseAddress()),
282+
m_range(CollapseRanges(ranges)), m_address(std::move(address)),
283283
m_prologue_byte_size(0) {
284284
assert(comp_unit != nullptr);
285285
lldb::addr_t base_file_addr = m_address.GetFileAddress();

0 commit comments

Comments
 (0)