40#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
41#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
61 uint8_t addr_byte_size) {
62 if (!const_value_byte_size)
66 DataBufferSP(
new DataBufferHeap(&const_value, const_value_byte_size)));
74 auto GetRegName = [&MCRegInfo](uint64_t DwarfRegNum,
75 bool IsEH) -> llvm::StringRef {
78 if (std::optional<unsigned> LLVMRegNum =
79 MCRegInfo->getLLVMRegNum(DwarfRegNum, IsEH))
80 if (
const char *RegName = MCRegInfo->getName(*LLVMRegNum))
81 return llvm::StringRef(RegName);
84 llvm::DIDumpOptions DumpOpts;
85 DumpOpts.GetNameForDWARFReg = GetRegName;
101 if (reg_ctx ==
nullptr) {
110 "kind=%u reg_num=%u to a native "
111 "register number.\n",
114 const RegisterInfo *reg_info =
121 const_cast<RegisterInfo *
>(reg_info));
130 "register %s can't be converted to a scalar value",
147 const uint8_t op,
const DWARFUnit *dwarf_cu) {
247 case DW_OP_push_object_address:
248 case DW_OP_form_tls_address:
249 case DW_OP_call_frame_cfa:
250 case DW_OP_stack_value:
251 case DW_OP_GNU_push_tls_address:
258 case DW_OP_deref_size:
259 case DW_OP_xderef_size:
285 case DW_OP_plus_uconst:
321 case DW_OP_GNU_addr_index:
322 case DW_OP_GNU_const_index:
324 return offset - data_offset;
328 case DW_OP_bit_piece:
331 return offset - data_offset;
333 case DW_OP_implicit_value:
338 return offset - data_offset;
341 case DW_OP_GNU_entry_value:
342 case DW_OP_entry_value:
344 uint64_t subexpr_len = data.
GetULEB128(&offset);
345 return (offset - data_offset) + subexpr_len;
353 data, data_offset, op);
366 if (op == DW_OP_addr) {
368 if (curr_op_addr_idx == op_addr_idx)
371 }
else if (op == DW_OP_GNU_addr_index || op == DW_OP_addrx) {
373 if (curr_op_addr_idx == op_addr_idx) {
389 offset += op_arg_size;
401 if (op == DW_OP_addr) {
415 if (encoder.PutAddress(offset, file_addr) ==
UINT32_MAX)
427 offset += op_arg_size;
439 if (op == DW_OP_form_tls_address || op == DW_OP_GNU_push_tls_address)
445 offset += op_arg_size;
452 &link_address_callback) {
466 size_t const_byte_size = 0;
470 bool decoded_data =
false;
475 const_offset = offset;
484 const_offset = offset;
490 case DW_OP_form_tls_address:
491 case DW_OP_GNU_push_tls_address:
502 if (const_byte_size > 0) {
503 lldb::addr_t linked_file_addr = link_address_callback(const_value);
507 if (encoder.PutUnsigned(const_offset, const_byte_size,
526 offset += op_arg_size;
586 LLDB_LOG(log,
"Evaluate_DW_OP_entry_value: no exe/reg context");
592 if (!current_frame || !thread) {
593 LLDB_LOG(log,
"Evaluate_DW_OP_entry_value: no current frame/thread");
598 StackFrameSP parent_frame =
nullptr;
602 for (
uint32_t parent_frame_idx = current_frame_idx + 1;
603 parent_frame_idx < num_frames; ++parent_frame_idx) {
613 return_pc = parent_frame->GetFrameCodeAddress().GetLoadAddress(&target);
615 "Evaluate_DW_OP_entry_value: immediate ancestor with pc = {0:x}",
621 if (parent_frame->IsInlined())
627 if (!parent_frame || !parent_frame->GetRegisterContext()) {
628 LLDB_LOG(log,
"Evaluate_DW_OP_entry_value: no parent frame with reg ctx");
633 parent_frame->GetSymbolContext(eSymbolContextFunction).function;
635 LLDB_LOG(log,
"Evaluate_DW_OP_entry_value: no parent function");
644 LLDB_LOG(log,
"Evaluate_DW_OP_entry_value: no current function");
652 if (!parent_frame->IsArtificial()) {
658 "Evaluate_DW_OP_entry_value: no call edge for retn-pc = {0:x} "
659 "in parent frame {1}",
660 return_pc, parent_func->
GetName());
664 if (callee_func != current_func) {
665 LLDB_LOG(log,
"Evaluate_DW_OP_entry_value: ambiguous call sequence, "
666 "can't find real parent frame");
674 if (edge->GetCallee(modlist, parent_exe_ctx) == current_func) {
675 call_edge = edge.get();
681 LLDB_LOG(log,
"Evaluate_DW_OP_entry_value: no unambiguous edge from parent "
682 "to current function");
690 const void *subexpr_data = opcodes.
GetData(&opcode_offset, subexpr_len);
692 LLDB_LOG(log,
"Evaluate_DW_OP_entry_value: subexpr could not be read");
699 if (!param.LocationInCallee.GetExpressionData(param_subexpr_extractor))
702 const void *param_subexpr_data =
703 param_subexpr_extractor.
GetData(¶m_subexpr_offset, subexpr_len);
704 if (!param_subexpr_data ||
705 param_subexpr_extractor.
BytesLeft(param_subexpr_offset) != 0)
715 if (memcmp(subexpr_data, param_subexpr_data, subexpr_len) == 0) {
716 matched_param = ¶m;
720 if (!matched_param) {
722 "Evaluate_DW_OP_entry_value: no matching call site param found");
730 if (!param_expr.
Evaluate(&parent_exe_ctx,
734 nullptr, result, error_ptr)) {
736 "Evaluate_DW_OP_entry_value: call site param evaluation failed");
740 stack.push_back(result);
748enum LocationDescriptionKind {
756void UpdateValueTypeFromLocationDescription(
Log *log,
const DWARFUnit *dwarf_cu,
757 LocationDescriptionKind kind,
758 Value *value =
nullptr) {
765 if (dwarf_cu && dwarf_cu->
GetVersion() >= 4) {
766 const char *log_msg =
"DWARF location description kind: %s";
806static std::optional<lldb::addr_t>
808 Status *error_ptr,
const char *dw_op_type,
810 bool check_sectionoffset =
false) {
814 "need module to resolve file address for %s", dw_op_type);
818 if (!module_sp->ResolveFileAddress(file_addr, so_addr)) {
820 error_ptr->
SetErrorString(
"failed to resolve file address in module");
845 size_t size_addr_bytes,
847 DataExtractor addr_data(addr_bytes, size_addr_bytes, byte_order, size);
851 return addr_data.
GetMaxU64(&addr_data_offset, size);
853 return addr_data.
GetAddress(&addr_data_offset);
860 const Value *initial_value_ptr,
const Value *object_address_ptr,
866 "no location, value may have been optimized out");
869 std::vector<Value> stack;
880 if (reg_ctx ==
nullptr && frame)
883 if (initial_value_ptr)
884 stack.push_back(*initial_value_ptr);
891 uint64_t op_piece_offset = 0;
899 auto to_generic = [&](
auto v) {
900 bool is_signed = std::is_signed<
decltype(v)>::value;
901 return Scalar(llvm::APSInt(
909 LocationDescriptionKind dwarf4_location_description_kind =
Memory;
913 const uint8_t op = opcodes.
GetU8(&offset);
916 size_t count = stack.size();
917 LLDB_LOGF(log,
"Stack before operation has %" PRIu64
" values:",
919 for (
size_t i = 0; i < count; ++i) {
921 new_value.
Printf(
"[%" PRIu64
"]", (uint64_t)i);
922 stack[i].Dump(&new_value);
925 LLDB_LOGF(log,
"0x%8.8" PRIx64
": %s", op_offset,
990 error_ptr->
SetErrorString(
"Expression stack empty for DW_OP_deref.");
994 switch (value_type) {
996 void *src = (
void *)stack.back().GetScalar().ULongLong();
998 ::memcpy(&ptr, src,
sizeof(
void *));
999 stack.back().GetScalar() = ptr;
1000 stack.back().ClearContext();
1003 auto file_addr = stack.back().GetScalar().ULongLong(
1008 exe_ctx, module_sp, error_ptr,
"DW_OP_deref", file_addr, so_addr);
1010 if (!maybe_load_addr)
1013 stack.back().GetScalar() = *maybe_load_addr;
1030 if (ABISP abi_sp = process->
GetABI())
1031 pointer_value = abi_sp->FixCodeAddress(pointer_value);
1032 stack.back().GetScalar() = pointer_value;
1033 stack.back().ClearContext();
1037 "Failed to dereference pointer from 0x%" PRIx64
1038 " for DW_OP_deref: %s\n",
1039 pointer_addr,
error.AsCString());
1050 "NULL execution context for DW_OP_deref.\n");
1057 error_ptr->
SetErrorString(
"Invalid value type for DW_OP_deref.\n");
1075 case DW_OP_deref_size: {
1076 if (stack.empty()) {
1079 "Expression stack empty for DW_OP_deref_size.");
1082 uint8_t size = opcodes.
GetU8(&offset);
1084 switch (value_type) {
1086 void *src = (
void *)stack.back().GetScalar().ULongLong();
1088 ::memcpy(&ptr, src,
sizeof(
void *));
1101 ptr = ptr & 0xffffff;
1104 ptr = ptr & 0xffffffff;
1111 ptr = (intptr_t)ptr & 0xffffffffffULL;
1114 ptr = (intptr_t)ptr & 0xffffffffffffULL;
1117 ptr = (intptr_t)ptr & 0xffffffffffffffULL;
1122 stack.back().GetScalar() = ptr;
1123 stack.back().ClearContext();
1129 auto maybe_load_addr =
1131 "DW_OP_deref_size", file_addr, so_addr,
1134 if (!maybe_load_addr)
1137 addr_t load_addr = *maybe_load_addr;
1140 uint8_t addr_bytes[8];
1146 ObjectFile *objfile = module_sp->GetObjectFile();
1150 stack.back().ClearContext();
1155 "Failed to dereference pointer for for DW_OP_deref_size: "
1161 stack.back().GetScalar() = load_addr;
1177 stack.back().GetScalar() =
1180 stack.back().ClearContext();
1184 "Failed to dereference pointer from 0x%" PRIx64
1185 " for DW_OP_deref: %s\n",
1186 pointer_addr,
error.AsCString());
1191 error_ptr->
SetErrorString(
"NULL process for DW_OP_deref_size.\n");
1197 "NULL execution context for DW_OP_deref_size.\n");
1204 error_ptr->
SetErrorString(
"Invalid value for DW_OP_deref_size.\n");
1225 case DW_OP_xderef_size:
1227 error_ptr->
SetErrorString(
"Unimplemented opcode: DW_OP_xderef_size.");
1241 error_ptr->
SetErrorString(
"Unimplemented opcode: DW_OP_xderef.");
1258 stack.push_back(to_generic(opcodes.
GetU8(&offset)));
1261 stack.push_back(to_generic((int8_t)opcodes.
GetU8(&offset)));
1264 stack.push_back(to_generic(opcodes.
GetU16(&offset)));
1267 stack.push_back(to_generic((int16_t)opcodes.
GetU16(&offset)));
1270 stack.push_back(to_generic(opcodes.
GetU32(&offset)));
1273 stack.push_back(to_generic((int32_t)opcodes.
GetU32(&offset)));
1276 stack.push_back(to_generic(opcodes.
GetU64(&offset)));
1279 stack.push_back(to_generic((int64_t)opcodes.
GetU64(&offset)));
1294 if (stack.empty()) {
1296 error_ptr->
SetErrorString(
"Expression stack empty for DW_OP_dup.");
1299 stack.push_back(stack.back());
1306 if (stack.empty()) {
1308 error_ptr->
SetErrorString(
"Expression stack empty for DW_OP_drop.");
1319 if (stack.size() < 2) {
1322 "Expression stack needs at least 2 items for DW_OP_over.");
1325 stack.push_back(stack[stack.size() - 2]);
1333 uint8_t pick_idx = opcodes.
GetU8(&offset);
1334 if (pick_idx < stack.size())
1335 stack.push_back(stack[stack.size() - 1 - pick_idx]);
1339 "Index %u out of range for DW_OP_pick.\n", pick_idx);
1350 if (stack.size() < 2) {
1353 "Expression stack needs at least 2 items for DW_OP_swap.");
1357 stack.back() = stack[stack.size() - 2];
1358 stack[stack.size() - 2] = tmp;
1369 if (stack.size() < 3) {
1372 "Expression stack needs at least 3 items for DW_OP_rot.");
1375 size_t last_idx = stack.size() - 1;
1376 Value old_top = stack[last_idx];
1377 stack[last_idx] = stack[last_idx - 1];
1378 stack[last_idx - 1] = stack[last_idx - 2];
1379 stack[last_idx - 2] = old_top;
1389 if (stack.empty()) {
1392 "Expression stack needs at least 1 item for DW_OP_abs.");
1394 }
else if (!stack.back().ResolveValue(exe_ctx).AbsoluteValue()) {
1397 "Failed to take the absolute value of the first stack item.");
1407 if (stack.size() < 2) {
1410 "Expression stack needs at least 2 items for DW_OP_and.");
1416 stack.back().ResolveValue(exe_ctx) & tmp.
ResolveValue(exe_ctx);
1426 if (stack.size() < 2) {
1429 "Expression stack needs at least 2 items for DW_OP_div.");
1440 stack.back().ResolveValue(exe_ctx) / tmp.
ResolveValue(exe_ctx);
1441 if (!stack.back().ResolveValue(exe_ctx).IsValid()) {
1455 if (stack.size() < 2) {
1458 "Expression stack needs at least 2 items for DW_OP_minus.");
1464 stack.back().ResolveValue(exe_ctx) - tmp.
ResolveValue(exe_ctx);
1474 if (stack.size() < 2) {
1477 "Expression stack needs at least 2 items for DW_OP_mod.");
1483 stack.back().ResolveValue(exe_ctx) % tmp.
ResolveValue(exe_ctx);
1492 if (stack.size() < 2) {
1495 "Expression stack needs at least 2 items for DW_OP_mul.");
1501 stack.back().ResolveValue(exe_ctx) * tmp.
ResolveValue(exe_ctx);
1509 if (stack.empty()) {
1512 "Expression stack needs at least 1 item for DW_OP_neg.");
1515 if (!stack.back().ResolveValue(exe_ctx).UnaryNegate()) {
1528 if (stack.empty()) {
1531 "Expression stack needs at least 1 item for DW_OP_not.");
1534 if (!stack.back().ResolveValue(exe_ctx).OnesComplement()) {
1547 if (stack.size() < 2) {
1550 "Expression stack needs at least 2 items for DW_OP_or.");
1556 stack.back().ResolveValue(exe_ctx) | tmp.
ResolveValue(exe_ctx);
1565 if (stack.size() < 2) {
1568 "Expression stack needs at least 2 items for DW_OP_plus.");
1581 case DW_OP_plus_uconst:
1582 if (stack.empty()) {
1585 "Expression stack needs at least 1 item for DW_OP_plus_uconst.");
1588 const uint64_t uconst_value = opcodes.
GetULEB128(&offset);
1590 stack.back().GetScalar() += uconst_value;
1591 if (!stack.back().GetScalar().IsValid()) {
1605 if (stack.size() < 2) {
1608 "Expression stack needs at least 2 items for DW_OP_shl.");
1623 if (stack.size() < 2) {
1626 "Expression stack needs at least 2 items for DW_OP_shr.");
1631 if (!stack.back().ResolveValue(exe_ctx).ShiftRightLogical(
1647 if (stack.size() < 2) {
1650 "Expression stack needs at least 2 items for DW_OP_shra.");
1664 if (stack.size() < 2) {
1667 "Expression stack needs at least 2 items for DW_OP_xor.");
1673 stack.back().ResolveValue(exe_ctx) ^ tmp.
ResolveValue(exe_ctx);
1684 int16_t skip_offset = (int16_t)opcodes.
GetU16(&offset);
1690 offset = new_offset;
1694 "Invalid opcode offset in DW_OP_skip: {0}+({1}) > {2}", offset,
1708 if (stack.empty()) {
1711 "Expression stack needs at least 1 item for DW_OP_bra.");
1716 int16_t bra_offset = (int16_t)opcodes.
GetU16(&offset);
1724 offset = new_offset;
1728 "Invalid opcode offset in DW_OP_bra: {0}+({1}) > {2}", offset,
1744 if (stack.size() < 2) {
1747 "Expression stack needs at least 2 items for DW_OP_eq.");
1753 stack.back().ResolveValue(exe_ctx) == tmp.
ResolveValue(exe_ctx);
1765 if (stack.size() < 2) {
1768 "Expression stack needs at least 2 items for DW_OP_ge.");
1774 stack.back().ResolveValue(exe_ctx) >= tmp.
ResolveValue(exe_ctx);
1786 if (stack.size() < 2) {
1789 "Expression stack needs at least 2 items for DW_OP_gt.");
1795 stack.back().ResolveValue(exe_ctx) > tmp.
ResolveValue(exe_ctx);
1807 if (stack.size() < 2) {
1810 "Expression stack needs at least 2 items for DW_OP_le.");
1816 stack.back().ResolveValue(exe_ctx) <= tmp.
ResolveValue(exe_ctx);
1828 if (stack.size() < 2) {
1831 "Expression stack needs at least 2 items for DW_OP_lt.");
1837 stack.back().ResolveValue(exe_ctx) < tmp.
ResolveValue(exe_ctx);
1849 if (stack.size() < 2) {
1852 "Expression stack needs at least 2 items for DW_OP_ne.");
1858 stack.back().ResolveValue(exe_ctx) != tmp.
ResolveValue(exe_ctx);
1899 stack.push_back(to_generic(op - DW_OP_lit0));
1937 dwarf4_location_description_kind = Register;
1938 reg_num = op - DW_OP_reg0;
1941 stack.push_back(tmp);
1950 dwarf4_location_description_kind = Register;
1953 stack.push_back(tmp);
1994 case DW_OP_breg31: {
1995 reg_num = op - DW_OP_breg0;
1999 int64_t breg_offset = opcodes.
GetSLEB128(&offset);
2002 stack.push_back(tmp);
2018 int64_t breg_offset = opcodes.
GetSLEB128(&offset);
2021 stack.push_back(tmp);
2032 int64_t fbreg_offset = opcodes.
GetSLEB128(&offset);
2033 value += fbreg_offset;
2034 stack.push_back(value);
2041 "Invalid stack frame in context for DW_OP_fbreg opcode.");
2047 "NULL execution context for DW_OP_fbreg.\n");
2074 LocationDescriptionKind piece_locdesc = dwarf4_location_description_kind;
2076 dwarf4_location_description_kind =
Memory;
2078 const uint64_t piece_byte_size = opcodes.
GetULEB128(&offset);
2080 if (piece_byte_size > 0) {
2083 if (stack.empty()) {
2084 UpdateValueTypeFromLocationDescription(
2085 log, dwarf_cu, LocationDescriptionKind::Empty);
2094 ::memset(curr_piece.
GetBuffer().GetBytes(), 0, piece_byte_size);
2099 Value curr_piece_source_value(stack.back());
2101 UpdateValueTypeFromLocationDescription(log, dwarf_cu, piece_locdesc,
2102 &curr_piece_source_value);
2106 switch (curr_piece_source_value_type) {
2111 if (curr_piece.
ResizeData(piece_byte_size) == piece_byte_size) {
2116 load_addr, curr_piece.
GetBuffer().GetBytes(),
2117 piece_byte_size,
error) != piece_byte_size) {
2120 "failed to read memory DW_OP_piece(%" PRIu64
2121 ") from 0x%" PRIx64,
2122 piece_byte_size, load_addr);
2128 "failed to resize the piece memory buffer for "
2129 "DW_OP_piece(%" PRIu64
")",
2142 "failed to read memory DW_OP_piece(%" PRIu64
2143 ") from %s address 0x%" PRIx64,
2144 piece_byte_size, curr_piece_source_value.
GetValueType() ==
2153 uint32_t bit_size = piece_byte_size * 8;
2157 bit_size, bit_offset)) {
2160 "unable to extract %" PRIu64
" bytes from a %" PRIu64
2161 " byte scalar value.",
2163 (uint64_t)curr_piece_source_value.
GetScalar()
2169 llvm::APInt fail_value(1, 0,
false);
2170 llvm::APInt ap_int = scalar.
UInt128(fail_value);
2171 assert(ap_int.getBitWidth() >= bit_size);
2172 llvm::ArrayRef<uint64_t> buf{ap_int.getRawData(),
2173 ap_int.getNumWords()};
2179 if (op_piece_offset == 0) {
2194 "DW_OP_piece for offset %" PRIu64
2195 " but top of stack is of size %" PRIu64,
2207 op_piece_offset += piece_byte_size;
2211 case DW_OP_bit_piece:
2212 if (stack.size() < 1) {
2213 UpdateValueTypeFromLocationDescription(log, dwarf_cu,
2214 LocationDescriptionKind::Empty);
2216 dwarf4_location_description_kind =
Memory;
2219 "Expression stack needs at least 1 item for DW_OP_bit_piece.");
2222 UpdateValueTypeFromLocationDescription(
2223 log, dwarf_cu, dwarf4_location_description_kind, &stack.back());
2225 dwarf4_location_description_kind =
Memory;
2226 const uint64_t piece_bit_size = opcodes.
GetULEB128(&offset);
2227 const uint64_t piece_bit_offset = opcodes.
GetULEB128(&offset);
2228 switch (stack.back().GetValueType()) {
2232 if (!stack.back().GetScalar().ExtractBitfield(piece_bit_size,
2233 piece_bit_offset)) {
2236 "unable to extract %" PRIu64
" bit value with %" PRIu64
2237 " bit offset from a %" PRIu64
" bit scalar value.",
2238 piece_bit_size, piece_bit_offset,
2239 (uint64_t)(stack.back().GetScalar().GetByteSize() * 8));
2249 "unable to extract DW_OP_bit_piece(bit_size = %" PRIu64
2250 ", bit_offset = %" PRIu64
") from an address value.",
2251 piece_bit_size, piece_bit_offset);
2265 case DW_OP_implicit_value: {
2266 dwarf4_location_description_kind = Implicit;
2269 const void *data = opcodes.
GetData(&offset, len);
2272 LLDB_LOG(log,
"Evaluate_DW_OP_implicit_value: could not be read data");
2278 Value result(data, len);
2279 stack.push_back(result);
2283 case DW_OP_implicit_pointer: {
2284 dwarf4_location_description_kind = Implicit;
2297 case DW_OP_push_object_address:
2298 if (object_address_ptr)
2299 stack.push_back(*object_address_ptr);
2302 error_ptr->
SetErrorString(
"DW_OP_push_object_address used without "
2303 "specifying an object address");
2359 case DW_OP_stack_value:
2360 dwarf4_location_description_kind = Implicit;
2361 if (stack.empty()) {
2364 "Expression stack needs at least 1 item for DW_OP_stack_value.");
2377 case DW_OP_convert: {
2378 if (stack.size() < 1) {
2381 "Expression stack needs at least 1 item for DW_OP_convert.");
2384 const uint64_t die_offset = opcodes.
GetULEB128(&offset);
2387 if (die_offset == 0) {
2397 bit_size = module_sp->GetArchitecture().GetAddressByteSize() * 8;
2406 const uint64_t abs_die_offset = die_offset + dwarf_cu->
GetOffset();
2411 error_ptr->
SetErrorString(
"Cannot resolve DW_OP_convert type DIE");
2421 error_ptr->
SetErrorString(
"Unsupported type size in DW_OP_convert");
2426 case DW_ATE_signed_char:
2429 case DW_ATE_unsigned:
2430 case DW_ATE_unsigned_char:
2435 error_ptr->
SetErrorString(
"Unsupported encoding in DW_OP_convert");
2439 Scalar &top = stack.back().ResolveValue(exe_ctx);
2449 case DW_OP_call_frame_cfa:
2456 stack.push_back(
Scalar(cfa));
2458 }
else if (error_ptr)
2459 error_ptr->
SetErrorString(
"Stack frame does not include a canonical "
2460 "frame address for DW_OP_call_frame_cfa "
2465 "DW_OP_call_frame_cfa opcode.");
2476 case DW_OP_form_tls_address:
2477 case DW_OP_GNU_push_tls_address: {
2478 if (stack.size() < 1) {
2480 if (op == DW_OP_form_tls_address)
2482 "DW_OP_form_tls_address needs an argument.");
2485 "DW_OP_GNU_push_tls_address needs an argument.");
2490 if (!exe_ctx || !module_sp) {
2504 const addr_t tls_file_addr =
2506 const addr_t tls_load_addr =
2512 "No TLS data currently exists for this thread.");
2516 stack.back().GetScalar() = tls_load_addr;
2527 case DW_OP_GNU_addr_index: {
2530 error_ptr->
SetErrorString(
"DW_OP_GNU_addr_index found without a "
2531 "compile unit being specified");
2534 uint64_t index = opcodes.
GetULEB128(&offset);
2536 stack.push_back(
Scalar(value));
2554 case DW_OP_GNU_const_index: {
2557 error_ptr->
SetErrorString(
"DW_OP_GNU_const_index found without a "
2558 "compile unit being specified");
2561 uint64_t index = opcodes.
GetULEB128(&offset);
2563 stack.push_back(
Scalar(value));
2566 case DW_OP_GNU_entry_value:
2567 case DW_OP_entry_value: {
2580 op, opcodes, offset, stack)) {
2586 "Unhandled opcode {0} in DWARFExpression", LocationAtom(op));
2591 if (stack.empty()) {
2603 UpdateValueTypeFromLocationDescription(
2604 log, dwarf_cu, dwarf4_location_description_kind, &stack.back());
2607 size_t count = stack.size();
2609 "Stack after operation has %" PRIu64
" values:", (uint64_t)count);
2610 for (
size_t i = 0; i < count; ++i) {
2612 new_value.
Printf(
"[%" PRIu64
"]", (uint64_t)i);
2613 stack[i].Dump(&new_value);
2617 result = stack.back();
2624 location_list->
Clear();
2625 std::unique_ptr<llvm::DWARFLocationTable> loctable_up =
2629 [&](
uint32_t index) -> std::optional<llvm::object::SectionedAddress> {
2632 return std::nullopt;
2633 return llvm::object::SectionedAddress{address};
2635 auto process_list = [&](llvm::Expected<llvm::DWARFLocationExpression> loc) {
2641 std::make_shared<DataBufferHeap>(loc->Expr.data(), loc->Expr.size());
2644 location_list->
AddExpression(loc->Range->LowPC, loc->Range->HighPC, expr);
2647 llvm::Error
error = loctable_up->visitAbsoluteLocationList(
2649 lookup_addr, process_list);
2650 location_list->
Sort();
2660 using namespace OperandMatchers;
2670 uint8_t opcode = opcodes.
GetU8(&op_offset);
2672 if (opcode == DW_OP_fbreg) {
2673 int64_t offset = opcodes.
GetSLEB128(&op_offset);
2686 recurse)(operand)) {
2690 return MatchUnaryOp(
2693 MatchImmOp(offset), recurse))(operand);
2696 bool dereference =
false;
2697 const RegisterInfo *reg =
nullptr;
2700 if (opcode >= DW_OP_reg0 && opcode <= DW_OP_reg31) {
2701 reg = reg_ctx_sp->GetRegisterInfo(
m_reg_kind, opcode - DW_OP_reg0);
2702 }
else if (opcode >= DW_OP_breg0 && opcode <= DW_OP_breg31) {
2704 reg = reg_ctx_sp->GetRegisterInfo(
m_reg_kind, opcode - DW_OP_breg0);
2705 }
else if (opcode == DW_OP_regx) {
2707 reg = reg_ctx_sp->GetRegisterInfo(
m_reg_kind, reg_num);
2708 }
else if (opcode == DW_OP_bregx) {
2711 reg = reg_ctx_sp->GetRegisterInfo(
m_reg_kind, reg_num);
2723 MatchRegOp(*reg))(operand)) {
2727 return MatchUnaryOp(
2731 MatchImmOp(offset)))(operand);
2733 return MatchRegOp(*reg)(operand);
static llvm::raw_ostream & error(Stream &strm)
static offset_t GetOpcodeDataSize(const DataExtractor &data, const lldb::offset_t data_offset, const uint8_t op, const DWARFUnit *dwarf_cu)
Return the length in bytes of the set of operands for op.
static bool ReadRegisterValueAsScalar(RegisterContext *reg_ctx, lldb::RegisterKind reg_kind, uint32_t reg_num, Status *error_ptr, Value &value)
static bool Evaluate_DW_OP_entry_value(std::vector< Value > &stack, ExecutionContext *exe_ctx, RegisterContext *reg_ctx, const DataExtractor &opcodes, lldb::offset_t &opcode_offset, Status *error_ptr, Log *log)
static Scalar DerefSizeExtractDataHelper(uint8_t *addr_bytes, size_t size_addr_bytes, ByteOrder byte_order, size_t size)
Helper function to move common code used to load sized data from a uint8_t buffer.
static std::optional< lldb::addr_t > ResolveLoadAddress(ExecutionContext *exe_ctx, lldb::ModuleSP &module_sp, Status *error_ptr, const char *dw_op_type, lldb::addr_t file_addr, Address &so_addr, bool check_sectionoffset=false)
Helper function to move common code used to resolve a file address and turn into a load address.
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
#define LLDB_LOG_ERROR(log, error,...)
@ Empty
If the Mangled object has neither a mangled name or demangled name we can encode the object with one ...
#define LLDB_ERRORF(status, fmt,...)
uint64_t GetAttributeValueAsUnsigned(const dw_attr_t attr, uint64_t fail_value) const
SymbolFileDWARF & GetSymbolFileDWARF() const
dw_addr_t ReadAddressFromDebugAddrSection(uint32_t index) const
uint16_t GetVersion() const
std::unique_ptr< llvm::DWARFLocationTable > GetLocationTable(const lldb_private::DataExtractor &data) const
Return the location table for parsing the given location list data.
dw_addr_t GetBaseAddress() const
dw_offset_t GetOffset() const
virtual lldb::offset_t GetVendorDWARFOpcodeSize(const lldb_private::DataExtractor &data, const lldb::offset_t data_offset, const uint8_t op) const
virtual bool ParseVendorDWARFOpcode(uint8_t op, const lldb_private::DataExtractor &opcodes, lldb::offset_t &offset, std::vector< lldb_private::Value > &stack) const
llvm::MCRegisterInfo & GetMCRegisterInfo()
A section + offset based address class.
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
bool IsSectionOffset() const
Check if an address is section offset.
Represent a call made within a Function.
virtual Function * GetCallee(ModuleList &images, ExecutionContext &exe_ctx)=0
Get the callee's definition.
llvm::ArrayRef< CallSiteParameter > GetCallSiteParameters() const
Get the call site parameters available at this call edge.
"lldb/Expression/DWARFExpressionList.h" Encapsulates a range map from file address range to a single ...
bool AddExpression(lldb::addr_t base, lldb::addr_t end, DWARFExpression expr)
bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx, lldb::addr_t func_load_addr, const Value *initial_value_ptr, const Value *object_address_ptr, Value &result, Status *error_ptr) const
bool MatchesOperand(StackFrame &frame, const Instruction::Operand &operand) const
void Sort()
Sort m_expressions.
"lldb/Expression/DWARFExpression.h" Encapsulates a DWARF location expression and interprets it.
static bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx, lldb::ModuleSP module_sp, const DataExtractor &opcodes, const DWARFUnit *dwarf_cu, const lldb::RegisterKind reg_set, const Value *initial_value_ptr, const Value *object_address_ptr, Value &result, Status *error_ptr)
Evaluate a DWARF location expression in a particular context.
DataExtractor m_data
A data extractor capable of reading opcode bytes.
virtual ~DWARFExpression()
Destructor.
void DumpLocation(Stream *s, lldb::DescriptionLevel level, ABI *abi) const
bool LinkThreadLocalStorage(const DWARFUnit *dwarf_cu, std::function< lldb::addr_t(lldb::addr_t file_addr)> const &link_address_callback)
lldb::addr_t GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu, uint32_t op_addr_idx, bool &error) const
If a location is not a location list, return true if the location contains a DW_OP_addr () opcode in ...
void UpdateValue(uint64_t const_value, lldb::offset_t const_value_byte_size, uint8_t addr_byte_size)
bool ContainsThreadLocalStorage(const DWARFUnit *dwarf_cu) const
lldb::RegisterKind m_reg_kind
One of the defines that starts with LLDB_REGKIND_.
bool Update_DW_OP_addr(const DWARFUnit *dwarf_cu, lldb::addr_t file_addr)
void SetRegisterKind(lldb::RegisterKind reg_kind)
Set the call-frame-info style register kind.
bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op) const
lldb::RegisterKind GetRegisterKind() const
Return the call-frame-info style register kind.
static bool ParseDWARFLocationList(const DWARFUnit *dwarf_cu, const DataExtractor &data, DWARFExpressionList *loc_list)
bool IsValid() const
Return true if the location expression contains data.
A subclass of DataBuffer that stores a data buffer on the heap.
lldb::offset_t GetByteSize() const override
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
void SetFrameSP(const lldb::StackFrameSP &frame_sp)
Set accessor to set only the frame shared pointer.
StackFrame * GetFramePtr() const
Returns a pointer to the frame object.
Target * GetTargetPtr() const
Returns a pointer to the target object.
bool HasTargetScope() const
Returns true the ExecutionContext object contains a valid target.
Target & GetTargetRef() const
Returns a reference to the target object.
Process * GetProcessPtr() const
Returns a pointer to the process object.
RegisterContext * GetRegisterContext() const
Thread * GetThreadPtr() const
Returns a pointer to the thread object.
A class that describes a function.
ConstString GetName() const
CallEdge * GetCallEdgeForReturnAddress(lldb::addr_t return_pc, Target &target)
Get the outgoing call edge from this function which has the given return address return_pc,...
llvm::ArrayRef< std::unique_ptr< CallEdge > > GetTailCallingEdges()
Get the outgoing tail-calling edges from this function.
A collection class for Module objects.
A plug-in interface definition class for object file parsers.
virtual lldb::ByteOrder GetByteOrder() const =0
Gets whether endian swapping should occur when extracting data from this object file.
A plug-in interface definition class for debugging a process.
virtual size_t ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, Status &error)
Read of memory from a process.
lldb::ByteOrder GetByteOrder() const
lldb::addr_t ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error)
const lldb::ABISP & GetABI()
virtual uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num)
Convert from a given register numbering scheme to the lldb register numbering scheme.
virtual const RegisterInfo * GetRegisterInfoAtIndex(size_t reg)=0
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue ®_value)=0
bool GetScalarValue(Scalar &scalar) const
size_t GetByteSize() const
void TruncOrExtendTo(uint16_t bits, bool sign)
Convert to an integer with bits and the given signedness.
unsigned long long ULongLong(unsigned long long fail_value=0) const
bool ExtractBitfield(uint32_t bit_size, uint32_t bit_offset)
llvm::APInt UInt128(const llvm::APInt &fail_value) const
This base class provides an interface to stack frames.
DWARFExpressionList * GetFrameBaseExpression(Status *error_ptr)
Get the DWARFExpressionList corresponding to the Canonical Frame Address.
lldb::RegisterContextSP GetRegisterContext()
Get the RegisterContext for this frame, if possible.
const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
uint32_t GetFrameIndex() const
Query this frame to find what frame it is in this Thread's StackFrameList.
bool GetFrameBaseValue(Scalar &value, Status *error_ptr)
Return the Canonical Frame Address (DWARF term) for this frame.
lldb::addr_t GetCallFrameAddress() const
void SetErrorStringWithFormatv(const char *format, Args &&... args)
void Clear()
Clear the object state.
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
const char * GetData() const
A stream class that can stream formatted output to a file.
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Function * function
The Function for a given query.
size_t ReadMemory(const Address &addr, void *dst, size_t dst_len, Status &error, bool force_live_memory=false, lldb::addr_t *load_addr_ptr=nullptr)
const ModuleList & GetImages() const
Get accessor for the images for this process.
const ArchSpec & GetArchitecture() const
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
virtual lldb::addr_t GetThreadLocalData(const lldb::ModuleSP module, lldb::addr_t tls_file_addr)
Retrieves the per-module TLS block for a thread.
virtual uint32_t GetStackFrameCount()
const Scalar & GetScalar() const
ValueType
Type that describes Value::m_value.
@ HostAddress
A host address value (for memory in the process that < A is using liblldb).
@ FileAddress
A file address value.
@ LoadAddress
A load address value.
@ Scalar
A raw scalar value.
size_t AppendDataToHostBuffer(const Value &rhs)
ValueType GetValueType() const
void SetContext(ContextType context_type, void *p)
DataBufferHeap & GetBuffer()
Scalar & ResolveValue(ExecutionContext *exe_ctx)
void SetValueType(ValueType value_type)
@ RegisterInfo
RegisterInfo * (can be a scalar or a vector register).
size_t ResizeData(size_t len)
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_OFFSET
#define LLDB_INVALID_REGNUM
lldb::ByteOrder InlHostByteOrder()
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
const char * DW_OP_value_to_name(uint32_t val)
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
ByteOrder
Byte ordering definitions.
RegisterKind
Register numbering types.
Represent the locations of a parameter at a call site, both in the caller and in the callee.
DWARFExpressionList LocationInCaller