diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp --- a/lldb/source/Expression/DWARFExpression.cpp +++ b/lldb/source/Expression/DWARFExpression.cpp @@ -408,13 +408,33 @@ // the heap data so "m_data" will now correctly manage the heap data. m_data.SetData(encoder.GetDataBuffer()); return true; - } else { - const offset_t op_arg_size = - GetOpcodeDataSize(m_data, offset, op, dwarf_cu); - if (op_arg_size == LLDB_INVALID_OFFSET) - break; - offset += op_arg_size; } + if (op == DW_OP_addrx) { + // Replace DW_OP_addrx with DW_OP_addr, since we can't modify the + // read-only debug_addr table. + // Subtract one to account for the opcode. + llvm::ArrayRef data_before_op = m_data.GetData().take_front(offset - 1); + + // Read the addrx index to determine how many bytes it needs. + const lldb::offset_t old_offset = offset; + m_data.GetULEB128(&offset); + if (old_offset == offset) + return false; + llvm::ArrayRef data_after_op = m_data.GetData().drop_front(offset); + + DataEncoder encoder(m_data.GetByteOrder(), m_data.GetAddressByteSize()); + encoder.AppendData(data_before_op); + encoder.AppendU8(DW_OP_addr); + encoder.AppendAddress(file_addr); + encoder.AppendData(data_after_op); + m_data.SetData(encoder.GetDataBuffer()); + return true; + } + const offset_t op_arg_size = + GetOpcodeDataSize(m_data, offset, op, dwarf_cu); + if (op_arg_size == LLDB_INVALID_OFFSET) + break; + offset += op_arg_size; } return false; } diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp b/lldb/unittests/Expression/DWARFExpressionTest.cpp --- a/lldb/unittests/Expression/DWARFExpressionTest.cpp +++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp @@ -522,6 +522,11 @@ ASSERT_TRUE(evaluate(expr, status, result)) << status.ToError(); ASSERT_EQ(result.GetValueType(), Value::ValueType::LoadAddress); ASSERT_EQ(result.GetScalar().UInt(), 0x5678u); + + ASSERT_TRUE(expr.Update_DW_OP_addr(dwarf_cu, 0xdeadbeef)); + ASSERT_TRUE(evaluate(expr, status, result)) << status.ToError(); + ASSERT_EQ(result.GetValueType(), Value::ValueType::LoadAddress); + ASSERT_EQ(result.GetScalar().UInt(), 0xdeadbeefu); } class CustomSymbolFileDWARF : public SymbolFileDWARF {