Fix access to FP registers when visiting stack
Adds GetFPR and SetFPR to Context class so we can read from and write to
floating-point registers during stack visit. They return a boolean flag
indicating whether the read/write is successful. This allows the debugger to
return the JDWP error ABSENT_INFORMATION when we can't read/write a register.
We also update GetGPR and SetGPR for consistency. We keep a default GetGPR
implementation asserting the read was successful using a CHECK so we don't
silently fail.
Adds missing JDWP object tags for StackFrame.SetValues to avoid crash when
setting corresponding objects (thread, thread group, class object or class
loader). Also returns JDWP error INVALID_OBJECT (when the given object id is
invalid) instead of crashing with an unimplemented message.
Bug: 15433097
Change-Id: I70843c9280e694aec1eae5cf6f2dc155cb9ea10e
diff --git a/runtime/arch/x86/context_x86.cc b/runtime/arch/x86/context_x86.cc
index 8c98d91..37049cf 100644
--- a/runtime/arch/x86/context_x86.cc
+++ b/runtime/arch/x86/context_x86.cc
@@ -24,11 +24,11 @@
namespace art {
namespace x86 {
-static const uintptr_t gZero = 0;
+static constexpr uintptr_t gZero = 0;
void X86Context::Reset() {
for (size_t i = 0; i < kNumberOfCpuRegisters; i++) {
- gprs_[i] = NULL;
+ gprs_[i] = nullptr;
}
gprs_[ESP] = &esp_;
// Initialize registers with easy to spot debug values.
@@ -57,15 +57,19 @@
// This needs to be 0 because we want a null/zero return value.
gprs_[EAX] = const_cast<uintptr_t*>(&gZero);
gprs_[EDX] = const_cast<uintptr_t*>(&gZero);
- gprs_[ECX] = NULL;
- gprs_[EBX] = NULL;
+ gprs_[ECX] = nullptr;
+ gprs_[EBX] = nullptr;
}
-void X86Context::SetGPR(uint32_t reg, uintptr_t value) {
+bool X86Context::SetGPR(uint32_t reg, uintptr_t value) {
CHECK_LT(reg, static_cast<uint32_t>(kNumberOfCpuRegisters));
CHECK_NE(gprs_[reg], &gZero);
- CHECK(gprs_[reg] != NULL);
- *gprs_[reg] = value;
+ if (gprs_[reg] != nullptr) {
+ *gprs_[reg] = value;
+ return true;
+ } else {
+ return false;
+ }
}
void X86Context::DoLongJump() {
@@ -74,7 +78,7 @@
// the top for the stack pointer that doesn't get popped in a pop-all.
volatile uintptr_t gprs[kNumberOfCpuRegisters + 1];
for (size_t i = 0; i < kNumberOfCpuRegisters; ++i) {
- gprs[kNumberOfCpuRegisters - i - 1] = gprs_[i] != NULL ? *gprs_[i] : X86Context::kBadGprBase + i;
+ gprs[kNumberOfCpuRegisters - i - 1] = gprs_[i] != nullptr ? *gprs_[i] : X86Context::kBadGprBase + i;
}
// We want to load the stack pointer one slot below so that the ret will pop eip.
uintptr_t esp = gprs[kNumberOfCpuRegisters - ESP - 1] - kWordSize;