diff options
author | Martyn Capewell <martyn.capewell@arm.com> | 2018-10-22 15:25:28 +0100 |
---|---|---|
committer | Jacob Bramley <jacob.bramley@arm.com> | 2018-10-22 15:26:54 +0100 |
commit | cb963f7bd9ac4f72d5948eef3f293a44315ecaee (patch) | |
tree | a4a131ffb344124ff405c8bb63a75ac3d0e51702 /test/aarch64 | |
parent | 8f36e7f6aa3fcb4ae765ab527904e32af2224c38 (diff) | |
download | vixl-cb963f7bd9ac4f72d5948eef3f293a44315ecaee.tar.gz |
Add support for BTI.
Add support for Branch Target Identification. This also adds an extension to
Bind() to indicate which instruction should be used as the landing pad - one of
the BTIs or a PAuth instruction.
The simulation support is partial; memory may only be guarded globally or not at
all.
Change-Id: Idb54826dcf866f1e677fe1579d05987621eae721
Diffstat (limited to 'test/aarch64')
-rw-r--r-- | test/aarch64/test-assembler-aarch64.cc | 264 | ||||
-rw-r--r-- | test/aarch64/test-disasm-aarch64.cc | 22 |
2 files changed, 274 insertions, 12 deletions
diff --git a/test/aarch64/test-assembler-aarch64.cc b/test/aarch64/test-assembler-aarch64.cc index 45aa033e..90b70956 100644 --- a/test/aarch64/test-assembler-aarch64.cc +++ b/test/aarch64/test-assembler-aarch64.cc @@ -339,18 +339,23 @@ const CPUFeatures kInfrastructureCPUFeatures(CPUFeatures::kNEON); #define ASSERT_LITERAL_POOL_SIZE(expected) \ VIXL_CHECK((expected + kInstructionSize) == (masm.GetLiteralPoolSize())) -#define MUST_FAIL_WITH_MESSAGE(code, message) \ - { \ - bool aborted = false; \ - try { \ - code; \ - } catch (const std::runtime_error& e) { \ - const char* expected_error = message; \ - size_t error_length = strlen(expected_error); \ - VIXL_CHECK(strncmp(expected_error, e.what(), error_length) == 0); \ - aborted = true; \ - } \ - VIXL_CHECK(aborted); \ +#define MUST_FAIL_WITH_MESSAGE(code, message) \ + { \ + bool aborted = false; \ + try { \ + code; \ + } catch (const std::runtime_error& e) { \ + const char* expected_error = message; \ + size_t error_length = strlen(expected_error); \ + if (strncmp(expected_error, e.what(), error_length) == 0) { \ + aborted = true; \ + } else { \ + printf("Mismatch in error message.\n"); \ + printf("Expected: %s\n", expected_error); \ + printf("Found: %s\n", e.what()); \ + } \ + } \ + VIXL_CHECK(aborted); \ } @@ -2799,6 +2804,56 @@ TEST(return_to_reg_auth) { TEARDOWN(); } +TEST(return_to_reg_auth_guarded) { + SETUP_WITH_FEATURES(CPUFeatures::kPAuth); + + START(); + + Label fn1, after_fn1; + + __ Mov(x28, sp); + __ Mov(x29, lr); + __ Mov(sp, 0x477d469dec0b8760); + + __ Mov(x0, 0); + __ B(&after_fn1); + + __ Bind(&fn1, EmitPACIASP); + __ Mov(x0, 42); + __ Retaa(); + + __ Bind(&after_fn1); + __ Adr(x2, &fn1); + __ Blr(x2); + + Label fn2, after_fn2; + + __ Mov(x1, 0); + __ B(&after_fn2); + + __ Bind(&fn2, EmitPACIBSP); + __ Mov(x1, 84); + __ Retab(); + + __ Bind(&after_fn2); + __ Adr(x2, &fn2); + __ Blr(x2); + + __ Mov(sp, x28); + __ Mov(lr, x29); + END(); + +#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64 + simulator.SetGuardedPages(true); + RUN(); + + ASSERT_EQUAL_64(42, x0); + ASSERT_EQUAL_64(84, x1); +#endif + + TEARDOWN(); +} + #ifdef VIXL_NEGATIVE_TESTING TEST(branch_to_reg_auth_fail) { SETUP_WITH_FEATURES(CPUFeatures::kPAuth); @@ -15127,6 +15182,191 @@ TEST(system) { TEARDOWN(); } +static void BtiHelper(Register ipreg) { + SETUP_WITH_FEATURES(CPUFeatures::kBTI); + + Label jump_target, jump_call_target, call_target, done; + START(); + UseScratchRegisterScope temps(&masm); + temps.Exclude(ipreg); + __ Adr(x0, &jump_target); + __ Br(x0); + __ Nop(); + __ Bind(&jump_target, EmitBTI_j); + __ Adr(x0, &call_target); + __ Blr(x0); + __ Adr(ipreg, &jump_call_target); + __ Blr(ipreg); + __ Adr(lr, &done); // Make Ret return to done label. + __ Br(ipreg); + __ Bind(&call_target, EmitBTI_c); + __ Ret(); + __ Bind(&jump_call_target, EmitBTI_jc); + __ Ret(); + __ Bind(&done); + END(); + +#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64 + simulator.SetGuardedPages(true); + RUN(); +#endif // VIXL_INCLUDE_SIMULATOR_AARCH64 + + TEARDOWN(); +} + +TEST(bti) { + BtiHelper(x16); + BtiHelper(x17); +} + +TEST(unguarded_bti_is_nop) { + SETUP_WITH_FEATURES(CPUFeatures::kBTI); + + Label start, none, c, j, jc; + START(); + __ B(&start); + __ Bind(&none, EmitBTI); + __ Bind(&c, EmitBTI_c); + __ Bind(&j, EmitBTI_j); + __ Bind(&jc, EmitBTI_jc); + VIXL_CHECK(__ GetSizeOfCodeGeneratedSince(&none) == 4 * kInstructionSize); + __ Ret(); + + Label jump_to_c, call_to_j; + __ Bind(&start); + __ Adr(x0, &none); + __ Adr(lr, &jump_to_c); + __ Br(x0); + + __ Bind(&jump_to_c); + __ Adr(x0, &c); + __ Adr(lr, &call_to_j); + __ Br(x0); + + __ Bind(&call_to_j); + __ Adr(x0, &j); + __ Blr(x0); + END(); + +#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64 + simulator.SetGuardedPages(false); + RUN(); +#endif // VIXL_INCLUDE_SIMULATOR_AARCH64 + + TEARDOWN(); +} + +#ifdef VIXL_NEGATIVE_TESTING +TEST(bti_jump_to_ip_unidentified) { + SETUP(); + + START(); + UseScratchRegisterScope temps(&masm); + temps.Exclude(x17); + Label l; + __ Adr(x17, &l); + __ Br(x17); + __ Nop(); + __ Bind(&l); + __ Nop(); + END(); + +#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64 + simulator.SetGuardedPages(true); + MUST_FAIL_WITH_MESSAGE(RUN(), + "Executing non-BTI instruction with wrong " + "BType."); +#endif // VIXL_INCLUDE_SIMULATOR_AARCH64 + + TEARDOWN(); +} + +TEST(bti_jump_to_unidentified) { + SETUP(); + + START(); + Label l; + __ Adr(x0, &l); + __ Br(x0); + __ Nop(); + __ Bind(&l); + __ Nop(); + END(); + +#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64 + simulator.SetGuardedPages(true); + MUST_FAIL_WITH_MESSAGE(RUN(), + "Executing non-BTI instruction with wrong " + "BType."); +#endif // VIXL_INCLUDE_SIMULATOR_AARCH64 + + TEARDOWN(); +} + +TEST(bti_call_to_unidentified) { + SETUP(); + + START(); + Label l; + __ Adr(x0, &l); + __ Blr(x0); + __ Nop(); + __ Bind(&l); + __ Nop(); + END(); + +#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64 + simulator.SetGuardedPages(true); + MUST_FAIL_WITH_MESSAGE(RUN(), + "Executing non-BTI instruction with wrong " + "BType."); +#endif // VIXL_INCLUDE_SIMULATOR_AARCH64 + + TEARDOWN(); +} + +TEST(bti_jump_to_c) { + SETUP_WITH_FEATURES(CPUFeatures::kBTI); + + START(); + // Jumping to a "BTI c" target must fail. + Label jump_target; + __ Adr(x0, &jump_target); + __ Br(x0); + __ Nop(); + __ Bind(&jump_target, EmitBTI_c); + __ Nop(); + END(); + +#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64 + simulator.SetGuardedPages(true); + MUST_FAIL_WITH_MESSAGE(RUN(), "Executing BTI c with wrong BType."); +#endif // VIXL_INCLUDE_SIMULATOR_AARCH64 + + TEARDOWN(); +} + +TEST(bti_call_to_j) { + SETUP_WITH_FEATURES(CPUFeatures::kBTI); + + START(); + // Calling a "BTI j" target must fail. + Label call_target; + __ Adr(x0, &call_target); + __ Blr(x0); + __ Nop(); + __ Bind(&call_target, EmitBTI_j); + __ Nop(); + END(); + +#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64 + simulator.SetGuardedPages(true); + MUST_FAIL_WITH_MESSAGE(RUN(), "Executing BTI j with wrong BType."); +#endif // VIXL_INCLUDE_SIMULATOR_AARCH64 + + TEARDOWN(); +} +#endif // VIXL_NEGATIVE_TESTING TEST(zero_dest) { // RegisterDump::Dump uses NEON. diff --git a/test/aarch64/test-disasm-aarch64.cc b/test/aarch64/test-disasm-aarch64.cc index d90c542d..1282c38b 100644 --- a/test/aarch64/test-disasm-aarch64.cc +++ b/test/aarch64/test-disasm-aarch64.cc @@ -3210,6 +3210,7 @@ TEST(system_nop) { SETUP(); COMPARE(nop(), "nop"); + COMPARE_MACRO(Nop(), "nop"); CLEANUP(); } @@ -7541,5 +7542,26 @@ TEST(hint) { CLEANUP(); } +TEST(bti) { + SETUP(); + + COMPARE(bti(EmitBTI), "bti"); + COMPARE(bti(EmitBTI_c), "bti c"); + COMPARE(bti(EmitBTI_j), "bti j"); + COMPARE(bti(EmitBTI_jc), "bti jc"); + COMPARE(hint(BTI), "bti"); + COMPARE(hint(BTI_c), "bti c"); + COMPARE(hint(BTI_j), "bti j"); + COMPARE(hint(BTI_jc), "bti jc"); + + Label dummy1, dummy2, dummy3, dummy4; + COMPARE_MACRO(Bind(&dummy1, EmitBTI), "bti"); + COMPARE_MACRO(Bind(&dummy2, EmitBTI_c), "bti c"); + COMPARE_MACRO(Bind(&dummy3, EmitBTI_j), "bti j"); + COMPARE_MACRO(Bind(&dummy4, EmitBTI_jc), "bti jc"); + + CLEANUP(); +} + } // namespace aarch64 } // namespace vixl |