1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2014 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_DISASSEMBLER_DISASSEMBLER_ARM64_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_DISASSEMBLER_DISASSEMBLER_ARM64_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include "disassembler.h" 21*795d594fSAndroid Build Coastguard Worker 22*795d594fSAndroid Build Coastguard Worker // TODO(VIXL): Make VIXL compile cleanly with -Wshadow, -Wdeprecated-declarations. 23*795d594fSAndroid Build Coastguard Worker #pragma GCC diagnostic push 24*795d594fSAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wshadow" 25*795d594fSAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 26*795d594fSAndroid Build Coastguard Worker #include "aarch64/decoder-aarch64.h" 27*795d594fSAndroid Build Coastguard Worker #include "aarch64/disasm-aarch64.h" 28*795d594fSAndroid Build Coastguard Worker #pragma GCC diagnostic pop 29*795d594fSAndroid Build Coastguard Worker 30*795d594fSAndroid Build Coastguard Worker namespace art { 31*795d594fSAndroid Build Coastguard Worker namespace arm64 { 32*795d594fSAndroid Build Coastguard Worker 33*795d594fSAndroid Build Coastguard Worker class CustomDisassembler final : public vixl::aarch64::Disassembler { 34*795d594fSAndroid Build Coastguard Worker public: CustomDisassembler(DisassemblerOptions * options)35*795d594fSAndroid Build Coastguard Worker explicit CustomDisassembler(DisassemblerOptions* options) 36*795d594fSAndroid Build Coastguard Worker : vixl::aarch64::Disassembler(), 37*795d594fSAndroid Build Coastguard Worker read_literals_(options->can_read_literals_), 38*795d594fSAndroid Build Coastguard Worker base_address_(options->base_address_), 39*795d594fSAndroid Build Coastguard Worker end_address_(options->end_address_), 40*795d594fSAndroid Build Coastguard Worker options_(options) { 41*795d594fSAndroid Build Coastguard Worker if (!options->absolute_addresses_) { 42*795d594fSAndroid Build Coastguard Worker MapCodeAddress(0, 43*795d594fSAndroid Build Coastguard Worker reinterpret_cast<const vixl::aarch64::Instruction*>(options->base_address_)); 44*795d594fSAndroid Build Coastguard Worker } 45*795d594fSAndroid Build Coastguard Worker } 46*795d594fSAndroid Build Coastguard Worker 47*795d594fSAndroid Build Coastguard Worker // Use register aliases in the disassembly. 48*795d594fSAndroid Build Coastguard Worker void AppendRegisterNameToOutput(const vixl::aarch64::Instruction* instr, 49*795d594fSAndroid Build Coastguard Worker const vixl::aarch64::CPURegister& reg) override; 50*795d594fSAndroid Build Coastguard Worker 51*795d594fSAndroid Build Coastguard Worker // Overriding to print the address with trailing zeroes e.g. 0x00004074 instead of 0x4074. 52*795d594fSAndroid Build Coastguard Worker void AppendCodeRelativeAddressToOutput(const vixl::aarch64::Instruction* instr, 53*795d594fSAndroid Build Coastguard Worker const void* addr) override; 54*795d594fSAndroid Build Coastguard Worker 55*795d594fSAndroid Build Coastguard Worker // Intercepts the instruction flow captured by the parent method, 56*795d594fSAndroid Build Coastguard Worker // to specially instrument for particular instruction types. 57*795d594fSAndroid Build Coastguard Worker void Visit(vixl::aarch64::Metadata* metadata, const vixl::aarch64::Instruction* instr) override; 58*795d594fSAndroid Build Coastguard Worker 59*795d594fSAndroid Build Coastguard Worker private: 60*795d594fSAndroid Build Coastguard Worker // Improve the disassembly of literal load instructions. 61*795d594fSAndroid Build Coastguard Worker void VisitLoadLiteralInstr(const vixl::aarch64::Instruction* instr); 62*795d594fSAndroid Build Coastguard Worker 63*795d594fSAndroid Build Coastguard Worker // Improve the disassembly of thread offset. 64*795d594fSAndroid Build Coastguard Worker void VisitLoadStoreUnsignedOffsetInstr(const vixl::aarch64::Instruction* instr); 65*795d594fSAndroid Build Coastguard Worker 66*795d594fSAndroid Build Coastguard Worker // Improve the disassembly of branch to thunk jumping to pointer from thread entrypoint. 67*795d594fSAndroid Build Coastguard Worker void VisitUnconditionalBranchInstr(const vixl::aarch64::Instruction* instr); 68*795d594fSAndroid Build Coastguard Worker 69*795d594fSAndroid Build Coastguard Worker void AppendThreadOfsetName(const vixl::aarch64::Instruction* instr); 70*795d594fSAndroid Build Coastguard Worker 71*795d594fSAndroid Build Coastguard Worker // Indicate if the disassembler should read data loaded from literal pools. 72*795d594fSAndroid Build Coastguard Worker // This should only be enabled if reading the target of literal loads is safe. 73*795d594fSAndroid Build Coastguard Worker // Here are possible outputs when the option is on or off: 74*795d594fSAndroid Build Coastguard Worker // read_literals_ | disassembly 75*795d594fSAndroid Build Coastguard Worker // true | 0x72681558: 1c000acb ldr s11, pc+344 (addr 0x726816b0) 76*795d594fSAndroid Build Coastguard Worker // false | 0x72681558: 1c000acb ldr s11, pc+344 (addr 0x726816b0) (3.40282e+38) 77*795d594fSAndroid Build Coastguard Worker const bool read_literals_; 78*795d594fSAndroid Build Coastguard Worker 79*795d594fSAndroid Build Coastguard Worker // Valid address range: [base_address_, end_address_) 80*795d594fSAndroid Build Coastguard Worker const void* const base_address_; 81*795d594fSAndroid Build Coastguard Worker const void* const end_address_; 82*795d594fSAndroid Build Coastguard Worker 83*795d594fSAndroid Build Coastguard Worker DisassemblerOptions* options_; 84*795d594fSAndroid Build Coastguard Worker }; 85*795d594fSAndroid Build Coastguard Worker 86*795d594fSAndroid Build Coastguard Worker class DisassemblerArm64 final : public Disassembler { 87*795d594fSAndroid Build Coastguard Worker public: DisassemblerArm64(DisassemblerOptions * options)88*795d594fSAndroid Build Coastguard Worker explicit DisassemblerArm64(DisassemblerOptions* options) : 89*795d594fSAndroid Build Coastguard Worker Disassembler(options), disasm(options) { 90*795d594fSAndroid Build Coastguard Worker decoder.AppendVisitor(&disasm); 91*795d594fSAndroid Build Coastguard Worker } 92*795d594fSAndroid Build Coastguard Worker 93*795d594fSAndroid Build Coastguard Worker size_t Dump(std::ostream& os, const uint8_t* begin) override; 94*795d594fSAndroid Build Coastguard Worker void Dump(std::ostream& os, const uint8_t* begin, const uint8_t* end) override; 95*795d594fSAndroid Build Coastguard Worker 96*795d594fSAndroid Build Coastguard Worker private: 97*795d594fSAndroid Build Coastguard Worker vixl::aarch64::Decoder decoder; 98*795d594fSAndroid Build Coastguard Worker CustomDisassembler disasm; 99*795d594fSAndroid Build Coastguard Worker 100*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(DisassemblerArm64); 101*795d594fSAndroid Build Coastguard Worker }; 102*795d594fSAndroid Build Coastguard Worker 103*795d594fSAndroid Build Coastguard Worker } // namespace arm64 104*795d594fSAndroid Build Coastguard Worker } // namespace art 105*795d594fSAndroid Build Coastguard Worker 106*795d594fSAndroid Build Coastguard Worker #endif // ART_DISASSEMBLER_DISASSEMBLER_ARM64_H_ 107