[snapshot][arm64] rename CPU context pstate to spsr

* upon exception, the process state ("pstate") is stored in the saved
process status register ("spsr") so the register we are manipulating is
really just the SPSR
* https://developer.arm.com/products/architecture/cpu-architecture/a-profile/docs/100878/latest/the-saved-process-status-register

Change-Id: I9ce612c00b7a56a0f6d778d974ff9e0e5402ca5e
Reviewed-on: https://chromium-review.googlesource.com/c/1312193
Reviewed-by: Joshua Peraza <jperaza@chromium.org>
Commit-Queue: Francois Rousseau <frousseau@google.com>
This commit is contained in:
Francois Rousseau 2018-11-01 10:41:15 -07:00 committed by Commit Bot
parent 8c0d3d2c1e
commit a4754a9ae9
10 changed files with 28 additions and 24 deletions

View File

@ -323,13 +323,6 @@ void MinidumpContextARM64Writer::InitializeFromSnapshot(
context_.context_flags = kMinidumpContextARM64Full;
if (context_snapshot->pstate >
std::numeric_limits<decltype(context_.cpsr)>::max()) {
LOG(WARNING) << "pstate truncation";
}
context_.cpsr =
static_cast<decltype(context_.cpsr)>(context_snapshot->pstate);
static_assert(
sizeof(context_.regs) == sizeof(context_snapshot->regs) -
2 * sizeof(context_snapshot->regs[0]),
@ -339,6 +332,7 @@ void MinidumpContextARM64Writer::InitializeFromSnapshot(
context_.lr = context_snapshot->regs[30];
context_.sp = context_snapshot->sp;
context_.pc = context_snapshot->pc;
context_.cpsr = context_snapshot->spsr;
static_assert(sizeof(context_.fpsimd) == sizeof(context_snapshot->fpsimd),
"FPSIMD size mismatch");

View File

@ -299,7 +299,7 @@ struct CPUContextARM64 {
uint64_t regs[31];
uint64_t sp;
uint64_t pc;
uint64_t pstate;
uint32_t spsr;
uint128_struct fpsimd[32];
uint32_t fpsr;

View File

@ -69,10 +69,17 @@ void InitializeCPUContextARM64_NoFloatingPoint(
// Only the NZCV flags (bits 31 to 28 respectively) of the cpsr register are
// readable and writable by userland on ARM64.
constexpr uint64_t kNZCV = 0xf0000000;
// Fuchsia uses the "cspr" terminology while Crashpad uses the "pstate"
// terminology. For the NZCV flags, the bit layout should be the same.
context->pstate = thread_context.cpsr & kNZCV;
constexpr uint32_t kNZCV = 0xf0000000;
// Fuchsia uses the old "cspr" terminology from armv7 while Crashpad uses the
// new "spsr" terminology for armv8.
context->spsr = thread_context.cpsr & kNZCV;
if (thread_context.cpsr >
std::numeric_limits<decltype(context->spsr)>::max()) {
LOG(WARNING) << "cpsr truncation: we only expect the first 32 bits to be "
"set in the cpsr";
}
context->spsr =
static_cast<decltype(context->spsr)>(thread_context.cpsr) & kNZCV;
}
#endif // ARCH_CPU_X86_64

View File

@ -62,7 +62,6 @@ void InitializeCPUContextX86(const ThreadContext::t32_t& thread_context,
context->dr5 = 0;
context->dr6 = 0;
context->dr7 = 0;
}
void InitializeCPUContextX86(const SignalThreadContext32& thread_context,
@ -241,7 +240,14 @@ void InitializeCPUContextARM64_NoFloatingPoint(
memcpy(context->regs, thread_context.regs, sizeof(context->regs));
context->sp = thread_context.sp;
context->pc = thread_context.pc;
context->pstate = thread_context.pstate;
// Linux seems to only be putting the SPSR register in its "pstate" field.
// https://elixir.bootlin.com/linux/latest/source/arch/arm64/include/uapi/asm/ptrace.h
if (thread_context.pstate >
std::numeric_limits<decltype(context->spsr)>::max()) {
LOG(WARNING) << "pstate truncation: we only expect the SPSR bits to be set "
"in the pstate";
}
context->spsr = static_cast<decltype(context->spsr)>(thread_context.pstate);
memset(&context->fpsimd, 0, sizeof(context->fpsimd));
context->fpsr = 0;

View File

@ -224,7 +224,7 @@ void InitializeContext(NativeCPUContext* context) {
}
context->uc_mcontext.sp = 1;
context->uc_mcontext.pc = 2;
context->uc_mcontext.pstate = 3;
context->uc_mcontext.spsr = 3;
auto test_context = reinterpret_cast<TestCoprocessorContext*>(
context->uc_mcontext.__reserved);
@ -254,7 +254,7 @@ void ExpectContext(const CPUContext& actual, const NativeCPUContext& expected) {
0);
EXPECT_EQ(actual.arm64->sp, expected.uc_mcontext.sp);
EXPECT_EQ(actual.arm64->pc, expected.uc_mcontext.pc);
EXPECT_EQ(actual.arm64->pstate, expected.uc_mcontext.pstate);
EXPECT_EQ(actual.arm64->spsr, expected.uc_mcontext.spsr);
auto test_context = reinterpret_cast<const TestCoprocessorContext*>(
expected.uc_mcontext.__reserved);

View File

@ -761,7 +761,7 @@ TEST(ProcessSnapshotMinidump, ThreadContextARM64) {
const CPUContextARM64* ctx = ctx_generic->arm64;
EXPECT_EQ(ctx->pstate, 0UL);
EXPECT_EQ(ctx->spsr, 0UL);
for (unsigned int i = 0; i < 31; i++) {
EXPECT_EQ(ctx->regs[i], i + 1);

View File

@ -239,10 +239,7 @@ bool ThreadSnapshotMinidump::InitializeContext(
context_.arm64->pc = src->pc;
context_.arm64->fpcr = src->fpcr;
context_.arm64->fpsr = src->fpsr;
// Seems we don't get a full PSTATE but it looks like this assignment
// should give something useful at least.
context_.arm64->pstate = src->cpsr;
context_.arm64->spsr = src->cpsr;
} else if (context_.architecture == CPUArchitecture::kCPUArchitectureMIPSEL) {
LOG(WARNING) << "Snapshot MIPS context support has no unit tests.";
context_memory_.resize(sizeof(CPUContextMIPS));

View File

@ -210,7 +210,7 @@ void InitializeCPUContextARM64(CPUContext* context, uint32_t seed) {
}
arm64->sp = value++;
arm64->pc = value++;
arm64->pstate = value++;
arm64->spsr = value++;
for (size_t index = 0; index < arraysize(arm64->fpsimd); ++index) {
arm64->fpsimd[index].lo = value++;

View File

@ -159,7 +159,7 @@ CAPTURECONTEXT_SYMBOL:
// The link register holds the return address for this function.
str LR, [x0, #0x1b8] // context->uc_mcontext.pc
// NZCV, pstate, and CPSR are synonyms.
// pstate should hold SPSR but NZCV are the only bits we know about.
mrs x1, NZCV
str x1, [x0, #0x1c0] // context->uc_mcontext.pstate

View File

@ -319,7 +319,7 @@ CAPTURECONTEXT_SYMBOL2:
// The link register holds the return address for this function.
str x30, [x0, #0x1b8] // context->uc_mcontext.pc
// NZCV, pstate, and CPSR are synonyms.
// pstate should hold SPSR but NZCV are the only bits we know about.
mrs x1, NZCV
str x1, [x0, #0x1c0] // context->uc_mcontext.pstate