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