blob: a895dfe823873458d9472a53d5cd6388910e5ed8 [file] [log] [blame]
Serban Constantinescue6622be2014-02-27 15:36:47 +00001/*
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
Artem Serovaf4e42a2016-08-08 15:11:24 +010022// TODO(VIXL): Make VIXL compile with -Wshadow.
Andreas Gampe277ccbd2014-11-03 21:36:10 -080023#pragma GCC diagnostic push
24#pragma GCC diagnostic ignored "-Wshadow"
Artem Serovaf4e42a2016-08-08 15:11:24 +010025#include "aarch64/decoder-aarch64.h"
26#include "aarch64/disasm-aarch64.h"
Andreas Gampe277ccbd2014-11-03 21:36:10 -080027#pragma GCC diagnostic pop
Serban Constantinescue6622be2014-02-27 15:36:47 +000028
29namespace art {
30namespace arm64 {
31
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010032class CustomDisassembler final : public vixl::aarch64::Disassembler {
Alexandre Ramesa37d9252014-10-27 11:28:14 +000033 public:
Aart Bikd3059e72016-05-11 10:30:47 -070034 explicit CustomDisassembler(DisassemblerOptions* options)
Scott Wakeling97c72b72016-06-24 16:19:36 +010035 : vixl::aarch64::Disassembler(),
Aart Bikd3059e72016-05-11 10:30:47 -070036 read_literals_(options->can_read_literals_),
37 base_address_(options->base_address_),
Andreas Gampe372f3a32016-08-19 10:49:06 -070038 end_address_(options->end_address_),
39 options_(options) {
Alexandre Ramesd737ab32015-03-06 09:11:12 +000040 if (!options->absolute_addresses_) {
Scott Wakeling97c72b72016-06-24 16:19:36 +010041 MapCodeAddress(0,
42 reinterpret_cast<const vixl::aarch64::Instruction*>(options->base_address_));
Alexandre Ramesd737ab32015-03-06 09:11:12 +000043 }
44 }
Alexandre Ramesa37d9252014-10-27 11:28:14 +000045
46 // Use register aliases in the disassembly.
Scott Wakeling97c72b72016-06-24 16:19:36 +010047 void AppendRegisterNameToOutput(const vixl::aarch64::Instruction* instr,
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010048 const vixl::aarch64::CPURegister& reg) override;
Alexandre Ramesa37d9252014-10-27 11:28:14 +000049
50 // Improve the disassembly of literal load instructions.
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010051 void VisitLoadLiteral(const vixl::aarch64::Instruction* instr) override;
Zheng Xua34e7602015-02-03 12:03:15 +080052
53 // Improve the disassembly of thread offset.
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010054 void VisitLoadStoreUnsignedOffset(const vixl::aarch64::Instruction* instr) override;
Alexandre Ramesa37d9252014-10-27 11:28:14 +000055
Vladimir Marko8feddbc2020-09-03 09:59:45 +010056 // Improve the disassembly of branch to thunk jumping to pointer from thread entrypoint.
57 void VisitUnconditionalBranch(const vixl::aarch64::Instruction* instr) override;
58
Alexandre Ramesa37d9252014-10-27 11:28:14 +000059 private:
Vladimir Marko8feddbc2020-09-03 09:59:45 +010060 void AppendThreadOfsetName(const vixl::aarch64::Instruction* instr);
61
Alexandre Ramesa37d9252014-10-27 11:28:14 +000062 // Indicate if the disassembler should read data loaded from literal pools.
63 // This should only be enabled if reading the target of literal loads is safe.
64 // Here are possible outputs when the option is on or off:
65 // read_literals_ | disassembly
66 // true | 0x72681558: 1c000acb ldr s11, pc+344 (addr 0x726816b0)
67 // false | 0x72681558: 1c000acb ldr s11, pc+344 (addr 0x726816b0) (3.40282e+38)
68 const bool read_literals_;
Aart Bikd3059e72016-05-11 10:30:47 -070069
70 // Valid address range: [base_address_, end_address_)
71 const void* const base_address_;
72 const void* const end_address_;
Andreas Gampe372f3a32016-08-19 10:49:06 -070073
74 DisassemblerOptions* options_;
Alexandre Ramesa37d9252014-10-27 11:28:14 +000075};
76
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010077class DisassemblerArm64 final : public Disassembler {
Serban Constantinescue6622be2014-02-27 15:36:47 +000078 public:
Alexandre Ramesa37d9252014-10-27 11:28:14 +000079 explicit DisassemblerArm64(DisassemblerOptions* options) :
Alexandre Ramesd737ab32015-03-06 09:11:12 +000080 Disassembler(options), disasm(options) {
Serban Constantinescue6622be2014-02-27 15:36:47 +000081 decoder.AppendVisitor(&disasm);
82 }
83
Roland Levillainbbc6e7e2018-08-24 16:58:47 +010084 size_t Dump(std::ostream& os, const uint8_t* begin) override;
85 void Dump(std::ostream& os, const uint8_t* begin, const uint8_t* end) override;
Serban Constantinescue6622be2014-02-27 15:36:47 +000086
87 private:
Scott Wakeling97c72b72016-06-24 16:19:36 +010088 vixl::aarch64::Decoder decoder;
Alexandre Ramesa37d9252014-10-27 11:28:14 +000089 CustomDisassembler disasm;
Serban Constantinescue6622be2014-02-27 15:36:47 +000090
91 DISALLOW_COPY_AND_ASSIGN(DisassemblerArm64);
92};
93
94} // namespace arm64
95} // namespace art
96
97#endif // ART_DISASSEMBLER_DISASSEMBLER_ARM64_H_