]>
Commit | Line | Data |
---|---|---|
92df71f0 | 1 | /* Disassemble support for GDB. |
213516ef | 2 | Copyright (C) 2002-2023 Free Software Foundation, Inc. |
92df71f0 FN |
3 | |
4 | This file is part of GDB. | |
5 | ||
6 | This program is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
a9762ec7 | 8 | the Free Software Foundation; either version 3 of the License, or |
92df71f0 FN |
9 | (at your option) any later version. |
10 | ||
11 | This program is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
a9762ec7 | 17 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
92df71f0 FN |
18 | |
19 | #ifndef DISASM_H | |
20 | #define DISASM_H | |
21 | ||
d55e5aa6 | 22 | #include "dis-asm.h" |
c8154ce0 | 23 | #include "disasm-flags.h" |
e6158f16 | 24 | |
ed3ef339 | 25 | struct gdbarch; |
da3331ec | 26 | struct ui_out; |
30e221b4 | 27 | struct ui_file; |
da3331ec | 28 | |
5975a5ca AB |
29 | #if __cplusplus >= 201703L |
30 | #define LIBOPCODE_CALLBACK_NOEXCEPT noexcept | |
31 | #else | |
32 | #define LIBOPCODE_CALLBACK_NOEXCEPT | |
33 | #endif | |
34 | ||
f0c2e3e0 AB |
35 | /* A wrapper around a disassemble_info and a gdbarch. This is the core |
36 | set of data that all disassembler sub-classes will need. This class | |
37 | doesn't actually implement the disassembling process, that is something | |
38 | that sub-classes will do, with each sub-class doing things slightly | |
39 | differently. | |
4d89c1c7 | 40 | |
f0c2e3e0 AB |
41 | The constructor of this class is protected, you should not create |
42 | instances of this class directly, instead create an instance of an | |
43 | appropriate sub-class. */ | |
4d89c1c7 | 44 | |
f0c2e3e0 AB |
45 | struct gdb_disassemble_info |
46 | { | |
47 | DISABLE_COPY_AND_ASSIGN (gdb_disassemble_info); | |
e47ad6c0 | 48 | |
f0c2e3e0 | 49 | /* Return the gdbarch we are disassembling for. */ |
e47ad6c0 YQ |
50 | struct gdbarch *arch () |
51 | { return m_gdbarch; } | |
52 | ||
f0c2e3e0 AB |
53 | /* Return a pointer to the disassemble_info, this will be needed for |
54 | passing into the libopcodes disassembler. */ | |
55 | struct disassemble_info *disasm_info () | |
56 | { return &m_di; } | |
57 | ||
e47ad6c0 | 58 | protected: |
e47ad6c0 | 59 | |
5975a5ca AB |
60 | /* Types for the function callbacks within m_di. The actual function |
61 | signatures here are taken from include/dis-asm.h. The noexcept macro | |
62 | expands to 'noexcept' for C++17 and later, otherwise, it expands to | |
63 | nothing. This is because including noexcept was ignored for function | |
64 | types before C++17, but both GCC and Clang warn that the noexcept | |
65 | will become relevant when you switch to C++17, and this warning | |
66 | causes the build to fail. */ | |
67 | using read_memory_ftype | |
68 | = int (*) (bfd_vma, bfd_byte *, unsigned int, struct disassemble_info *) | |
69 | LIBOPCODE_CALLBACK_NOEXCEPT; | |
70 | using memory_error_ftype | |
71 | = void (*) (int, bfd_vma, struct disassemble_info *) | |
72 | LIBOPCODE_CALLBACK_NOEXCEPT; | |
73 | using print_address_ftype | |
74 | = void (*) (bfd_vma, struct disassemble_info *) | |
75 | LIBOPCODE_CALLBACK_NOEXCEPT; | |
76 | using fprintf_ftype | |
77 | = int (*) (void *, const char *, ...) | |
78 | LIBOPCODE_CALLBACK_NOEXCEPT; | |
79 | using fprintf_styled_ftype | |
80 | = int (*) (void *, enum disassembler_style, const char *, ...) | |
81 | LIBOPCODE_CALLBACK_NOEXCEPT; | |
f0c2e3e0 | 82 | |
81384924 AB |
83 | /* Constructor, many fields in m_di are initialized from GDBARCH. The |
84 | remaining arguments are function callbacks that are written into m_di. | |
85 | Of these function callbacks FPRINTF_FUNC and FPRINTF_STYLED_FUNC must | |
86 | not be nullptr. If READ_MEMORY_FUNC, MEMORY_ERROR_FUNC, or | |
87 | PRINT_ADDRESS_FUNC are nullptr, then that field within m_di is left | |
88 | with its default value (see the libopcodes function | |
89 | init_disassemble_info for the defaults). */ | |
f0c2e3e0 | 90 | gdb_disassemble_info (struct gdbarch *gdbarch, |
f0c2e3e0 AB |
91 | read_memory_ftype read_memory_func, |
92 | memory_error_ftype memory_error_func, | |
93 | print_address_ftype print_address_func, | |
94 | fprintf_ftype fprintf_func, | |
95 | fprintf_styled_ftype fprintf_styled_func); | |
96 | ||
97 | /* Destructor. */ | |
98 | virtual ~gdb_disassemble_info (); | |
99 | ||
e47ad6c0 YQ |
100 | /* Stores data required for disassembling instructions in |
101 | opcodes. */ | |
102 | struct disassemble_info m_di; | |
471b9d15 | 103 | |
f0c2e3e0 AB |
104 | private: |
105 | /* The architecture we are disassembling for. */ | |
106 | struct gdbarch *m_gdbarch; | |
107 | ||
471b9d15 MR |
108 | /* If we own the string in `m_di.disassembler_options', we do so |
109 | using this field. */ | |
110 | std::string m_disassembler_options_holder; | |
f0c2e3e0 AB |
111 | }; |
112 | ||
113 | /* A wrapper around gdb_disassemble_info. This class adds default | |
114 | print functions that are supplied to the disassemble_info within the | |
115 | parent class. These default print functions write to the stream, which | |
116 | is also contained in the parent class. | |
117 | ||
118 | As with the parent class, the constructor for this class is protected, | |
119 | you should not create instances of this class, but create an | |
120 | appropriate sub-class instead. */ | |
121 | ||
122 | struct gdb_printing_disassembler : public gdb_disassemble_info | |
123 | { | |
124 | DISABLE_COPY_AND_ASSIGN (gdb_printing_disassembler); | |
125 | ||
126 | protected: | |
471b9d15 | 127 | |
81384924 AB |
128 | /* The stream that disassembler output is being written too. */ |
129 | struct ui_file *stream () | |
130 | { return m_stream; } | |
131 | ||
f0c2e3e0 AB |
132 | /* Constructor. All the arguments are just passed to the parent class. |
133 | We also add the two print functions to the arguments passed to the | |
134 | parent. See gdb_disassemble_info for a description of how the | |
135 | arguments are handled. */ | |
136 | gdb_printing_disassembler (struct gdbarch *gdbarch, | |
137 | struct ui_file *stream, | |
138 | read_memory_ftype read_memory_func, | |
139 | memory_error_ftype memory_error_func, | |
140 | print_address_ftype print_address_func) | |
81384924 | 141 | : gdb_disassemble_info (gdbarch, read_memory_func, |
f0c2e3e0 | 142 | memory_error_func, print_address_func, |
81384924 AB |
143 | fprintf_func, fprintf_styled_func), |
144 | m_stream (stream) | |
145 | { | |
146 | gdb_assert (stream != nullptr); | |
147 | } | |
148 | ||
149 | /* Callback used as the disassemble_info's fprintf_func callback. The | |
150 | DIS_INFO pointer is a pointer to a gdb_printing_disassembler object. | |
151 | Content is written to the m_stream extracted from DIS_INFO. */ | |
8eb7d135 | 152 | static int fprintf_func (void *dis_info, const char *format, ...) noexcept |
f0c2e3e0 AB |
153 | ATTRIBUTE_PRINTF(2,3); |
154 | ||
81384924 AB |
155 | /* Callback used as the disassemble_info's fprintf_styled_func callback. |
156 | The DIS_INFO pointer is a pointer to a gdb_printing_disassembler | |
157 | object. Content is written to the m_stream extracted from DIS_INFO. */ | |
158 | static int fprintf_styled_func (void *dis_info, | |
f0c2e3e0 | 159 | enum disassembler_style style, |
8eb7d135 | 160 | const char *format, ...) noexcept |
f0c2e3e0 | 161 | ATTRIBUTE_PRINTF(3,4); |
81384924 | 162 | |
4cbe4ca5 AB |
163 | /* Return true if the disassembler is considered inside a comment, false |
164 | otherwise. */ | |
165 | bool in_comment_p () const | |
166 | { return m_in_comment; } | |
167 | ||
168 | /* Set whether the disassembler should be considered as within comment | |
169 | text or not. */ | |
170 | void set_in_comment (bool c) | |
171 | { m_in_comment = c; } | |
172 | ||
81384924 AB |
173 | private: |
174 | ||
175 | /* When libopcodes calls the fprintf_func and fprintf_styled_func | |
176 | callbacks, a 'void *' argument is passed. We arrange, through our | |
177 | call to init_disassemble_info that this argument will be a pointer to | |
178 | a gdb_disassemble_info sub-class, specifically, a | |
179 | gdb_printing_disassembler pointer. This helper function casts | |
180 | DIS_INFO to the correct type (with some asserts), and then returns the | |
181 | m_stream member variable. */ | |
182 | static ui_file *stream_from_gdb_disassemble_info (void *dis_info); | |
183 | ||
184 | /* The stream to which output should be sent. */ | |
185 | struct ui_file *m_stream; | |
4cbe4ca5 AB |
186 | |
187 | /* Are we inside a comment? This will be set true if the disassembler | |
188 | uses styled output and emits a start of comment character. It is up | |
189 | to the code that uses this disassembler class to reset this flag back | |
190 | to false at a suitable time (e.g. at the end of every line). */ | |
55412841 | 191 | bool m_in_comment = false; |
f0c2e3e0 AB |
192 | }; |
193 | ||
8b39b1e7 AB |
194 | /* A basic disassembler that doesn't actually print anything. */ |
195 | ||
196 | struct gdb_non_printing_disassembler : public gdb_disassemble_info | |
197 | { | |
198 | gdb_non_printing_disassembler (struct gdbarch *gdbarch, | |
199 | read_memory_ftype read_memory_func) | |
81384924 | 200 | : gdb_disassemble_info (gdbarch, |
8b39b1e7 AB |
201 | read_memory_func, |
202 | nullptr /* memory_error_func */, | |
203 | nullptr /* print_address_func */, | |
204 | null_fprintf_func, | |
205 | null_fprintf_styled_func) | |
206 | { /* Nothing. */ } | |
207 | ||
208 | private: | |
209 | ||
210 | /* Callback used as the disassemble_info's fprintf_func callback, this | |
211 | doesn't write anything to STREAM, but just returns 0. */ | |
8eb7d135 | 212 | static int null_fprintf_func (void *stream, const char *format, ...) noexcept |
8b39b1e7 AB |
213 | ATTRIBUTE_PRINTF(2,3); |
214 | ||
215 | /* Callback used as the disassemble_info's fprintf_styled_func callback, | |
216 | , this doesn't write anything to STREAM, but just returns 0. */ | |
217 | static int null_fprintf_styled_func (void *stream, | |
218 | enum disassembler_style style, | |
8eb7d135 | 219 | const char *format, ...) noexcept |
8b39b1e7 AB |
220 | ATTRIBUTE_PRINTF(3,4); |
221 | }; | |
222 | ||
75033d08 AB |
223 | /* This is a helper class, for use as an additional base-class, by some of |
224 | the disassembler classes below. This class just defines a static method | |
225 | for reading from target memory, which can then be used by the various | |
226 | disassembler sub-classes. */ | |
227 | ||
228 | struct gdb_disassembler_memory_reader | |
229 | { | |
230 | /* Implements the read_memory_func disassemble_info callback. */ | |
231 | static int dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr, | |
232 | unsigned int len, | |
8eb7d135 | 233 | struct disassemble_info *info) noexcept; |
75033d08 AB |
234 | }; |
235 | ||
8b39b1e7 AB |
236 | /* A non-printing disassemble_info management class. The disassemble_info |
237 | setup by this class will not print anything to the output stream (there | |
238 | is no output stream), and the instruction to be disassembled will be | |
239 | read from target memory. */ | |
240 | ||
241 | struct gdb_non_printing_memory_disassembler | |
75033d08 AB |
242 | : public gdb_non_printing_disassembler, |
243 | private gdb_disassembler_memory_reader | |
8b39b1e7 AB |
244 | { |
245 | /* Constructor. GDBARCH is the architecture to disassemble for. */ | |
246 | gdb_non_printing_memory_disassembler (struct gdbarch *gdbarch) | |
247 | :gdb_non_printing_disassembler (gdbarch, dis_asm_read_memory) | |
248 | { /* Nothing. */ } | |
8b39b1e7 AB |
249 | }; |
250 | ||
f0c2e3e0 AB |
251 | /* A dissassembler class that provides 'print_insn', a method for |
252 | disassembling a single instruction to the output stream. */ | |
253 | ||
75033d08 AB |
254 | struct gdb_disassembler : public gdb_printing_disassembler, |
255 | private gdb_disassembler_memory_reader | |
f0c2e3e0 AB |
256 | { |
257 | gdb_disassembler (struct gdbarch *gdbarch, struct ui_file *file) | |
258 | : gdb_disassembler (gdbarch, file, dis_asm_read_memory) | |
259 | { /* Nothing. */ } | |
260 | ||
261 | DISABLE_COPY_AND_ASSIGN (gdb_disassembler); | |
262 | ||
263 | /* Disassemble a single instruction at MEMADDR to the ui_file* that was | |
264 | passed to the constructor. If a memory error occurs while | |
265 | disassembling this instruction then an error will be thrown. */ | |
266 | int print_insn (CORE_ADDR memaddr, int *branch_delay_insns = NULL); | |
267 | ||
268 | protected: | |
269 | gdb_disassembler (struct gdbarch *gdbarch, struct ui_file *file, | |
270 | read_memory_ftype func); | |
271 | ||
272 | private: | |
76b43c9b AB |
273 | /* This member variable is given a value by calling dis_asm_memory_error. |
274 | If after calling into the libopcodes disassembler we get back a | |
275 | negative value (which indicates an error), then, if this variable has | |
276 | a value, we report a memory error to the user, otherwise, we report a | |
277 | non-memory error. */ | |
278 | gdb::optional<CORE_ADDR> m_err_memaddr; | |
e47ad6c0 | 279 | |
f22c50c2 AB |
280 | /* The stream to which disassembler output will be written. */ |
281 | ui_file *m_dest; | |
282 | ||
e867795e AB |
283 | /* Disassembler output is built up into this buffer. Whether this |
284 | string_file is created with styling support or not depends on the | |
285 | value of use_ext_lang_colorization_p, as well as whether disassembler | |
286 | styling in general is turned on, and also, whether *m_dest supports | |
287 | styling or not. */ | |
288 | string_file m_buffer; | |
289 | ||
e867795e AB |
290 | /* When true, m_buffer will be created without styling support, |
291 | otherwise, m_buffer will be created with styling support. | |
292 | ||
293 | This field will initially be true, but will be set to false if | |
294 | ext_lang_colorize_disasm fails to add styling at any time. | |
295 | ||
296 | If the extension language is going to add the styling then m_buffer | |
297 | should be created without styling support, the extension language will | |
298 | then add styling at the end of the disassembly process. | |
299 | ||
300 | If the extension language is not going to add the styling, then we | |
301 | create m_buffer with styling support, and GDB will add minimal styling | |
302 | (currently just to addresses and symbols) as it goes. */ | |
303 | static bool use_ext_lang_colorization_p; | |
304 | ||
e47ad6c0 | 305 | static void dis_asm_memory_error (int err, bfd_vma memaddr, |
8eb7d135 | 306 | struct disassemble_info *info) noexcept; |
e47ad6c0 | 307 | static void dis_asm_print_address (bfd_vma addr, |
8eb7d135 | 308 | struct disassemble_info *info) noexcept; |
f22c50c2 AB |
309 | |
310 | /* Return true if we should use the extension language to apply | |
311 | disassembler styling. This requires disassembler styling to be on | |
312 | (i.e. 'set style disassembler enabled on'), the output stream needs to | |
313 | support styling, and libopcode styling needs to be either off, or not | |
314 | supported for the current architecture (libopcodes is used in | |
315 | preference to the extension language method). */ | |
316 | bool use_ext_lang_for_styling () const; | |
317 | ||
318 | /* Return true if we should use libopcodes to apply disassembler styling. | |
319 | This requires disassembler styling to be on (i.e. 'set style | |
320 | disassembler enabled on'), the output stream needs to support styling, | |
321 | and libopcodes styling needs to be supported for the current | |
322 | architecture, and not disabled by the user. */ | |
323 | bool use_libopcodes_for_styling () const; | |
e47ad6c0 YQ |
324 | }; |
325 | ||
a50a4026 MM |
326 | /* An instruction to be disassembled. */ |
327 | ||
328 | struct disasm_insn | |
329 | { | |
330 | /* The address of the memory containing the instruction. */ | |
331 | CORE_ADDR addr; | |
332 | ||
333 | /* An optional instruction number. If non-zero, it is printed first. */ | |
334 | unsigned int number; | |
335 | ||
336 | /* True if the instruction was executed speculatively. */ | |
337 | unsigned int is_speculative:1; | |
338 | }; | |
339 | ||
13274fc3 | 340 | extern void gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout, |
9a24775b | 341 | gdb_disassembly_flags flags, int how_many, |
9c419145 | 342 | CORE_ADDR low, CORE_ADDR high); |
92bf2b80 | 343 | |
a4642986 MR |
344 | /* Print the instruction at address MEMADDR in debugged memory, |
345 | on STREAM. Returns the length of the instruction, in bytes, | |
346 | and, if requested, the number of branch delay slot instructions. */ | |
92bf2b80 | 347 | |
13274fc3 UW |
348 | extern int gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr, |
349 | struct ui_file *stream, int *branch_delay_insns); | |
92bf2b80 | 350 | |
c99cc448 | 351 | /* Class used to pretty-print instructions. */ |
187808b0 | 352 | |
8b172ce7 PA |
353 | class gdb_pretty_print_disassembler |
354 | { | |
355 | public: | |
046bebe1 TT |
356 | explicit gdb_pretty_print_disassembler (struct gdbarch *gdbarch, |
357 | struct ui_out *uiout) | |
358 | : m_uiout (uiout), | |
359 | m_insn_stb (uiout->can_emit_style_escape ()), | |
360 | m_di (gdbarch, &m_insn_stb) | |
8b172ce7 PA |
361 | {} |
362 | ||
046bebe1 TT |
363 | /* Prints the instruction INSN into the saved ui_out and returns the |
364 | length of the printed instruction in bytes. */ | |
365 | int pretty_print_insn (const struct disasm_insn *insn, | |
9a24775b | 366 | gdb_disassembly_flags flags); |
8b172ce7 PA |
367 | |
368 | private: | |
369 | /* Returns the architecture used for disassembling. */ | |
370 | struct gdbarch *arch () { return m_di.arch (); } | |
371 | ||
046bebe1 TT |
372 | /* The ui_out that is used by pretty_print_insn. */ |
373 | struct ui_out *m_uiout; | |
8b172ce7 PA |
374 | |
375 | /* The buffer used to build the instruction string. The | |
376 | disassembler is initialized with this stream. */ | |
377 | string_file m_insn_stb; | |
378 | ||
046bebe1 TT |
379 | /* The disassembler used for instruction printing. */ |
380 | gdb_disassembler m_di; | |
381 | ||
8b172ce7 PA |
382 | /* The buffer used to build the raw opcodes string. */ |
383 | string_file m_opcode_stb; | |
d309a8f9 AB |
384 | |
385 | /* The buffer used to hold the opcode bytes (if required). */ | |
386 | gdb::byte_vector m_opcode_data; | |
8b172ce7 | 387 | }; |
187808b0 | 388 | |
eda5a4d7 PA |
389 | /* Return the length in bytes of the instruction at address MEMADDR in |
390 | debugged memory. */ | |
391 | ||
392 | extern int gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR memaddr); | |
393 | ||
394 | /* Return the length in bytes of INSN, originally at MEMADDR. MAX_LEN | |
395 | is the size of the buffer containing INSN. */ | |
396 | ||
397 | extern int gdb_buffered_insn_length (struct gdbarch *gdbarch, | |
398 | const gdb_byte *insn, int max_len, | |
399 | CORE_ADDR memaddr); | |
400 | ||
65b48a81 PB |
401 | /* Returns GDBARCH's disassembler options. */ |
402 | ||
403 | extern char *get_disassembler_options (struct gdbarch *gdbarch); | |
404 | ||
405 | /* Sets the active gdbarch's disassembler options to OPTIONS. */ | |
406 | ||
e0700ba4 | 407 | extern void set_disassembler_options (const char *options); |
65b48a81 | 408 | |
92df71f0 | 409 | #endif |