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 #pragma GCC diagnostic push
23 #pragma GCC diagnostic ignored "-Wshadow"
24 #include "vixl/a64/decoder-a64.h"
25 #include "vixl/a64/disasm-a64.h"
26 #pragma GCC diagnostic pop
27 
28 namespace art {
29 namespace arm64 {
30 
31 class CustomDisassembler FINAL : public vixl::Disassembler {
32  public:
CustomDisassembler(DisassemblerOptions * options)33   explicit CustomDisassembler(DisassemblerOptions* options) :
34       vixl::Disassembler(), read_literals_(options->can_read_literals_) {
35     if (!options->absolute_addresses_) {
36       MapCodeAddress(0, reinterpret_cast<const vixl::Instruction*>(options->base_address_));
37     }
38   }
39 
40   // Use register aliases in the disassembly.
41   void AppendRegisterNameToOutput(const vixl::Instruction* instr,
42                                   const vixl::CPURegister& reg) OVERRIDE;
43 
44   // Improve the disassembly of literal load instructions.
45   void VisitLoadLiteral(const vixl::Instruction* instr) OVERRIDE;
46 
47   // Improve the disassembly of thread offset.
48   void VisitLoadStoreUnsignedOffset(const vixl::Instruction* instr) OVERRIDE;
49 
50  private:
51   // Indicate if the disassembler should read data loaded from literal pools.
52   // This should only be enabled if reading the target of literal loads is safe.
53   // Here are possible outputs when the option is on or off:
54   // read_literals_ | disassembly
55   //           true | 0x72681558: 1c000acb  ldr s11, pc+344 (addr 0x726816b0)
56   //          false | 0x72681558: 1c000acb  ldr s11, pc+344 (addr 0x726816b0) (3.40282e+38)
57   const bool read_literals_;
58 };
59 
60 class DisassemblerArm64 FINAL : public Disassembler {
61  public:
DisassemblerArm64(DisassemblerOptions * options)62   explicit DisassemblerArm64(DisassemblerOptions* options) :
63       Disassembler(options), disasm(options) {
64     decoder.AppendVisitor(&disasm);
65   }
66 
67   size_t Dump(std::ostream& os, const uint8_t* begin) OVERRIDE;
68   void Dump(std::ostream& os, const uint8_t* begin, const uint8_t* end) OVERRIDE;
69 
70  private:
71   vixl::Decoder decoder;
72   CustomDisassembler disasm;
73 
74   DISALLOW_COPY_AND_ASSIGN(DisassemblerArm64);
75 };
76 
77 }  // namespace arm64
78 }  // namespace art
79 
80 #endif  // ART_DISASSEMBLER_DISASSEMBLER_ARM64_H_
81