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