1 | // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
2 | // for details. All rights reserved. Use of this source code is governed by a |
3 | // BSD-style license that can be found in the LICENSE file. |
4 | |
5 | #ifndef RUNTIME_VM_COMPILER_ASSEMBLER_DISASSEMBLER_H_ |
6 | #define RUNTIME_VM_COMPILER_ASSEMBLER_DISASSEMBLER_H_ |
7 | |
8 | #include "vm/allocation.h" |
9 | #include "vm/globals.h" |
10 | #include "vm/log.h" |
11 | #include "vm/object.h" |
12 | |
13 | #if !defined(DART_PRECOMPILED_RUNTIME) |
14 | #include "vm/compiler/assembler/assembler.h" |
15 | #endif // !defined(DART_PRECOMPILED_RUNTIME) |
16 | |
17 | namespace dart { |
18 | |
19 | // Forward declaration. |
20 | class MemoryRegion; |
21 | class JSONArray; |
22 | |
23 | // Disassembly formatter interface, which consumes the |
24 | // disassembled instructions in any desired form. |
25 | class DisassemblyFormatter { |
26 | public: |
27 | DisassemblyFormatter() {} |
28 | virtual ~DisassemblyFormatter() {} |
29 | |
30 | // Consume the decoded instruction at the given pc. |
31 | virtual void ConsumeInstruction(char* hex_buffer, |
32 | intptr_t hex_size, |
33 | char* human_buffer, |
34 | intptr_t human_size, |
35 | Object* object, |
36 | uword pc) = 0; |
37 | |
38 | // Print a formatted message. |
39 | virtual void Print(const char* format, ...) PRINTF_ATTRIBUTE(2, 3) = 0; |
40 | }; |
41 | |
42 | // Basic disassembly formatter that outputs the disassembled instruction |
43 | // to stdout. |
44 | class DisassembleToStdout : public DisassemblyFormatter { |
45 | public: |
46 | DisassembleToStdout() : DisassemblyFormatter() {} |
47 | ~DisassembleToStdout() {} |
48 | |
49 | virtual void ConsumeInstruction(char* hex_buffer, |
50 | intptr_t hex_size, |
51 | char* human_buffer, |
52 | intptr_t human_size, |
53 | Object* object, |
54 | uword pc); |
55 | |
56 | virtual void Print(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); |
57 | |
58 | private: |
59 | DISALLOW_ALLOCATION() |
60 | DISALLOW_COPY_AND_ASSIGN(DisassembleToStdout); |
61 | }; |
62 | |
63 | // Disassemble into a JSONStream. |
64 | class DisassembleToJSONStream : public DisassemblyFormatter { |
65 | public: |
66 | explicit DisassembleToJSONStream(const JSONArray& jsarr) |
67 | : DisassemblyFormatter(), jsarr_(jsarr) {} |
68 | ~DisassembleToJSONStream() {} |
69 | |
70 | virtual void ConsumeInstruction(char* hex_buffer, |
71 | intptr_t hex_size, |
72 | char* human_buffer, |
73 | intptr_t human_size, |
74 | Object* object, |
75 | uword pc); |
76 | |
77 | virtual void Print(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); |
78 | |
79 | private: |
80 | const JSONArray& jsarr_; |
81 | DISALLOW_ALLOCATION(); |
82 | DISALLOW_COPY_AND_ASSIGN(DisassembleToJSONStream); |
83 | }; |
84 | |
85 | #if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER) |
86 | // Basic disassembly formatter that outputs the disassembled instruction |
87 | // to a memory buffer. This is only intended for test writing. |
88 | class DisassembleToMemory : public DisassemblyFormatter { |
89 | public: |
90 | DisassembleToMemory(char* buffer, uintptr_t length) |
91 | : DisassemblyFormatter(), |
92 | buffer_(buffer), |
93 | remaining_(length), |
94 | overflowed_(false) {} |
95 | ~DisassembleToMemory() {} |
96 | |
97 | virtual void ConsumeInstruction(char* hex_buffer, |
98 | intptr_t hex_size, |
99 | char* human_buffer, |
100 | intptr_t human_size, |
101 | Object* object, |
102 | uword pc); |
103 | |
104 | virtual void Print(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); |
105 | |
106 | private: |
107 | char* buffer_; |
108 | int remaining_; |
109 | bool overflowed_; |
110 | DISALLOW_ALLOCATION(); |
111 | DISALLOW_COPY_AND_ASSIGN(DisassembleToMemory); |
112 | }; |
113 | #endif |
114 | |
115 | // Disassemble instructions. |
116 | class Disassembler : public AllStatic { |
117 | public: |
118 | // Disassemble instructions between start and end. |
119 | // (The assumption is that start is at a valid instruction). |
120 | // Return true if all instructions were successfully decoded, false otherwise. |
121 | static void (uword start, |
122 | uword end, |
123 | DisassemblyFormatter* formatter, |
124 | const Code& code, |
125 | const Code::Comments* = nullptr); |
126 | |
127 | static void Disassemble(uword start, |
128 | uword end, |
129 | DisassemblyFormatter* formatter) { |
130 | Disassemble(start, end, formatter, Code::Handle()); |
131 | } |
132 | |
133 | static void (uword start, |
134 | uword end, |
135 | DisassemblyFormatter* formatter, |
136 | const Code::Comments* ) { |
137 | Disassemble(start, end, formatter, Code::Handle(), comments); |
138 | } |
139 | |
140 | static void Disassemble(uword start, uword end, const Code& code) { |
141 | #if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER) |
142 | DisassembleToStdout stdout_formatter; |
143 | LogBlock lb; |
144 | Disassemble(start, end, &stdout_formatter, code); |
145 | #else |
146 | UNREACHABLE(); |
147 | #endif |
148 | } |
149 | |
150 | static void Disassemble(uword start, uword end) { |
151 | #if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER) |
152 | DisassembleToStdout stdout_formatter; |
153 | LogBlock lb; |
154 | Disassemble(start, end, &stdout_formatter); |
155 | #else |
156 | UNREACHABLE(); |
157 | #endif |
158 | } |
159 | |
160 | static void Disassemble(uword start, |
161 | uword end, |
162 | char* buffer, |
163 | uintptr_t buffer_size) { |
164 | #if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER) |
165 | DisassembleToMemory memory_formatter(buffer, buffer_size); |
166 | LogBlock lb; |
167 | Disassemble(start, end, &memory_formatter); |
168 | #else |
169 | UNREACHABLE(); |
170 | #endif |
171 | } |
172 | |
173 | // Decodes one instruction. |
174 | // Writes a hexadecimal representation into the hex_buffer and a |
175 | // human-readable representation into the human_buffer. |
176 | // Writes the length of the decoded instruction in bytes in out_instr_len. |
177 | static void DecodeInstruction(char* hex_buffer, |
178 | intptr_t hex_size, |
179 | char* human_buffer, |
180 | intptr_t human_size, |
181 | int* out_instr_len, |
182 | const Code& code, |
183 | Object** object, |
184 | uword pc); |
185 | |
186 | static void DisassembleCode(const Function& function, |
187 | const Code& code, |
188 | bool optimized); |
189 | |
190 | static void DisassembleStub(const char* name, const Code& code); |
191 | |
192 | private: |
193 | static void DisassembleCodeHelper(const char* function_fullname, |
194 | const char* function_info, |
195 | const Code& code, |
196 | bool optimized); |
197 | |
198 | static const int kHexadecimalBufferSize = 32; |
199 | static const int kUserReadableBufferSize = 256; |
200 | }; |
201 | |
202 | } // namespace dart |
203 | |
204 | #endif // RUNTIME_VM_COMPILER_ASSEMBLER_DISASSEMBLER_H_ |
205 | |