================
@@ -861,84 +861,159 @@ ResolveLoadAddress(ExecutionContext *exe_ctx,
lldb::ModuleSP &module_sp,
return load_addr;
}
-static llvm::Error Evaluate_DW_OP_deref(DWARFExpression::Stack &stack,
- ExecutionContext *exe_ctx,
- lldb::ModuleSP module_sp,
- Process *process) {
- if (stack.empty())
- return llvm::createStringError("expression stack empty for DW_OP_deref");
-
- const Value::ValueType value_type = stack.back().GetValueType();
+/// Helper function to move common code used to load sized data from a uint8_t
+/// buffer.
+///
+/// \param addr_bytes uint8_t buffer containg raw data
+/// \param size_addr_bytes how large is the underlying raw data
+/// \param byte_order what is the byter order of the underlyig data
+/// \param size How much of the underlying data we want to use
+/// \return The underlying data converted into a Scalar
+static Scalar DerefSizeExtractDataHelper(uint8_t *addr_bytes,
+ size_t size_addr_bytes,
+ ByteOrder byte_order, size_t size) {
+ DataExtractor addr_data(addr_bytes, size_addr_bytes, byte_order, size);
+
+ lldb::offset_t addr_data_offset = 0;
+ if (size <= 8)
+ return addr_data.GetMaxU64(&addr_data_offset, size);
+ else
+ return addr_data.GetAddress(&addr_data_offset);
+}
+
+static llvm::Error Evaluate_DW_OP_deref_size(DWARFExpression::Stack &stack,
+ ExecutionContext *exe_ctx,
+ lldb::ModuleSP module_sp,
+ Process *process, Target *target,
+ uint8_t size) {
+ if (stack.empty()) {
+ return llvm::createStringError(
+ "expression stack empty for DW_OP_deref_size");
+ }
+
+ if (size > 8) {
+ return llvm::createStringError(
+ "Invalid address size for DW_OP_deref_size: %d\n", size);
+ }
+ Value::ValueType value_type = stack.back().GetValueType();
switch (value_type) {
case Value::ValueType::HostAddress: {
void *src = (void *)stack.back().GetScalar().ULongLong();
intptr_t ptr;
::memcpy(&ptr, src, sizeof(void *));
+ // I can't decide whether the size operand should apply to the bytes in
+ // their
+ // lldb-host endianness or the target endianness.. I doubt this'll ever
+ // come up but I'll opt for assuming big endian regardless.
+ switch (size) {
+ case 1:
+ ptr = ptr & 0xff;
+ break;
+ case 2:
+ ptr = ptr & 0xffff;
+ break;
+ case 3:
+ ptr = ptr & 0xffffff;
+ break;
+ case 4:
+ ptr = ptr & 0xffffffff;
+ break;
+ // the casts are added to work around the case where intptr_t is a 32
+ // bit quantity;
+ // presumably we won't hit the 5..7 cases if (void*) is 32-bits in this
+ // program.
+ case 5:
+ ptr = (intptr_t)ptr & 0xffffffffffULL;
+ break;
+ case 6:
+ ptr = (intptr_t)ptr & 0xffffffffffffULL;
+ break;
+ case 7:
+ ptr = (intptr_t)ptr & 0xffffffffffffffULL;
+ break;
+ default:
+ break;
+ }
stack.back().GetScalar() = ptr;
stack.back().ClearContext();
} break;
case Value::ValueType::FileAddress: {
auto file_addr = stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
Address so_addr;
- auto maybe_load_addr = ResolveLoadAddress(exe_ctx, module_sp,
"DW_OP_deref",
- file_addr, so_addr);
+ auto maybe_load_addr = ResolveLoadAddress(
+ exe_ctx, module_sp, "DW_OP_deref_size", file_addr, so_addr,
+ /*check_sectionoffset=*/true);
+
if (!maybe_load_addr)
return maybe_load_addr.takeError();
- stack.back().GetScalar() = *maybe_load_addr;
+
+ addr_t load_addr = *maybe_load_addr;
+
+ if (load_addr == LLDB_INVALID_ADDRESS && so_addr.IsSectionOffset()) {
+ uint8_t addr_bytes[8];
+ Status error;
+
+ if (target && target->ReadMemory(so_addr, &addr_bytes, size, error,
+ /*force_live_memory=*/false) == size) {
+ ObjectFile *objfile = module_sp->GetObjectFile();
+
+ stack.back().GetScalar() = DerefSizeExtractDataHelper(
+ addr_bytes, size, objfile->GetByteOrder(), size);
+ stack.back().ClearContext();
+ break;
+ } else {
+ return llvm::createStringError(
+ "Failed to dereference pointer for DW_OP_deref_size: "
+ "%s\n",
+ error.AsCString());
----------------
JDevlieghere wrote:
Let's invert the condition and do an early return to save the indentation.
While you're at it, errors shouldn't start with a capital letter.
https://github.com/llvm/llvm-project/pull/169587
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits