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