[vm, compiler] Update the RISC-V shadow call stack pointer from S2 to GP.
Cf. https://reviews.llvm.org/D146463 TEST=ci (Linux), inspect disassembly (Fuchsia/Android) Change-Id: I3ef4bc4c3212e80221ec7edaebfa33e9eb1db03d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/291660 Commit-Queue: Ryan Macnak <rmacnak@google.com> Reviewed-by: Daco Harkes <dacoharkes@google.com>
This commit is contained in:
committed by
Commit Queue
parent
f70238a83b
commit
867dfd226e
File diff suppressed because it is too large
Load Diff
@@ -3228,6 +3228,10 @@ void StubCodeCompiler::GenerateJumpToFrameStub() {
|
||||
__ mov(THR, R3);
|
||||
__ SetupCSPFromThread(THR);
|
||||
#if defined(DART_TARGET_OS_FUCHSIA)
|
||||
// We need to restore the shadow call stack pointer like longjmp would,
|
||||
// effectively popping all the return addresses between the Dart exit frame
|
||||
// and Exceptions::JumpToFrame, otherwise the shadow call stack might
|
||||
// eventually overflow.
|
||||
__ ldr(R18, Address(THR, target::Thread::saved_shadow_call_stack_offset()));
|
||||
#elif defined(USING_SHADOW_CALL_STACK)
|
||||
#error Unimplemented
|
||||
|
||||
@@ -1317,8 +1317,8 @@ void StubCodeCompiler::GenerateInvokeDartCodeStub() {
|
||||
__ lx(TMP2, Address(A3, target::Thread::invoke_dart_code_stub_offset()));
|
||||
__ sx(TMP2, Address(SP, 0 * target::kWordSize));
|
||||
|
||||
#if defined(DART_TARGET_OS_FUCHSIA)
|
||||
__ sx(S2, Address(A3, target::Thread::saved_shadow_call_stack_offset()));
|
||||
#if defined(DART_TARGET_OS_FUCHSIA) || defined(DART_TARGET_OS_ANDROID)
|
||||
__ sx(GP, Address(A3, target::Thread::saved_shadow_call_stack_offset()));
|
||||
#elif defined(USING_SHADOW_CALL_STACK)
|
||||
#error Unimplemented
|
||||
#endif
|
||||
@@ -3002,8 +3002,12 @@ void StubCodeCompiler::GenerateJumpToFrameStub() {
|
||||
__ mv(SP, A1); // Stack pointer.
|
||||
__ mv(FP, A2); // Frame_pointer.
|
||||
__ mv(THR, A3);
|
||||
#if defined(DART_TARGET_OS_FUCHSIA)
|
||||
__ lx(S2, Address(THR, target::Thread::saved_shadow_call_stack_offset()));
|
||||
#if defined(DART_TARGET_OS_FUCHSIA) || defined(DART_TARGET_OS_ANDROID)
|
||||
// We need to restore the shadow call stack pointer like longjmp would,
|
||||
// effectively popping all the return addresses between the Dart exit frame
|
||||
// and Exceptions::JumpToFrame, otherwise the shadow call stack might
|
||||
// eventually overflow.
|
||||
__ lx(GP, Address(THR, target::Thread::saved_shadow_call_stack_offset()));
|
||||
#elif defined(USING_SHADOW_CALL_STACK)
|
||||
#error Unimplemented
|
||||
#endif
|
||||
|
||||
@@ -46,7 +46,7 @@ enum Register {
|
||||
ZR = 0,
|
||||
RA = 1,
|
||||
SP = 2,
|
||||
GP = 3,
|
||||
GP = 3, // Shadow call stack on Fuchsia and Android
|
||||
TP = 4,
|
||||
T0 = 5,
|
||||
T1 = 6,
|
||||
@@ -61,7 +61,7 @@ enum Register {
|
||||
A5 = 15, // PP, untagged
|
||||
A6 = 16,
|
||||
A7 = 17,
|
||||
S2 = 18, // ShadowCallStack
|
||||
S2 = 18,
|
||||
S3 = 19,
|
||||
S4 = 20, // ARGS_DESC_REG
|
||||
S5 = 21, // IC_DATA_REG
|
||||
@@ -198,19 +198,19 @@ struct InstantiateTAVInternalRegs {
|
||||
static constexpr intptr_t kSavedRegisters = 0;
|
||||
|
||||
// Additional registers used to probe hash-based caches.
|
||||
static constexpr Register kEntryStartReg = S3;
|
||||
static constexpr Register kProbeMaskReg = S4;
|
||||
static constexpr Register kProbeDistanceReg = S5;
|
||||
static constexpr Register kCurrentEntryIndexReg = S6;
|
||||
static constexpr Register kEntryStartReg = S2;
|
||||
static constexpr Register kProbeMaskReg = S3;
|
||||
static constexpr Register kProbeDistanceReg = S4;
|
||||
static constexpr Register kCurrentEntryIndexReg = S5;
|
||||
};
|
||||
|
||||
// Registers in addition to those listed in TypeTestABI used inside the
|
||||
// implementation of type testing stubs that are _not_ preserved.
|
||||
struct TTSInternalRegs {
|
||||
static constexpr Register kInstanceTypeArgumentsReg = S3;
|
||||
static constexpr Register kScratchReg = S4;
|
||||
static constexpr Register kSubTypeArgumentReg = S5;
|
||||
static constexpr Register kSuperTypeArgumentReg = S6;
|
||||
static constexpr Register kInstanceTypeArgumentsReg = S2;
|
||||
static constexpr Register kScratchReg = S3;
|
||||
static constexpr Register kSubTypeArgumentReg = S4;
|
||||
static constexpr Register kSuperTypeArgumentReg = S5;
|
||||
|
||||
// Must be pushed/popped whenever generic type arguments are being checked as
|
||||
// they overlap with registers in TypeTestABI.
|
||||
@@ -225,10 +225,10 @@ struct TTSInternalRegs {
|
||||
// Registers in addition to those listed in TypeTestABI used inside the
|
||||
// implementation of subtype test cache stubs that are _not_ preserved.
|
||||
struct STCInternalRegs {
|
||||
static constexpr Register kInstanceCidOrSignatureReg = S3;
|
||||
static constexpr Register kInstanceInstantiatorTypeArgumentsReg = S4;
|
||||
static constexpr Register kInstanceParentFunctionTypeArgumentsReg = S5;
|
||||
static constexpr Register kInstanceDelayedFunctionTypeArgumentsReg = S6;
|
||||
static constexpr Register kInstanceCidOrSignatureReg = S2;
|
||||
static constexpr Register kInstanceInstantiatorTypeArgumentsReg = S3;
|
||||
static constexpr Register kInstanceParentFunctionTypeArgumentsReg = S4;
|
||||
static constexpr Register kInstanceDelayedFunctionTypeArgumentsReg = S5;
|
||||
|
||||
static constexpr intptr_t kInternalRegisters =
|
||||
(1 << kInstanceCidOrSignatureReg) |
|
||||
@@ -493,13 +493,10 @@ constexpr RegList kAbiPreservedCpuRegs = R(S1) | R(S2) | R(S3) | R(S4) | R(S5) |
|
||||
R(S10) | R(S11);
|
||||
constexpr int kAbiPreservedCpuRegCount = 11;
|
||||
|
||||
// S2 is reserved as the shadow call stack pointer on Fuchsia and Android.
|
||||
// Although it is available on Linux, we mark it as reserved unconditionally to
|
||||
// avoid adding another dimenision for OS into the extracted runtime offsets.
|
||||
constexpr RegList kReservedCpuRegisters =
|
||||
R(ZR) | R(TP) | R(GP) | R(SP) | R(FP) | R(TMP) | R(TMP2) | R(PP) | R(THR) |
|
||||
R(RA) | R(WRITE_BARRIER_STATE) | R(NULL_REG) | R(DISPATCH_TABLE_REG) |
|
||||
R(FAR_TMP) | R(S2);
|
||||
R(FAR_TMP);
|
||||
constexpr intptr_t kNumberOfReservedCpuRegisters =
|
||||
Utils::CountOneBits32(kReservedCpuRegisters);
|
||||
// CPU registers available to Dart allocator.
|
||||
@@ -568,8 +565,8 @@ class CallingConventions {
|
||||
static constexpr Register kSecondReturnReg = A1;
|
||||
static constexpr FpuRegister kReturnFpuReg = FA0;
|
||||
|
||||
// S0=FP, S1=THR, S2=ShadowCallStack
|
||||
static constexpr Register kFfiAnyNonAbiRegister = S3;
|
||||
// S0=FP, S1=THR
|
||||
static constexpr Register kFfiAnyNonAbiRegister = S2;
|
||||
static constexpr Register kFirstNonArgumentRegister = T0;
|
||||
static constexpr Register kSecondNonArgumentRegister = T1;
|
||||
static constexpr Register kStackPointerRegister = SPREG;
|
||||
|
||||
@@ -414,10 +414,10 @@ intptr_t TypeTestingStubCallPattern::GetSubtypeTestCachePoolIndex() {
|
||||
// where Rn = TypeTestABI::kSubtypeTestCacheReg.
|
||||
|
||||
// Ensure the caller of the type testing stub (whose return address is [pc_])
|
||||
// branched via `blr R9` or a pc-relative call.
|
||||
if (*reinterpret_cast<uint16_t*>(pc_ - 2) == 0x9a02) { // jalr s4
|
||||
// branched via `jalr s3` or a pc-relative call.
|
||||
if (*reinterpret_cast<uint16_t*>(pc_ - 2) == 0x9982) { // jalr s3
|
||||
// indirect call
|
||||
// xxxx c.jalr s4
|
||||
// xxxx c.jalr s3
|
||||
Register reg;
|
||||
intptr_t pool_index = -1;
|
||||
InstructionPattern::DecodeLoadWordFromPool(pc_ - 2, ®, &pool_index);
|
||||
|
||||
@@ -3890,6 +3890,9 @@ void Simulator::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) {
|
||||
set_register(nullptr, FP, static_cast<int64_t>(fp));
|
||||
set_register(nullptr, THR, reinterpret_cast<int64_t>(thread));
|
||||
set_register(nullptr, R31, thread->saved_stack_limit() - 4096);
|
||||
#if defined(DART_TARGET_OS_FUCHSIA)
|
||||
set_register(nullptr, R18, thread->saved_shadow_call_stack());
|
||||
#endif
|
||||
// Set the tag.
|
||||
thread->set_vm_tag(VMTag::kDartTagId);
|
||||
// Clear top exit frame.
|
||||
|
||||
@@ -449,6 +449,9 @@ void Simulator::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) {
|
||||
set_xreg(SP, static_cast<uintx_t>(sp));
|
||||
set_xreg(FP, static_cast<uintx_t>(fp));
|
||||
set_xreg(THR, reinterpret_cast<uintx_t>(thread));
|
||||
#if defined(DART_TARGET_OS_FUCHSIA) || defined(DART_TARGET_OS_ANDROID)
|
||||
set_xreg(GP, thread->saved_shadow_call_stack());
|
||||
#endif
|
||||
// Set the tag.
|
||||
thread->set_vm_tag(VMTag::kDartTagId);
|
||||
// Clear top exit frame.
|
||||
|
||||
@@ -403,6 +403,7 @@ class Thread : public ThreadState {
|
||||
saved_safestack_limit_ = limit;
|
||||
}
|
||||
#endif
|
||||
uword saved_shadow_call_stack() const { return saved_shadow_call_stack_; }
|
||||
static uword saved_shadow_call_stack_offset() {
|
||||
return OFFSET_OF(Thread, saved_shadow_call_stack_);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user