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_DISASSEMBLER_DISASSEMBLER_ARM64_H_ 18 #define ART_DISASSEMBLER_DISASSEMBLER_ARM64_H_ 19 20 #include "disassembler.h" 21 22 // TODO(VIXL): Make VIXL compile cleanly with -Wshadow, -Wdeprecated-declarations. 23 #pragma GCC diagnostic push 24 #pragma GCC diagnostic ignored "-Wshadow" 25 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 26 #include "aarch64/decoder-aarch64.h" 27 #include "aarch64/disasm-aarch64.h" 28 #pragma GCC diagnostic pop 29 30 namespace art { 31 namespace arm64 { 32 33 class CustomDisassembler final : public vixl::aarch64::Disassembler { 34 public: CustomDisassembler(DisassemblerOptions * options)35 explicit CustomDisassembler(DisassemblerOptions* options) 36 : vixl::aarch64::Disassembler(), 37 read_literals_(options->can_read_literals_), 38 base_address_(options->base_address_), 39 end_address_(options->end_address_), 40 options_(options) { 41 if (!options->absolute_addresses_) { 42 MapCodeAddress(0, 43 reinterpret_cast<const vixl::aarch64::Instruction*>(options->base_address_)); 44 } 45 } 46 47 // Use register aliases in the disassembly. 48 void AppendRegisterNameToOutput(const vixl::aarch64::Instruction* instr, 49 const vixl::aarch64::CPURegister& reg) override; 50 51 // Overriding to print the address with trailing zeroes e.g. 0x00004074 instead of 0x4074. 52 void AppendCodeRelativeAddressToOutput(const vixl::aarch64::Instruction* instr, 53 const void* addr) override; 54 55 // Intercepts the instruction flow captured by the parent method, 56 // to specially instrument for particular instruction types. 57 void Visit(vixl::aarch64::Metadata* metadata, const vixl::aarch64::Instruction* instr) override; 58 59 private: 60 // Improve the disassembly of literal load instructions. 61 void VisitLoadLiteralInstr(const vixl::aarch64::Instruction* instr); 62 63 // Improve the disassembly of thread offset. 64 void VisitLoadStoreUnsignedOffsetInstr(const vixl::aarch64::Instruction* instr); 65 66 // Improve the disassembly of branch to thunk jumping to pointer from thread entrypoint. 67 void VisitUnconditionalBranchInstr(const vixl::aarch64::Instruction* instr); 68 69 void AppendThreadOfsetName(const vixl::aarch64::Instruction* instr); 70 71 // Indicate if the disassembler should read data loaded from literal pools. 72 // This should only be enabled if reading the target of literal loads is safe. 73 // Here are possible outputs when the option is on or off: 74 // read_literals_ | disassembly 75 // true | 0x72681558: 1c000acb ldr s11, pc+344 (addr 0x726816b0) 76 // false | 0x72681558: 1c000acb ldr s11, pc+344 (addr 0x726816b0) (3.40282e+38) 77 const bool read_literals_; 78 79 // Valid address range: [base_address_, end_address_) 80 const void* const base_address_; 81 const void* const end_address_; 82 83 DisassemblerOptions* options_; 84 }; 85 86 class DisassemblerArm64 final : public Disassembler { 87 public: DisassemblerArm64(DisassemblerOptions * options)88 explicit DisassemblerArm64(DisassemblerOptions* options) : 89 Disassembler(options), disasm(options) { 90 decoder.AppendVisitor(&disasm); 91 } 92 93 size_t Dump(std::ostream& os, const uint8_t* begin) override; 94 void Dump(std::ostream& os, const uint8_t* begin, const uint8_t* end) override; 95 96 private: 97 vixl::aarch64::Decoder decoder; 98 CustomDisassembler disasm; 99 100 DISALLOW_COPY_AND_ASSIGN(DisassemblerArm64); 101 }; 102 103 } // namespace arm64 104 } // namespace art 105 106 #endif // ART_DISASSEMBLER_DISASSEMBLER_ARM64_H_ 107