Skip to content

Commit 93f2b59

Browse files
committed
Merge commit '2edf534f5542' from llvm.org/main into next
Conflicts: lldb/source/Expression/DWARFExpression.cpp rdar://147772462
2 parents 9e9e26b + 2edf534 commit 93f2b59

File tree

8 files changed

+175
-128
lines changed

8 files changed

+175
-128
lines changed

lldb/include/lldb/Expression/DWARFExpression.h

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "lldb/Core/Address.h"
1313
#include "lldb/Core/Disassembler.h"
14+
#include "lldb/Core/dwarf.h"
1415
#include "lldb/Utility/DataExtractor.h"
1516
#include "lldb/Utility/Scalar.h"
1617
#include "lldb/Utility/Status.h"
@@ -21,12 +22,6 @@
2122

2223
namespace lldb_private {
2324

24-
namespace plugin {
25-
namespace dwarf {
26-
class DWARFUnit;
27-
} // namespace dwarf
28-
} // namespace plugin
29-
3025
/// \class DWARFExpression DWARFExpression.h
3126
/// "lldb/Expression/DWARFExpression.h" Encapsulates a DWARF location
3227
/// expression and interprets it.
@@ -40,6 +35,30 @@ class DWARFUnit;
4035
/// location expression or a location list and interprets it.
4136
class DWARFExpression {
4237
public:
38+
class Delegate {
39+
public:
40+
Delegate() = default;
41+
virtual ~Delegate() = default;
42+
43+
virtual uint16_t GetVersion() const = 0;
44+
virtual dw_addr_t GetBaseAddress() const = 0;
45+
virtual uint8_t GetAddressByteSize() const = 0;
46+
virtual llvm::Expected<std::pair<uint64_t, bool>>
47+
GetDIEBitSizeAndSign(uint64_t relative_die_offset) const = 0;
48+
virtual dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const = 0;
49+
virtual lldb::offset_t
50+
GetVendorDWARFOpcodeSize(const DataExtractor &data,
51+
const lldb::offset_t data_offset,
52+
const uint8_t op) const = 0;
53+
virtual bool ParseVendorDWARFOpcode(uint8_t op,
54+
const DataExtractor &opcodes,
55+
lldb::offset_t &offset,
56+
std::vector<Value> &stack) const = 0;
57+
58+
Delegate(const Delegate &) = delete;
59+
Delegate &operator=(const Delegate &) = delete;
60+
};
61+
4362
DWARFExpression();
4463

4564
/// Constructor
@@ -66,19 +85,17 @@ class DWARFExpression {
6685
/// The address specified by the operation, if the operation exists, or
6786
/// an llvm::Error otherwise.
6887
llvm::Expected<lldb::addr_t>
69-
GetLocation_DW_OP_addr(const plugin::dwarf::DWARFUnit *dwarf_cu) const;
88+
GetLocation_DW_OP_addr(const Delegate *dwarf_cu) const;
7089

71-
bool Update_DW_OP_addr(const plugin::dwarf::DWARFUnit *dwarf_cu,
72-
lldb::addr_t file_addr);
90+
bool Update_DW_OP_addr(const Delegate *dwarf_cu, lldb::addr_t file_addr);
7391

7492
void UpdateValue(uint64_t const_value, lldb::offset_t const_value_byte_size,
7593
uint8_t addr_byte_size);
7694

77-
bool
78-
ContainsThreadLocalStorage(const plugin::dwarf::DWARFUnit *dwarf_cu) const;
95+
bool ContainsThreadLocalStorage(const Delegate *dwarf_cu) const;
7996

8097
bool LinkThreadLocalStorage(
81-
const plugin::dwarf::DWARFUnit *dwarf_cu,
98+
const Delegate *dwarf_cu,
8299
std::function<lldb::addr_t(lldb::addr_t file_addr)> const
83100
&link_address_callback);
84101

@@ -132,13 +149,8 @@ class DWARFExpression {
132149
static llvm::Expected<Value>
133150
Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
134151
lldb::ModuleSP module_sp, const DataExtractor &opcodes,
135-
const plugin::dwarf::DWARFUnit *dwarf_cu,
136-
const lldb::RegisterKind reg_set, const Value *initial_value_ptr,
137-
const Value *object_address_ptr);
138-
139-
static bool ParseDWARFLocationList(const plugin::dwarf::DWARFUnit *dwarf_cu,
140-
const DataExtractor &data,
141-
DWARFExpressionList *loc_list);
152+
const Delegate *dwarf_cu, const lldb::RegisterKind reg_set,
153+
const Value *initial_value_ptr, const Value *object_address_ptr);
142154

143155
bool GetExpressionData(DataExtractor &data) const {
144156
data = m_data;

lldb/source/Expression/DWARFExpression.cpp

Lines changed: 38 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
#include "lldb/Core/Module.h"
1717
#include "lldb/Core/Value.h"
18-
#include "lldb/Core/dwarf.h"
1918
#include "lldb/Utility/DataEncoder.h"
2019
#include "lldb/Utility/LLDBLog.h"
2120
#include "lldb/Utility/Log.h"
@@ -37,7 +36,6 @@
3736
#include "lldb/Target/StackID.h"
3837
#include "lldb/Target/Target.h"
3938
#include "lldb/Target/Thread.h"
40-
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
4139
#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
4240

4341
#ifdef LLDB_ENABLE_SWIFT
@@ -134,10 +132,10 @@ static llvm::Error ReadRegisterValueAsScalar(RegisterContext *reg_ctx,
134132

135133
/// Return the length in bytes of the set of operands for \p op. No guarantees
136134
/// are made on the state of \p data after this call.
137-
static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data,
138-
const lldb::offset_t data_offset,
139-
const LocationAtom op,
140-
const DWARFUnit *dwarf_cu) {
135+
static lldb::offset_t
136+
GetOpcodeDataSize(const DataExtractor &data, const lldb::offset_t data_offset,
137+
const LocationAtom op,
138+
const DWARFExpression::Delegate *dwarf_cu) {
141139
lldb::offset_t offset = data_offset;
142140
switch (op) {
143141
// Only used in LLVM metadata.
@@ -366,7 +364,8 @@ static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data,
366364
// + LEB128
367365
{
368366
data.Skip_LEB128(&offset);
369-
return DWARFUnit::GetAddressByteSize(dwarf_cu) + offset - data_offset;
367+
return (dwarf_cu ? dwarf_cu->GetAddressByteSize() : 4) + offset -
368+
data_offset;
370369
}
371370

372371
case DW_OP_GNU_entry_value:
@@ -391,14 +390,23 @@ static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data,
391390
}
392391

393392
if (dwarf_cu)
394-
return dwarf_cu->GetSymbolFileDWARF().GetVendorDWARFOpcodeSize(
395-
data, data_offset, op);
393+
return dwarf_cu->GetVendorDWARFOpcodeSize(data, data_offset, op);
396394

397395
return LLDB_INVALID_OFFSET;
398396
}
399397

400-
llvm::Expected<lldb::addr_t>
401-
DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu) const {
398+
static const char *DW_OP_value_to_name(uint32_t val) {
399+
static char invalid[100];
400+
llvm::StringRef llvmstr = llvm::dwarf::OperationEncodingString(val);
401+
if (llvmstr.empty()) {
402+
snprintf(invalid, sizeof(invalid), "Unknown DW_OP constant: 0x%x", val);
403+
return invalid;
404+
}
405+
return llvmstr.data();
406+
}
407+
408+
llvm::Expected<lldb::addr_t> DWARFExpression::GetLocation_DW_OP_addr(
409+
const DWARFExpression::Delegate *dwarf_cu) const {
402410
lldb::offset_t offset = 0;
403411
while (m_data.ValidOffset(offset)) {
404412
const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset));
@@ -426,8 +434,8 @@ DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu) const {
426434
return LLDB_INVALID_ADDRESS;
427435
}
428436

429-
bool DWARFExpression::Update_DW_OP_addr(const DWARFUnit *dwarf_cu,
430-
lldb::addr_t file_addr) {
437+
bool DWARFExpression::Update_DW_OP_addr(
438+
const DWARFExpression::Delegate *dwarf_cu, lldb::addr_t file_addr) {
431439
lldb::offset_t offset = 0;
432440
while (m_data.ValidOffset(offset)) {
433441
const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset));
@@ -485,7 +493,7 @@ bool DWARFExpression::Update_DW_OP_addr(const DWARFUnit *dwarf_cu,
485493
}
486494

487495
bool DWARFExpression::ContainsThreadLocalStorage(
488-
const DWARFUnit *dwarf_cu) const {
496+
const DWARFExpression::Delegate *dwarf_cu) const {
489497
lldb::offset_t offset = 0;
490498
while (m_data.ValidOffset(offset)) {
491499
const LocationAtom op = static_cast<LocationAtom>(m_data.GetU8(&offset));
@@ -501,7 +509,7 @@ bool DWARFExpression::ContainsThreadLocalStorage(
501509
return false;
502510
}
503511
bool DWARFExpression::LinkThreadLocalStorage(
504-
const DWARFUnit *dwarf_cu,
512+
const DWARFExpression::Delegate *dwarf_cu,
505513
std::function<lldb::addr_t(lldb::addr_t file_addr)> const
506514
&link_address_callback) {
507515
const uint32_t addr_byte_size = m_data.GetAddressByteSize();
@@ -868,9 +876,9 @@ enum LocationDescriptionKind {
868876
/* Composite*/
869877
};
870878
/// Adjust value's ValueType according to the kind of location description.
871-
void UpdateValueTypeFromLocationDescription(Log *log, const DWARFUnit *dwarf_cu,
872-
LocationDescriptionKind kind,
873-
Value *value = nullptr) {
879+
void UpdateValueTypeFromLocationDescription(
880+
Log *log, const DWARFExpression::Delegate *dwarf_cu,
881+
LocationDescriptionKind kind, Value *value = nullptr) {
874882
// Note that this function is conflating DWARF expressions with
875883
// DWARF location descriptions. Perhaps it would be better to define
876884
// a wrapper for DWARFExpression::Eval() that deals with DWARF
@@ -960,8 +968,9 @@ static Scalar DerefSizeExtractDataHelper(uint8_t *addr_bytes,
960968
llvm::Expected<Value> DWARFExpression::Evaluate(
961969
ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
962970
lldb::ModuleSP module_sp, const DataExtractor &opcodes,
963-
const DWARFUnit *dwarf_cu, const lldb::RegisterKind reg_kind,
964-
const Value *initial_value_ptr, const Value *object_address_ptr) {
971+
const DWARFExpression::Delegate *dwarf_cu,
972+
const lldb::RegisterKind reg_kind, const Value *initial_value_ptr,
973+
const Value *object_address_ptr) {
965974

966975
if (opcodes.GetByteSize() == 0)
967976
return llvm::createStringError(
@@ -2235,10 +2244,10 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
22352244
// DESCRIPTION: Pop the top stack element, convert it to a
22362245
// different type, and push the result.
22372246
case DW_OP_convert: {
2238-
const uint64_t die_offset = opcodes.GetULEB128(&offset);
2247+
const uint64_t relative_die_offset = opcodes.GetULEB128(&offset);
22392248
uint64_t bit_size;
22402249
bool sign;
2241-
if (die_offset == 0) {
2250+
if (relative_die_offset == 0) {
22422251
// The generic type has the size of an address on the target
22432252
// machine and an unspecified signedness. Scalar has no
22442253
// "unspecified signedness", so we use unsigned types.
@@ -2249,35 +2258,12 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
22492258
if (!bit_size)
22502259
return llvm::createStringError("unspecified architecture");
22512260
} else {
2252-
// Retrieve the type DIE that the value is being converted to. This
2253-
// offset is compile unit relative so we need to fix it up.
2254-
const uint64_t abs_die_offset = die_offset + dwarf_cu->GetOffset();
2255-
// FIXME: the constness has annoying ripple effects.
2256-
DWARFDIE die = const_cast<DWARFUnit *>(dwarf_cu)->GetDIE(abs_die_offset);
2257-
if (!die)
2258-
return llvm::createStringError(
2259-
"cannot resolve DW_OP_convert type DIE");
2260-
uint64_t encoding =
2261-
die.GetAttributeValueAsUnsigned(DW_AT_encoding, DW_ATE_hi_user);
2262-
bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
2263-
if (!bit_size)
2264-
bit_size = die.GetAttributeValueAsUnsigned(DW_AT_bit_size, 0);
2265-
if (!bit_size)
2266-
return llvm::createStringError(
2267-
"unsupported type size in DW_OP_convert");
2268-
switch (encoding) {
2269-
case DW_ATE_signed:
2270-
case DW_ATE_signed_char:
2271-
sign = true;
2272-
break;
2273-
case DW_ATE_unsigned:
2274-
case DW_ATE_unsigned_char:
2275-
sign = false;
2276-
break;
2277-
default:
2278-
return llvm::createStringError(
2279-
"unsupported encoding in DW_OP_convert");
2280-
}
2261+
auto bit_size_sign_or_err =
2262+
dwarf_cu->GetDIEBitSizeAndSign(relative_die_offset);
2263+
if (!bit_size_sign_or_err)
2264+
return bit_size_sign_or_err.takeError();
2265+
bit_size = bit_size_sign_or_err->first;
2266+
sign = bit_size_sign_or_err->second;
22812267
}
22822268
Scalar &top = stack.back().ResolveValue(exe_ctx);
22832269
top.TruncOrExtendTo(bit_size, sign);
@@ -2401,8 +2387,7 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
24012387

24022388
default:
24032389
if (dwarf_cu) {
2404-
if (dwarf_cu->GetSymbolFileDWARF().ParseVendorDWARFOpcode(
2405-
op, opcodes, offset, stack)) {
2390+
if (dwarf_cu->ParseVendorDWARFOpcode(op, opcodes, offset, stack)) {
24062391
break;
24072392
}
24082393
}
@@ -2437,43 +2422,6 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
24372422
return stack.back();
24382423
}
24392424

2440-
bool DWARFExpression::ParseDWARFLocationList(
2441-
const DWARFUnit *dwarf_cu, const DataExtractor &data,
2442-
DWARFExpressionList *location_list) {
2443-
location_list->Clear();
2444-
std::unique_ptr<llvm::DWARFLocationTable> loctable_up =
2445-
dwarf_cu->GetLocationTable(data);
2446-
Log *log = GetLog(LLDBLog::Expressions);
2447-
auto lookup_addr =
2448-
[&](uint32_t index) -> std::optional<llvm::object::SectionedAddress> {
2449-
addr_t address = dwarf_cu->ReadAddressFromDebugAddrSection(index);
2450-
if (address == LLDB_INVALID_ADDRESS)
2451-
return std::nullopt;
2452-
return llvm::object::SectionedAddress{address};
2453-
};
2454-
auto process_list = [&](llvm::Expected<llvm::DWARFLocationExpression> loc) {
2455-
if (!loc) {
2456-
LLDB_LOG_ERROR(log, loc.takeError(), "{0}");
2457-
return true;
2458-
}
2459-
auto buffer_sp =
2460-
std::make_shared<DataBufferHeap>(loc->Expr.data(), loc->Expr.size());
2461-
DWARFExpression expr = DWARFExpression(DataExtractor(
2462-
buffer_sp, data.GetByteOrder(), data.GetAddressByteSize()));
2463-
location_list->AddExpression(loc->Range->LowPC, loc->Range->HighPC, expr);
2464-
return true;
2465-
};
2466-
llvm::Error error = loctable_up->visitAbsoluteLocationList(
2467-
0, llvm::object::SectionedAddress{dwarf_cu->GetBaseAddress()},
2468-
lookup_addr, process_list);
2469-
location_list->Sort();
2470-
if (error) {
2471-
LLDB_LOG_ERROR(log, std::move(error), "{0}");
2472-
return false;
2473-
}
2474-
return true;
2475-
}
2476-
24772425
bool DWARFExpression::MatchesOperand(
24782426
StackFrame &frame, const Instruction::Operand &operand) const {
24792427
using namespace OperandMatchers;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
240240
data = DataExtractor(data, offset, data.GetByteSize() - offset);
241241
if (lo_pc != LLDB_INVALID_ADDRESS) {
242242
assert(lo_pc >= cu->GetBaseAddress());
243-
DWARFExpression::ParseDWARFLocationList(cu, data, frame_base);
243+
cu->ParseDWARFLocationList(data, *frame_base);
244244
frame_base->SetFuncFileAddress(lo_pc);
245245
} else
246246
set_frame_base_loclist_addr = true;

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

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,5 @@ llvm::StringRef DW_TAG_value_to_name(dw_tag_t tag) {
2323
return s_unknown_tag_name;
2424
}
2525

26-
const char *DW_OP_value_to_name(uint32_t val) {
27-
static char invalid[100];
28-
llvm::StringRef llvmstr = llvm::dwarf::OperationEncodingString(val);
29-
if (llvmstr.empty()) {
30-
snprintf(invalid, sizeof(invalid), "Unknown DW_OP constant: 0x%x", val);
31-
return invalid;
32-
}
33-
return llvmstr.data();
34-
}
35-
3626
} // namespace dwarf
3727
} // namespace lldb_private::plugin

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ namespace dwarf {
1717

1818
llvm::StringRef DW_TAG_value_to_name(dw_tag_t tag);
1919

20-
const char *DW_OP_value_to_name(uint32_t val);
21-
2220
} // namespace dwarf
2321
} // namespace lldb_private::plugin
2422

0 commit comments

Comments
 (0)