1e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu/* 2e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu * Copyright (C) 2014 The Android Open Source Project 3e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu * 4e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu * Licensed under the Apache License, Version 2.0 (the "License"); 5e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu * you may not use this file except in compliance with the License. 6e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu * You may obtain a copy of the License at 7e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu * 8e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu * http://www.apache.org/licenses/LICENSE-2.0 9e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu * 10e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu * Unless required by applicable law or agreed to in writing, software 11e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu * distributed under the License is distributed on an "AS IS" BASIS, 12e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu * See the License for the specific language governing permissions and 14e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu * limitations under the License. 15e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu */ 16e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu 17e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu#ifndef ART_DISASSEMBLER_DISASSEMBLER_ARM64_H_ 18e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu#define ART_DISASSEMBLER_DISASSEMBLER_ARM64_H_ 19e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu 20e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu#include "disassembler.h" 21e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu 22277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe#pragma GCC diagnostic push 23277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe#pragma GCC diagnostic ignored "-Wshadow" 2482e52ce8364e3e1c644d0d3b3b4f61364bf7089aSerban Constantinescu#include "vixl/a64/decoder-a64.h" 2582e52ce8364e3e1c644d0d3b3b4f61364bf7089aSerban Constantinescu#include "vixl/a64/disasm-a64.h" 26277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampe#pragma GCC diagnostic pop 27e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu 28e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescunamespace art { 29e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescunamespace arm64 { 30e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu 31a37d925d405be9f589ac282869a997e73414d859Alexandre Ramesclass CustomDisassembler FINAL : public vixl::Disassembler { 32a37d925d405be9f589ac282869a997e73414d859Alexandre Rames public: 33a6e95b32d499811bbb37602fc7446a5a0d05b9f8Aart Bik explicit CustomDisassembler(DisassemblerOptions* options) 34a6e95b32d499811bbb37602fc7446a5a0d05b9f8Aart Bik : vixl::Disassembler(), 35a6e95b32d499811bbb37602fc7446a5a0d05b9f8Aart Bik read_literals_(options->can_read_literals_), 36a6e95b32d499811bbb37602fc7446a5a0d05b9f8Aart Bik base_address_(options->base_address_), 37a6e95b32d499811bbb37602fc7446a5a0d05b9f8Aart Bik end_address_(options->end_address_) { 38d737ab33a458537fca6207e9e4e25198a1511113Alexandre Rames if (!options->absolute_addresses_) { 39d737ab33a458537fca6207e9e4e25198a1511113Alexandre Rames MapCodeAddress(0, reinterpret_cast<const vixl::Instruction*>(options->base_address_)); 40d737ab33a458537fca6207e9e4e25198a1511113Alexandre Rames } 41d737ab33a458537fca6207e9e4e25198a1511113Alexandre Rames } 42a37d925d405be9f589ac282869a997e73414d859Alexandre Rames 43a37d925d405be9f589ac282869a997e73414d859Alexandre Rames // Use register aliases in the disassembly. 44a34e760fa5cc3102ce1998f10816d380c37f43aaZheng Xu void AppendRegisterNameToOutput(const vixl::Instruction* instr, 45a34e760fa5cc3102ce1998f10816d380c37f43aaZheng Xu const vixl::CPURegister& reg) OVERRIDE; 46a37d925d405be9f589ac282869a997e73414d859Alexandre Rames 47a37d925d405be9f589ac282869a997e73414d859Alexandre Rames // Improve the disassembly of literal load instructions. 48a34e760fa5cc3102ce1998f10816d380c37f43aaZheng Xu void VisitLoadLiteral(const vixl::Instruction* instr) OVERRIDE; 49a34e760fa5cc3102ce1998f10816d380c37f43aaZheng Xu 50a34e760fa5cc3102ce1998f10816d380c37f43aaZheng Xu // Improve the disassembly of thread offset. 51a34e760fa5cc3102ce1998f10816d380c37f43aaZheng Xu void VisitLoadStoreUnsignedOffset(const vixl::Instruction* instr) OVERRIDE; 52a37d925d405be9f589ac282869a997e73414d859Alexandre Rames 53a37d925d405be9f589ac282869a997e73414d859Alexandre Rames private: 54a37d925d405be9f589ac282869a997e73414d859Alexandre Rames // Indicate if the disassembler should read data loaded from literal pools. 55a37d925d405be9f589ac282869a997e73414d859Alexandre Rames // This should only be enabled if reading the target of literal loads is safe. 56a37d925d405be9f589ac282869a997e73414d859Alexandre Rames // Here are possible outputs when the option is on or off: 57a37d925d405be9f589ac282869a997e73414d859Alexandre Rames // read_literals_ | disassembly 58a37d925d405be9f589ac282869a997e73414d859Alexandre Rames // true | 0x72681558: 1c000acb ldr s11, pc+344 (addr 0x726816b0) 59a37d925d405be9f589ac282869a997e73414d859Alexandre Rames // false | 0x72681558: 1c000acb ldr s11, pc+344 (addr 0x726816b0) (3.40282e+38) 60a37d925d405be9f589ac282869a997e73414d859Alexandre Rames const bool read_literals_; 61a6e95b32d499811bbb37602fc7446a5a0d05b9f8Aart Bik 62a6e95b32d499811bbb37602fc7446a5a0d05b9f8Aart Bik // Valid address range: [base_address_, end_address_) 63a6e95b32d499811bbb37602fc7446a5a0d05b9f8Aart Bik const void* const base_address_; 64a6e95b32d499811bbb37602fc7446a5a0d05b9f8Aart Bik const void* const end_address_; 65a37d925d405be9f589ac282869a997e73414d859Alexandre Rames}; 66a37d925d405be9f589ac282869a997e73414d859Alexandre Rames 6738e12034f1ef2b32e98b6e49cb36b7cc37a7f1beIan Rogersclass DisassemblerArm64 FINAL : public Disassembler { 68e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu public: 69a37d925d405be9f589ac282869a997e73414d859Alexandre Rames explicit DisassemblerArm64(DisassemblerOptions* options) : 70d737ab33a458537fca6207e9e4e25198a1511113Alexandre Rames Disassembler(options), disasm(options) { 71e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu decoder.AppendVisitor(&disasm); 72e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu } 73e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu 7438e12034f1ef2b32e98b6e49cb36b7cc37a7f1beIan Rogers size_t Dump(std::ostream& os, const uint8_t* begin) OVERRIDE; 7538e12034f1ef2b32e98b6e49cb36b7cc37a7f1beIan Rogers void Dump(std::ostream& os, const uint8_t* begin, const uint8_t* end) OVERRIDE; 76e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu 77e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu private: 78e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu vixl::Decoder decoder; 79a37d925d405be9f589ac282869a997e73414d859Alexandre Rames CustomDisassembler disasm; 80e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu 81e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu DISALLOW_COPY_AND_ASSIGN(DisassemblerArm64); 82e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu}; 83e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu 84e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu} // namespace arm64 85e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu} // namespace art 86e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu 87e6622be6c353c7178f34adf814c58370a51c5ed7Serban Constantinescu#endif // ART_DISASSEMBLER_DISASSEMBLER_ARM64_H_ 88