1dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky/* 2dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky * Copyright (C) 2015 The Android Open Source Project 3dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky * 4dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky * Licensed under the Apache License, Version 2.0 (the "License"); 5dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky * you may not use this file except in compliance with the License. 6dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky * You may obtain a copy of the License at 7dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky * 8dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky * http://www.apache.org/licenses/LICENSE-2.0 9dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky * 10dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky * Unless required by applicable law or agreed to in writing, software 11dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky * distributed under the License is distributed on an "AS IS" BASIS, 12dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky * See the License for the specific language governing permissions and 14dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky * limitations under the License. 15dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky */ 16dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky 17dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky#include <memory> 18dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky#include <vector> 19dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky 20dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky#include "arch/instruction_set.h" 21dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky#include "cfi_test.h" 22dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky#include "gtest/gtest.h" 23dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky#include "jni/quick/calling_convention.h" 24dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky#include "utils/assembler.h" 25dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky 26dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky#include "jni/jni_cfi_test_expected.inc" 27dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky 28dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbeckynamespace art { 29dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky 30dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky// Run the tests only on host. 31dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky#ifndef HAVE_ANDROID_OS 32dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky 33dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbeckyclass JNICFITest : public CFITest { 34dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky public: 35dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky // Enable this flag to generate the expected outputs. 36dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky static constexpr bool kGenerateExpected = false; 37dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky 38dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky void TestImpl(InstructionSet isa, const char* isa_str, 39dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky const std::vector<uint8_t>& expected_asm, 40dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky const std::vector<uint8_t>& expected_cfi) { 41dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky // Description of simple method. 42dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky const bool is_static = true; 43dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky const bool is_synchronized = false; 44dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky const char* shorty = "IIFII"; 45dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky std::unique_ptr<JniCallingConvention> jni_conv( 46dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky JniCallingConvention::Create(is_static, is_synchronized, shorty, isa)); 47dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky std::unique_ptr<ManagedRuntimeCallingConvention> mr_conv( 48dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky ManagedRuntimeCallingConvention::Create(is_static, is_synchronized, shorty, isa)); 49dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky const int frame_size(jni_conv->FrameSize()); 50dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky const std::vector<ManagedRegister>& callee_save_regs = jni_conv->CalleeSaveRegisters(); 51dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky 52dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky // Assemble the method. 53dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky std::unique_ptr<Assembler> jni_asm(Assembler::Create(isa)); 54dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky jni_asm->BuildFrame(frame_size, mr_conv->MethodRegister(), 55dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky callee_save_regs, mr_conv->EntrySpills()); 56dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky jni_asm->IncreaseFrameSize(32); 57dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky jni_asm->DecreaseFrameSize(32); 58dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky jni_asm->RemoveFrame(frame_size, callee_save_regs); 59dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky jni_asm->EmitSlowPaths(); 60dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky std::vector<uint8_t> actual_asm(jni_asm->CodeSize()); 61dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky MemoryRegion code(&actual_asm[0], actual_asm.size()); 62dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky jni_asm->FinalizeInstructions(code); 63dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky ASSERT_EQ(jni_asm->cfi().GetCurrentCFAOffset(), frame_size); 64dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky const std::vector<uint8_t>& actual_cfi = *(jni_asm->cfi().data()); 65dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky 66dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky if (kGenerateExpected) { 67dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky GenerateExpected(stdout, isa, isa_str, actual_asm, actual_cfi); 68dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky } else { 69dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky EXPECT_EQ(expected_asm, actual_asm); 70dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky EXPECT_EQ(expected_cfi, actual_cfi); 71dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky } 72dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky } 73dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky}; 74dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky 75dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky#define TEST_ISA(isa) \ 76dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky TEST_F(JNICFITest, isa) { \ 77dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky std::vector<uint8_t> expected_asm(expected_asm_##isa, \ 78dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky expected_asm_##isa + arraysize(expected_asm_##isa)); \ 79dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky std::vector<uint8_t> expected_cfi(expected_cfi_##isa, \ 80dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky expected_cfi_##isa + arraysize(expected_cfi_##isa)); \ 81dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky TestImpl(isa, #isa, expected_asm, expected_cfi); \ 82dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky } 83dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky 84dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid SrbeckyTEST_ISA(kThumb2) 85dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid SrbeckyTEST_ISA(kArm64) 86dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid SrbeckyTEST_ISA(kX86) 87dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid SrbeckyTEST_ISA(kX86_64) 88dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid SrbeckyTEST_ISA(kMips) 89dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid SrbeckyTEST_ISA(kMips64) 90dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky 91dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky#endif // HAVE_ANDROID_OS 92dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky 93dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky} // namespace art 94