1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_COMPILER_UTILS_JNI_MACRO_ASSEMBLER_TEST_H_ 18 #define ART_COMPILER_UTILS_JNI_MACRO_ASSEMBLER_TEST_H_ 19 20 #include "jni_macro_assembler.h" 21 22 #include "assembler_test_base.h" 23 #include "base/malloc_arena_pool.h" 24 #include "common_runtime_test.h" // For ScratchFile 25 26 #include <sys/stat.h> 27 28 #include <cstdio> 29 #include <cstdlib> 30 #include <fstream> 31 #include <iterator> 32 33 namespace art { 34 35 template<typename Ass> 36 class JNIMacroAssemblerTest : public testing::Test { 37 public: GetAssembler()38 Ass* GetAssembler() { 39 return assembler_.get(); 40 } 41 42 typedef std::string (*TestFn)(JNIMacroAssemblerTest* assembler_test, Ass* assembler); 43 DriverFn(TestFn f,const std::string & test_name)44 void DriverFn(TestFn f, const std::string& test_name) { 45 DriverWrapper(f(this, assembler_.get()), test_name); 46 } 47 48 // This driver assumes the assembler has already been called. DriverStr(const std::string & assembly_string,const std::string & test_name)49 void DriverStr(const std::string& assembly_string, const std::string& test_name) { 50 DriverWrapper(assembly_string, test_name); 51 } 52 53 // This is intended to be run as a test. CheckTools()54 bool CheckTools() { 55 return test_helper_->CheckTools(); 56 } 57 58 protected: JNIMacroAssemblerTest()59 JNIMacroAssemblerTest() {} 60 SetUp()61 void SetUp() override { 62 allocator_.reset(new ArenaAllocator(&pool_)); 63 assembler_.reset(CreateAssembler(allocator_.get())); 64 test_helper_.reset( 65 new AssemblerTestInfrastructure(GetArchitectureString(), 66 GetAssemblerCmdName(), 67 GetAssemblerParameters(), 68 GetObjdumpCmdName(), 69 GetObjdumpParameters(), 70 GetDisassembleCmdName(), 71 GetDisassembleParameters(), 72 GetAssemblyHeader())); 73 74 SetUpHelpers(); 75 } 76 TearDown()77 void TearDown() override { 78 test_helper_.reset(); // Clean up the helper. 79 assembler_.reset(); 80 allocator_.reset(); 81 } 82 83 // Override this to set up any architecture-specific things, e.g., CPU revision. CreateAssembler(ArenaAllocator * allocator)84 virtual Ass* CreateAssembler(ArenaAllocator* allocator) { 85 return new (allocator) Ass(allocator); 86 } 87 88 // Override this to set up any architecture-specific things, e.g., register vectors. SetUpHelpers()89 virtual void SetUpHelpers() {} 90 91 // Get the typically used name for this architecture, e.g., aarch64, x86_64, ... 92 virtual std::string GetArchitectureString() = 0; 93 94 // Get the name of the assembler, e.g., "as" by default. GetAssemblerCmdName()95 virtual std::string GetAssemblerCmdName() { 96 return "as"; 97 } 98 99 // Switches to the assembler command. Default none. GetAssemblerParameters()100 virtual std::string GetAssemblerParameters() { 101 return ""; 102 } 103 104 // Get the name of the objdump, e.g., "objdump" by default. GetObjdumpCmdName()105 virtual std::string GetObjdumpCmdName() { 106 return "objdump"; 107 } 108 109 // Switches to the objdump command. Default is " -h". GetObjdumpParameters()110 virtual std::string GetObjdumpParameters() { 111 return " -h"; 112 } 113 114 // Get the name of the objdump, e.g., "objdump" by default. GetDisassembleCmdName()115 virtual std::string GetDisassembleCmdName() { 116 return "objdump"; 117 } 118 119 // Switches to the objdump command. As it's a binary, one needs to push the architecture and 120 // such to objdump, so it's architecture-specific and there is no default. 121 virtual std::string GetDisassembleParameters() = 0; 122 123 // If the assembly file needs a header, return it in a sub-class. GetAssemblyHeader()124 virtual const char* GetAssemblyHeader() { 125 return nullptr; 126 } 127 128 private: 129 // Override this to pad the code with NOPs to a certain size if needed. Pad(std::vector<uint8_t> & data ATTRIBUTE_UNUSED)130 virtual void Pad(std::vector<uint8_t>& data ATTRIBUTE_UNUSED) { 131 } 132 DriverWrapper(const std::string & assembly_text,const std::string & test_name)133 void DriverWrapper(const std::string& assembly_text, const std::string& test_name) { 134 assembler_->FinalizeCode(); 135 size_t cs = assembler_->CodeSize(); 136 std::unique_ptr<std::vector<uint8_t>> data(new std::vector<uint8_t>(cs)); 137 MemoryRegion code(&(*data)[0], data->size()); 138 assembler_->FinalizeInstructions(code); 139 Pad(*data); 140 test_helper_->Driver(*data, assembly_text, test_name); 141 } 142 143 MallocArenaPool pool_; 144 std::unique_ptr<ArenaAllocator> allocator_; 145 std::unique_ptr<Ass> assembler_; 146 std::unique_ptr<AssemblerTestInfrastructure> test_helper_; 147 148 DISALLOW_COPY_AND_ASSIGN(JNIMacroAssemblerTest); 149 }; 150 151 } // namespace art 152 153 #endif // ART_COMPILER_UTILS_JNI_MACRO_ASSEMBLER_TEST_H_ 154