disasm.c revision 1.7 1 1.1 christos /* Disassemble support for GDB.
2 1.1 christos
3 1.7 christos Copyright (C) 2000-2017 Free Software Foundation, Inc.
4 1.1 christos
5 1.1 christos This file is part of GDB.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 1.1 christos
20 1.1 christos #include "defs.h"
21 1.7 christos #include "arch-utils.h"
22 1.1 christos #include "target.h"
23 1.1 christos #include "value.h"
24 1.1 christos #include "ui-out.h"
25 1.1 christos #include "disasm.h"
26 1.1 christos #include "gdbcore.h"
27 1.7 christos #include "gdbcmd.h"
28 1.1 christos #include "dis-asm.h"
29 1.6 christos #include "source.h"
30 1.7 christos #include "safe-ctype.h"
31 1.7 christos #include <algorithm>
32 1.1 christos
33 1.1 christos /* Disassemble functions.
34 1.1 christos FIXME: We should get rid of all the duplicate code in gdb that does
35 1.1 christos the same thing: disassemble_command() and the gdbtk variation. */
36 1.1 christos
37 1.7 christos /* This variable is used to hold the prospective disassembler_options value
38 1.7 christos which is set by the "set disassembler_options" command. */
39 1.7 christos static char *prospective_options = NULL;
40 1.7 christos
41 1.6 christos /* This structure is used to store line number information for the
42 1.6 christos deprecated /m option.
43 1.6 christos We need a different sort of line table from the normal one cuz we can't
44 1.6 christos depend upon implicit line-end pc's for lines to do the
45 1.6 christos reordering in this function. */
46 1.6 christos
47 1.6 christos struct deprecated_dis_line_entry
48 1.6 christos {
49 1.6 christos int line;
50 1.6 christos CORE_ADDR start_pc;
51 1.6 christos CORE_ADDR end_pc;
52 1.6 christos };
53 1.6 christos
54 1.1 christos /* This Structure is used to store line number information.
55 1.1 christos We need a different sort of line table from the normal one cuz we can't
56 1.1 christos depend upon implicit line-end pc's for lines to do the
57 1.1 christos reordering in this function. */
58 1.1 christos
59 1.1 christos struct dis_line_entry
60 1.1 christos {
61 1.6 christos struct symtab *symtab;
62 1.1 christos int line;
63 1.1 christos };
64 1.1 christos
65 1.6 christos /* Hash function for dis_line_entry. */
66 1.6 christos
67 1.6 christos static hashval_t
68 1.6 christos hash_dis_line_entry (const void *item)
69 1.6 christos {
70 1.6 christos const struct dis_line_entry *dle = (const struct dis_line_entry *) item;
71 1.6 christos
72 1.6 christos return htab_hash_pointer (dle->symtab) + dle->line;
73 1.6 christos }
74 1.6 christos
75 1.6 christos /* Equal function for dis_line_entry. */
76 1.6 christos
77 1.6 christos static int
78 1.6 christos eq_dis_line_entry (const void *item_lhs, const void *item_rhs)
79 1.6 christos {
80 1.6 christos const struct dis_line_entry *lhs = (const struct dis_line_entry *) item_lhs;
81 1.6 christos const struct dis_line_entry *rhs = (const struct dis_line_entry *) item_rhs;
82 1.6 christos
83 1.6 christos return (lhs->symtab == rhs->symtab
84 1.6 christos && lhs->line == rhs->line);
85 1.6 christos }
86 1.6 christos
87 1.6 christos /* Create the table to manage lines for mixed source/disassembly. */
88 1.6 christos
89 1.6 christos static htab_t
90 1.6 christos allocate_dis_line_table (void)
91 1.6 christos {
92 1.6 christos return htab_create_alloc (41,
93 1.6 christos hash_dis_line_entry, eq_dis_line_entry,
94 1.6 christos xfree, xcalloc, xfree);
95 1.6 christos }
96 1.6 christos
97 1.6 christos /* Add a new dis_line_entry containing SYMTAB and LINE to TABLE. */
98 1.6 christos
99 1.6 christos static void
100 1.6 christos add_dis_line_entry (htab_t table, struct symtab *symtab, int line)
101 1.6 christos {
102 1.6 christos void **slot;
103 1.6 christos struct dis_line_entry dle, *dlep;
104 1.6 christos
105 1.6 christos dle.symtab = symtab;
106 1.6 christos dle.line = line;
107 1.6 christos slot = htab_find_slot (table, &dle, INSERT);
108 1.6 christos if (*slot == NULL)
109 1.6 christos {
110 1.6 christos dlep = XNEW (struct dis_line_entry);
111 1.6 christos dlep->symtab = symtab;
112 1.6 christos dlep->line = line;
113 1.6 christos *slot = dlep;
114 1.6 christos }
115 1.6 christos }
116 1.6 christos
117 1.6 christos /* Return non-zero if SYMTAB, LINE are in TABLE. */
118 1.6 christos
119 1.6 christos static int
120 1.6 christos line_has_code_p (htab_t table, struct symtab *symtab, int line)
121 1.6 christos {
122 1.6 christos struct dis_line_entry dle;
123 1.6 christos
124 1.6 christos dle.symtab = symtab;
125 1.6 christos dle.line = line;
126 1.6 christos return htab_find (table, &dle) != NULL;
127 1.6 christos }
128 1.6 christos
129 1.7 christos /* Wrapper of target_read_code. */
130 1.7 christos
131 1.7 christos int
132 1.7 christos gdb_disassembler::dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr,
133 1.7 christos unsigned int len,
134 1.7 christos struct disassemble_info *info)
135 1.1 christos {
136 1.1 christos return target_read_code (memaddr, myaddr, len);
137 1.1 christos }
138 1.1 christos
139 1.7 christos /* Wrapper of memory_error. */
140 1.7 christos
141 1.7 christos void
142 1.7 christos gdb_disassembler::dis_asm_memory_error (int err, bfd_vma memaddr,
143 1.7 christos struct disassemble_info *info)
144 1.1 christos {
145 1.7 christos gdb_disassembler *self
146 1.7 christos = static_cast<gdb_disassembler *>(info->application_data);
147 1.7 christos
148 1.7 christos self->m_err_memaddr = memaddr;
149 1.1 christos }
150 1.1 christos
151 1.7 christos /* Wrapper of print_address. */
152 1.7 christos
153 1.7 christos void
154 1.7 christos gdb_disassembler::dis_asm_print_address (bfd_vma addr,
155 1.7 christos struct disassemble_info *info)
156 1.1 christos {
157 1.7 christos gdb_disassembler *self
158 1.7 christos = static_cast<gdb_disassembler *>(info->application_data);
159 1.1 christos
160 1.7 christos print_address (self->arch (), addr, self->stream ());
161 1.1 christos }
162 1.1 christos
163 1.1 christos static int
164 1.1 christos compare_lines (const void *mle1p, const void *mle2p)
165 1.1 christos {
166 1.6 christos struct deprecated_dis_line_entry *mle1, *mle2;
167 1.1 christos int val;
168 1.1 christos
169 1.6 christos mle1 = (struct deprecated_dis_line_entry *) mle1p;
170 1.6 christos mle2 = (struct deprecated_dis_line_entry *) mle2p;
171 1.1 christos
172 1.1 christos /* End of sequence markers have a line number of 0 but don't want to
173 1.1 christos be sorted to the head of the list, instead sort by PC. */
174 1.1 christos if (mle1->line == 0 || mle2->line == 0)
175 1.1 christos {
176 1.1 christos val = mle1->start_pc - mle2->start_pc;
177 1.1 christos if (val == 0)
178 1.1 christos val = mle1->line - mle2->line;
179 1.1 christos }
180 1.1 christos else
181 1.1 christos {
182 1.1 christos val = mle1->line - mle2->line;
183 1.1 christos if (val == 0)
184 1.1 christos val = mle1->start_pc - mle2->start_pc;
185 1.1 christos }
186 1.1 christos return val;
187 1.1 christos }
188 1.1 christos
189 1.6 christos /* See disasm.h. */
190 1.6 christos
191 1.6 christos int
192 1.7 christos gdb_pretty_print_disassembler::pretty_print_insn (struct ui_out *uiout,
193 1.7 christos const struct disasm_insn *insn,
194 1.7 christos int flags)
195 1.1 christos {
196 1.1 christos /* parts of the symbolic representation of the address */
197 1.1 christos int unmapped;
198 1.1 christos int offset;
199 1.1 christos int line;
200 1.6 christos int size;
201 1.1 christos struct cleanup *ui_out_chain;
202 1.6 christos char *filename = NULL;
203 1.6 christos char *name = NULL;
204 1.6 christos CORE_ADDR pc;
205 1.7 christos struct gdbarch *gdbarch = arch ();
206 1.6 christos
207 1.6 christos ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
208 1.6 christos pc = insn->addr;
209 1.1 christos
210 1.6 christos if (insn->number != 0)
211 1.1 christos {
212 1.7 christos uiout->field_fmt ("insn-number", "%u", insn->number);
213 1.7 christos uiout->text ("\t");
214 1.6 christos }
215 1.1 christos
216 1.6 christos if ((flags & DISASSEMBLY_SPECULATIVE) != 0)
217 1.6 christos {
218 1.6 christos if (insn->is_speculative)
219 1.1 christos {
220 1.7 christos uiout->field_string ("is-speculative", "?");
221 1.6 christos
222 1.6 christos /* The speculative execution indication overwrites the first
223 1.6 christos character of the PC prefix.
224 1.6 christos We assume a PC prefix length of 3 characters. */
225 1.6 christos if ((flags & DISASSEMBLY_OMIT_PC) == 0)
226 1.7 christos uiout->text (pc_prefix (pc) + 1);
227 1.1 christos else
228 1.7 christos uiout->text (" ");
229 1.1 christos }
230 1.6 christos else if ((flags & DISASSEMBLY_OMIT_PC) == 0)
231 1.7 christos uiout->text (pc_prefix (pc));
232 1.6 christos else
233 1.7 christos uiout->text (" ");
234 1.6 christos }
235 1.6 christos else if ((flags & DISASSEMBLY_OMIT_PC) == 0)
236 1.7 christos uiout->text (pc_prefix (pc));
237 1.7 christos uiout->field_core_addr ("address", gdbarch, pc);
238 1.1 christos
239 1.6 christos if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename,
240 1.6 christos &line, &unmapped))
241 1.6 christos {
242 1.6 christos /* We don't care now about line, filename and unmapped. But we might in
243 1.6 christos the future. */
244 1.7 christos uiout->text (" <");
245 1.6 christos if ((flags & DISASSEMBLY_OMIT_FNAME) == 0)
246 1.7 christos uiout->field_string ("func-name", name);
247 1.7 christos uiout->text ("+");
248 1.7 christos uiout->field_int ("offset", offset);
249 1.7 christos uiout->text (">:\t");
250 1.6 christos }
251 1.6 christos else
252 1.7 christos uiout->text (":\t");
253 1.6 christos
254 1.6 christos if (filename != NULL)
255 1.6 christos xfree (filename);
256 1.6 christos if (name != NULL)
257 1.6 christos xfree (name);
258 1.6 christos
259 1.7 christos m_insn_stb.clear ();
260 1.7 christos
261 1.6 christos if (flags & DISASSEMBLY_RAW_INSN)
262 1.6 christos {
263 1.6 christos CORE_ADDR end_pc;
264 1.6 christos bfd_byte data;
265 1.6 christos int err;
266 1.6 christos const char *spacer = "";
267 1.6 christos
268 1.6 christos /* Build the opcodes using a temporary stream so we can
269 1.6 christos write them out in a single go for the MI. */
270 1.7 christos m_opcode_stb.clear ();
271 1.6 christos
272 1.7 christos size = m_di.print_insn (pc);
273 1.6 christos end_pc = pc + size;
274 1.1 christos
275 1.6 christos for (;pc < end_pc; ++pc)
276 1.1 christos {
277 1.7 christos read_code (pc, &data, 1);
278 1.7 christos m_opcode_stb.printf ("%s%02x", spacer, (unsigned) data);
279 1.6 christos spacer = " ";
280 1.1 christos }
281 1.1 christos
282 1.7 christos uiout->field_stream ("opcodes", m_opcode_stb);
283 1.7 christos uiout->text ("\t");
284 1.6 christos }
285 1.6 christos else
286 1.7 christos size = m_di.print_insn (pc);
287 1.6 christos
288 1.7 christos uiout->field_stream ("inst", m_insn_stb);
289 1.6 christos do_cleanups (ui_out_chain);
290 1.7 christos uiout->text ("\n");
291 1.6 christos
292 1.6 christos return size;
293 1.6 christos }
294 1.6 christos
295 1.6 christos static int
296 1.7 christos dump_insns (struct gdbarch *gdbarch,
297 1.7 christos struct ui_out *uiout, CORE_ADDR low, CORE_ADDR high,
298 1.7 christos int how_many, int flags, CORE_ADDR *end_pc)
299 1.6 christos {
300 1.6 christos struct disasm_insn insn;
301 1.6 christos int num_displayed = 0;
302 1.6 christos
303 1.6 christos memset (&insn, 0, sizeof (insn));
304 1.6 christos insn.addr = low;
305 1.6 christos
306 1.7 christos gdb_pretty_print_disassembler disasm (gdbarch);
307 1.7 christos
308 1.6 christos while (insn.addr < high && (how_many < 0 || num_displayed < how_many))
309 1.6 christos {
310 1.6 christos int size;
311 1.6 christos
312 1.7 christos size = disasm.pretty_print_insn (uiout, &insn, flags);
313 1.6 christos if (size <= 0)
314 1.6 christos break;
315 1.6 christos
316 1.6 christos ++num_displayed;
317 1.6 christos insn.addr += size;
318 1.1 christos
319 1.6 christos /* Allow user to bail out with ^C. */
320 1.6 christos QUIT;
321 1.1 christos }
322 1.6 christos
323 1.6 christos if (end_pc != NULL)
324 1.6 christos *end_pc = insn.addr;
325 1.6 christos
326 1.1 christos return num_displayed;
327 1.1 christos }
328 1.1 christos
329 1.1 christos /* The idea here is to present a source-O-centric view of a
330 1.1 christos function to the user. This means that things are presented
331 1.1 christos in source order, with (possibly) out of order assembly
332 1.6 christos immediately following.
333 1.6 christos
334 1.6 christos N.B. This view is deprecated. */
335 1.1 christos
336 1.1 christos static void
337 1.6 christos do_mixed_source_and_assembly_deprecated
338 1.6 christos (struct gdbarch *gdbarch, struct ui_out *uiout,
339 1.7 christos struct symtab *symtab,
340 1.6 christos CORE_ADDR low, CORE_ADDR high,
341 1.7 christos int how_many, int flags)
342 1.1 christos {
343 1.1 christos int newlines = 0;
344 1.6 christos int nlines;
345 1.6 christos struct linetable_entry *le;
346 1.6 christos struct deprecated_dis_line_entry *mle;
347 1.1 christos struct symtab_and_line sal;
348 1.1 christos int i;
349 1.1 christos int out_of_order = 0;
350 1.1 christos int next_line = 0;
351 1.1 christos int num_displayed = 0;
352 1.6 christos print_source_lines_flags psl_flags = 0;
353 1.1 christos struct cleanup *ui_out_chain;
354 1.1 christos struct cleanup *ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
355 1.1 christos struct cleanup *ui_out_list_chain = make_cleanup (null_cleanup, 0);
356 1.1 christos
357 1.6 christos gdb_assert (symtab != NULL && SYMTAB_LINETABLE (symtab) != NULL);
358 1.6 christos
359 1.6 christos nlines = SYMTAB_LINETABLE (symtab)->nitems;
360 1.6 christos le = SYMTAB_LINETABLE (symtab)->item;
361 1.6 christos
362 1.1 christos if (flags & DISASSEMBLY_FILENAME)
363 1.1 christos psl_flags |= PRINT_SOURCE_LINES_FILENAME;
364 1.1 christos
365 1.6 christos mle = (struct deprecated_dis_line_entry *)
366 1.6 christos alloca (nlines * sizeof (struct deprecated_dis_line_entry));
367 1.1 christos
368 1.1 christos /* Copy linetable entries for this function into our data
369 1.1 christos structure, creating end_pc's and setting out_of_order as
370 1.1 christos appropriate. */
371 1.1 christos
372 1.1 christos /* First, skip all the preceding functions. */
373 1.1 christos
374 1.1 christos for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
375 1.1 christos
376 1.1 christos /* Now, copy all entries before the end of this function. */
377 1.1 christos
378 1.1 christos for (; i < nlines - 1 && le[i].pc < high; i++)
379 1.1 christos {
380 1.1 christos if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc)
381 1.1 christos continue; /* Ignore duplicates. */
382 1.1 christos
383 1.1 christos /* Skip any end-of-function markers. */
384 1.1 christos if (le[i].line == 0)
385 1.1 christos continue;
386 1.1 christos
387 1.1 christos mle[newlines].line = le[i].line;
388 1.1 christos if (le[i].line > le[i + 1].line)
389 1.1 christos out_of_order = 1;
390 1.1 christos mle[newlines].start_pc = le[i].pc;
391 1.1 christos mle[newlines].end_pc = le[i + 1].pc;
392 1.1 christos newlines++;
393 1.1 christos }
394 1.1 christos
395 1.1 christos /* If we're on the last line, and it's part of the function,
396 1.1 christos then we need to get the end pc in a special way. */
397 1.1 christos
398 1.1 christos if (i == nlines - 1 && le[i].pc < high)
399 1.1 christos {
400 1.1 christos mle[newlines].line = le[i].line;
401 1.1 christos mle[newlines].start_pc = le[i].pc;
402 1.1 christos sal = find_pc_line (le[i].pc, 0);
403 1.1 christos mle[newlines].end_pc = sal.end;
404 1.1 christos newlines++;
405 1.1 christos }
406 1.1 christos
407 1.6 christos /* Now, sort mle by line #s (and, then by addresses within lines). */
408 1.1 christos
409 1.1 christos if (out_of_order)
410 1.6 christos qsort (mle, newlines, sizeof (struct deprecated_dis_line_entry),
411 1.6 christos compare_lines);
412 1.1 christos
413 1.1 christos /* Now, for each line entry, emit the specified lines (unless
414 1.1 christos they have been emitted before), followed by the assembly code
415 1.1 christos for that line. */
416 1.1 christos
417 1.1 christos ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
418 1.1 christos
419 1.1 christos for (i = 0; i < newlines; i++)
420 1.1 christos {
421 1.1 christos /* Print out everything from next_line to the current line. */
422 1.1 christos if (mle[i].line >= next_line)
423 1.1 christos {
424 1.1 christos if (next_line != 0)
425 1.1 christos {
426 1.1 christos /* Just one line to print. */
427 1.1 christos if (next_line == mle[i].line)
428 1.1 christos {
429 1.1 christos ui_out_tuple_chain
430 1.1 christos = make_cleanup_ui_out_tuple_begin_end (uiout,
431 1.1 christos "src_and_asm_line");
432 1.1 christos print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
433 1.1 christos }
434 1.1 christos else
435 1.1 christos {
436 1.1 christos /* Several source lines w/o asm instructions associated. */
437 1.1 christos for (; next_line < mle[i].line; next_line++)
438 1.1 christos {
439 1.1 christos struct cleanup *ui_out_list_chain_line;
440 1.1 christos struct cleanup *ui_out_tuple_chain_line;
441 1.1 christos
442 1.1 christos ui_out_tuple_chain_line
443 1.1 christos = make_cleanup_ui_out_tuple_begin_end (uiout,
444 1.1 christos "src_and_asm_line");
445 1.1 christos print_source_lines (symtab, next_line, next_line + 1,
446 1.1 christos psl_flags);
447 1.1 christos ui_out_list_chain_line
448 1.1 christos = make_cleanup_ui_out_list_begin_end (uiout,
449 1.1 christos "line_asm_insn");
450 1.1 christos do_cleanups (ui_out_list_chain_line);
451 1.1 christos do_cleanups (ui_out_tuple_chain_line);
452 1.1 christos }
453 1.1 christos /* Print the last line and leave list open for
454 1.1 christos asm instructions to be added. */
455 1.1 christos ui_out_tuple_chain
456 1.1 christos = make_cleanup_ui_out_tuple_begin_end (uiout,
457 1.1 christos "src_and_asm_line");
458 1.1 christos print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
459 1.1 christos }
460 1.1 christos }
461 1.1 christos else
462 1.1 christos {
463 1.1 christos ui_out_tuple_chain
464 1.1 christos = make_cleanup_ui_out_tuple_begin_end (uiout,
465 1.1 christos "src_and_asm_line");
466 1.1 christos print_source_lines (symtab, mle[i].line, mle[i].line + 1, psl_flags);
467 1.1 christos }
468 1.1 christos
469 1.1 christos next_line = mle[i].line + 1;
470 1.1 christos ui_out_list_chain
471 1.1 christos = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
472 1.1 christos }
473 1.1 christos
474 1.7 christos num_displayed += dump_insns (gdbarch, uiout,
475 1.1 christos mle[i].start_pc, mle[i].end_pc,
476 1.7 christos how_many, flags, NULL);
477 1.1 christos
478 1.1 christos /* When we've reached the end of the mle array, or we've seen the last
479 1.1 christos assembly range for this source line, close out the list/tuple. */
480 1.1 christos if (i == (newlines - 1) || mle[i + 1].line > mle[i].line)
481 1.1 christos {
482 1.1 christos do_cleanups (ui_out_list_chain);
483 1.1 christos do_cleanups (ui_out_tuple_chain);
484 1.1 christos ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
485 1.1 christos ui_out_list_chain = make_cleanup (null_cleanup, 0);
486 1.7 christos uiout->text ("\n");
487 1.1 christos }
488 1.1 christos if (how_many >= 0 && num_displayed >= how_many)
489 1.1 christos break;
490 1.1 christos }
491 1.1 christos do_cleanups (ui_out_chain);
492 1.1 christos }
493 1.1 christos
494 1.6 christos /* The idea here is to present a source-O-centric view of a
495 1.6 christos function to the user. This means that things are presented
496 1.6 christos in source order, with (possibly) out of order assembly
497 1.6 christos immediately following. */
498 1.6 christos
499 1.6 christos static void
500 1.7 christos do_mixed_source_and_assembly (struct gdbarch *gdbarch,
501 1.7 christos struct ui_out *uiout,
502 1.6 christos struct symtab *main_symtab,
503 1.6 christos CORE_ADDR low, CORE_ADDR high,
504 1.7 christos int how_many, int flags)
505 1.6 christos {
506 1.6 christos const struct linetable_entry *le, *first_le;
507 1.6 christos int i, nlines;
508 1.6 christos int num_displayed = 0;
509 1.6 christos print_source_lines_flags psl_flags = 0;
510 1.6 christos struct cleanup *ui_out_chain;
511 1.6 christos struct cleanup *ui_out_tuple_chain;
512 1.6 christos struct cleanup *ui_out_list_chain;
513 1.6 christos CORE_ADDR pc;
514 1.6 christos struct symtab *last_symtab;
515 1.6 christos int last_line;
516 1.6 christos
517 1.6 christos gdb_assert (main_symtab != NULL && SYMTAB_LINETABLE (main_symtab) != NULL);
518 1.6 christos
519 1.6 christos /* First pass: collect the list of all source files and lines.
520 1.6 christos We do this so that we can only print lines containing code once.
521 1.6 christos We try to print the source text leading up to the next instruction,
522 1.6 christos but if that text is for code that will be disassembled later, then
523 1.6 christos we'll want to defer printing it until later with its associated code. */
524 1.6 christos
525 1.7 christos htab_up dis_line_table (allocate_dis_line_table ());
526 1.6 christos
527 1.6 christos pc = low;
528 1.6 christos
529 1.6 christos /* The prologue may be empty, but there may still be a line number entry
530 1.6 christos for the opening brace which is distinct from the first line of code.
531 1.6 christos If the prologue has been eliminated find_pc_line may return the source
532 1.6 christos line after the opening brace. We still want to print this opening brace.
533 1.6 christos first_le is used to implement this. */
534 1.6 christos
535 1.6 christos nlines = SYMTAB_LINETABLE (main_symtab)->nitems;
536 1.6 christos le = SYMTAB_LINETABLE (main_symtab)->item;
537 1.6 christos first_le = NULL;
538 1.6 christos
539 1.6 christos /* Skip all the preceding functions. */
540 1.6 christos for (i = 0; i < nlines && le[i].pc < low; i++)
541 1.6 christos continue;
542 1.6 christos
543 1.6 christos if (i < nlines && le[i].pc < high)
544 1.6 christos first_le = &le[i];
545 1.6 christos
546 1.6 christos /* Add lines for every pc value. */
547 1.6 christos while (pc < high)
548 1.6 christos {
549 1.6 christos struct symtab_and_line sal;
550 1.6 christos int length;
551 1.6 christos
552 1.6 christos sal = find_pc_line (pc, 0);
553 1.6 christos length = gdb_insn_length (gdbarch, pc);
554 1.6 christos pc += length;
555 1.6 christos
556 1.6 christos if (sal.symtab != NULL)
557 1.7 christos add_dis_line_entry (dis_line_table.get (), sal.symtab, sal.line);
558 1.6 christos }
559 1.6 christos
560 1.6 christos /* Second pass: print the disassembly.
561 1.6 christos
562 1.6 christos Output format, from an MI perspective:
563 1.6 christos The result is a ui_out list, field name "asm_insns", where elements have
564 1.6 christos name "src_and_asm_line".
565 1.6 christos Each element is a tuple of source line specs (field names line, file,
566 1.6 christos fullname), and field "line_asm_insn" which contains the disassembly.
567 1.6 christos Field "line_asm_insn" is a list of tuples: address, func-name, offset,
568 1.6 christos opcodes, inst.
569 1.6 christos
570 1.6 christos CLI output works on top of this because MI ignores ui_out_text output,
571 1.6 christos which is where we put file name and source line contents output.
572 1.6 christos
573 1.6 christos Cleanup usage:
574 1.6 christos ui_out_chain
575 1.6 christos Handles the outer "asm_insns" list.
576 1.6 christos ui_out_tuple_chain
577 1.6 christos The tuples for each group of consecutive disassemblies.
578 1.6 christos ui_out_list_chain
579 1.6 christos List of consecutive source lines or disassembled insns. */
580 1.6 christos
581 1.6 christos if (flags & DISASSEMBLY_FILENAME)
582 1.6 christos psl_flags |= PRINT_SOURCE_LINES_FILENAME;
583 1.6 christos
584 1.6 christos ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
585 1.6 christos
586 1.6 christos ui_out_tuple_chain = NULL;
587 1.6 christos ui_out_list_chain = NULL;
588 1.6 christos
589 1.6 christos last_symtab = NULL;
590 1.6 christos last_line = 0;
591 1.6 christos pc = low;
592 1.6 christos
593 1.6 christos while (pc < high)
594 1.6 christos {
595 1.6 christos struct symtab_and_line sal;
596 1.6 christos CORE_ADDR end_pc;
597 1.6 christos int start_preceding_line_to_display = 0;
598 1.6 christos int end_preceding_line_to_display = 0;
599 1.6 christos int new_source_line = 0;
600 1.6 christos
601 1.6 christos sal = find_pc_line (pc, 0);
602 1.6 christos
603 1.6 christos if (sal.symtab != last_symtab)
604 1.6 christos {
605 1.6 christos /* New source file. */
606 1.6 christos new_source_line = 1;
607 1.6 christos
608 1.6 christos /* If this is the first line of output, check for any preceding
609 1.6 christos lines. */
610 1.6 christos if (last_line == 0
611 1.6 christos && first_le != NULL
612 1.6 christos && first_le->line < sal.line)
613 1.6 christos {
614 1.6 christos start_preceding_line_to_display = first_le->line;
615 1.6 christos end_preceding_line_to_display = sal.line;
616 1.6 christos }
617 1.6 christos }
618 1.6 christos else
619 1.6 christos {
620 1.6 christos /* Same source file as last time. */
621 1.6 christos if (sal.symtab != NULL)
622 1.6 christos {
623 1.6 christos if (sal.line > last_line + 1 && last_line != 0)
624 1.6 christos {
625 1.6 christos int l;
626 1.6 christos
627 1.6 christos /* Several preceding source lines. Print the trailing ones
628 1.6 christos not associated with code that we'll print later. */
629 1.6 christos for (l = sal.line - 1; l > last_line; --l)
630 1.6 christos {
631 1.7 christos if (line_has_code_p (dis_line_table.get (),
632 1.7 christos sal.symtab, l))
633 1.6 christos break;
634 1.6 christos }
635 1.6 christos if (l < sal.line - 1)
636 1.6 christos {
637 1.6 christos start_preceding_line_to_display = l + 1;
638 1.6 christos end_preceding_line_to_display = sal.line;
639 1.6 christos }
640 1.6 christos }
641 1.6 christos if (sal.line != last_line)
642 1.6 christos new_source_line = 1;
643 1.6 christos else
644 1.6 christos {
645 1.6 christos /* Same source line as last time. This can happen, depending
646 1.6 christos on the debug info. */
647 1.6 christos }
648 1.6 christos }
649 1.6 christos }
650 1.6 christos
651 1.6 christos if (new_source_line)
652 1.6 christos {
653 1.6 christos /* Skip the newline if this is the first instruction. */
654 1.6 christos if (pc > low)
655 1.7 christos uiout->text ("\n");
656 1.6 christos if (ui_out_tuple_chain != NULL)
657 1.6 christos {
658 1.6 christos gdb_assert (ui_out_list_chain != NULL);
659 1.6 christos do_cleanups (ui_out_list_chain);
660 1.6 christos do_cleanups (ui_out_tuple_chain);
661 1.6 christos }
662 1.6 christos if (sal.symtab != last_symtab
663 1.6 christos && !(flags & DISASSEMBLY_FILENAME))
664 1.6 christos {
665 1.6 christos /* Remember MI ignores ui_out_text.
666 1.6 christos We don't have to do anything here for MI because MI
667 1.6 christos output includes the source specs for each line. */
668 1.6 christos if (sal.symtab != NULL)
669 1.6 christos {
670 1.7 christos uiout->text (symtab_to_filename_for_display (sal.symtab));
671 1.6 christos }
672 1.6 christos else
673 1.7 christos uiout->text ("unknown");
674 1.7 christos uiout->text (":\n");
675 1.6 christos }
676 1.6 christos if (start_preceding_line_to_display > 0)
677 1.6 christos {
678 1.6 christos /* Several source lines w/o asm instructions associated.
679 1.6 christos We need to preserve the structure of the output, so output
680 1.6 christos a bunch of line tuples with no asm entries. */
681 1.6 christos int l;
682 1.6 christos struct cleanup *ui_out_list_chain_line;
683 1.6 christos struct cleanup *ui_out_tuple_chain_line;
684 1.6 christos
685 1.6 christos gdb_assert (sal.symtab != NULL);
686 1.6 christos for (l = start_preceding_line_to_display;
687 1.6 christos l < end_preceding_line_to_display;
688 1.6 christos ++l)
689 1.6 christos {
690 1.6 christos ui_out_tuple_chain_line
691 1.6 christos = make_cleanup_ui_out_tuple_begin_end (uiout,
692 1.6 christos "src_and_asm_line");
693 1.6 christos print_source_lines (sal.symtab, l, l + 1, psl_flags);
694 1.6 christos ui_out_list_chain_line
695 1.6 christos = make_cleanup_ui_out_list_begin_end (uiout,
696 1.6 christos "line_asm_insn");
697 1.6 christos do_cleanups (ui_out_list_chain_line);
698 1.6 christos do_cleanups (ui_out_tuple_chain_line);
699 1.6 christos }
700 1.6 christos }
701 1.6 christos ui_out_tuple_chain
702 1.6 christos = make_cleanup_ui_out_tuple_begin_end (uiout, "src_and_asm_line");
703 1.6 christos if (sal.symtab != NULL)
704 1.6 christos print_source_lines (sal.symtab, sal.line, sal.line + 1, psl_flags);
705 1.6 christos else
706 1.7 christos uiout->text (_("--- no source info for this pc ---\n"));
707 1.6 christos ui_out_list_chain
708 1.6 christos = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
709 1.6 christos }
710 1.6 christos else
711 1.6 christos {
712 1.6 christos /* Here we're appending instructions to an existing line.
713 1.6 christos By construction the very first insn will have a symtab
714 1.6 christos and follow the new_source_line path above. */
715 1.6 christos gdb_assert (ui_out_tuple_chain != NULL);
716 1.6 christos gdb_assert (ui_out_list_chain != NULL);
717 1.6 christos }
718 1.6 christos
719 1.6 christos if (sal.end != 0)
720 1.7 christos end_pc = std::min (sal.end, high);
721 1.6 christos else
722 1.6 christos end_pc = pc + 1;
723 1.7 christos num_displayed += dump_insns (gdbarch, uiout, pc, end_pc,
724 1.7 christos how_many, flags, &end_pc);
725 1.6 christos pc = end_pc;
726 1.6 christos
727 1.6 christos if (how_many >= 0 && num_displayed >= how_many)
728 1.6 christos break;
729 1.6 christos
730 1.6 christos last_symtab = sal.symtab;
731 1.6 christos last_line = sal.line;
732 1.6 christos }
733 1.6 christos
734 1.6 christos do_cleanups (ui_out_chain);
735 1.6 christos }
736 1.1 christos
737 1.1 christos static void
738 1.1 christos do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout,
739 1.1 christos CORE_ADDR low, CORE_ADDR high,
740 1.7 christos int how_many, int flags)
741 1.1 christos {
742 1.1 christos struct cleanup *ui_out_chain;
743 1.1 christos
744 1.1 christos ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
745 1.1 christos
746 1.7 christos dump_insns (gdbarch, uiout, low, high, how_many, flags, NULL);
747 1.1 christos
748 1.1 christos do_cleanups (ui_out_chain);
749 1.1 christos }
750 1.1 christos
751 1.1 christos /* Initialize the disassemble info struct ready for the specified
752 1.1 christos stream. */
753 1.1 christos
754 1.1 christos static int ATTRIBUTE_PRINTF (2, 3)
755 1.1 christos fprintf_disasm (void *stream, const char *format, ...)
756 1.1 christos {
757 1.1 christos va_list args;
758 1.1 christos
759 1.1 christos va_start (args, format);
760 1.6 christos vfprintf_filtered ((struct ui_file *) stream, format, args);
761 1.1 christos va_end (args);
762 1.1 christos /* Something non -ve. */
763 1.1 christos return 0;
764 1.1 christos }
765 1.1 christos
766 1.7 christos gdb_disassembler::gdb_disassembler (struct gdbarch *gdbarch,
767 1.7 christos struct ui_file *file,
768 1.7 christos di_read_memory_ftype read_memory_func)
769 1.7 christos : m_gdbarch (gdbarch),
770 1.7 christos m_err_memaddr (0)
771 1.7 christos {
772 1.7 christos init_disassemble_info (&m_di, file, fprintf_disasm);
773 1.7 christos m_di.flavour = bfd_target_unknown_flavour;
774 1.7 christos m_di.memory_error_func = dis_asm_memory_error;
775 1.7 christos m_di.print_address_func = dis_asm_print_address;
776 1.1 christos /* NOTE: cagney/2003-04-28: The original code, from the old Insight
777 1.1 christos disassembler had a local optomization here. By default it would
778 1.1 christos access the executable file, instead of the target memory (there
779 1.1 christos was a growing list of exceptions though). Unfortunately, the
780 1.1 christos heuristic was flawed. Commands like "disassemble &variable"
781 1.1 christos didn't work as they relied on the access going to the target.
782 1.1 christos Further, it has been supperseeded by trust-read-only-sections
783 1.1 christos (although that should be superseeded by target_trust..._p()). */
784 1.7 christos m_di.read_memory_func = read_memory_func;
785 1.7 christos m_di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
786 1.7 christos m_di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
787 1.7 christos m_di.endian = gdbarch_byte_order (gdbarch);
788 1.7 christos m_di.endian_code = gdbarch_byte_order_for_code (gdbarch);
789 1.7 christos m_di.application_data = this;
790 1.7 christos m_di.disassembler_options = get_disassembler_options (gdbarch);
791 1.7 christos disassemble_init_for_target (&m_di);
792 1.7 christos }
793 1.7 christos
794 1.7 christos int
795 1.7 christos gdb_disassembler::print_insn (CORE_ADDR memaddr,
796 1.7 christos int *branch_delay_insns)
797 1.7 christos {
798 1.7 christos m_err_memaddr = 0;
799 1.7 christos
800 1.7 christos int length = gdbarch_print_insn (arch (), memaddr, &m_di);
801 1.7 christos
802 1.7 christos if (length < 0)
803 1.7 christos memory_error (TARGET_XFER_E_IO, m_err_memaddr);
804 1.7 christos
805 1.7 christos if (branch_delay_insns != NULL)
806 1.7 christos {
807 1.7 christos if (m_di.insn_info_valid)
808 1.7 christos *branch_delay_insns = m_di.branch_delay_insns;
809 1.7 christos else
810 1.7 christos *branch_delay_insns = 0;
811 1.7 christos }
812 1.7 christos return length;
813 1.1 christos }
814 1.1 christos
815 1.1 christos void
816 1.1 christos gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
817 1.7 christos int flags, int how_many,
818 1.1 christos CORE_ADDR low, CORE_ADDR high)
819 1.1 christos {
820 1.3 christos struct symtab *symtab;
821 1.1 christos int nlines = -1;
822 1.1 christos
823 1.1 christos /* Assume symtab is valid for whole PC range. */
824 1.3 christos symtab = find_pc_line_symtab (low);
825 1.1 christos
826 1.3 christos if (symtab != NULL && SYMTAB_LINETABLE (symtab) != NULL)
827 1.6 christos nlines = SYMTAB_LINETABLE (symtab)->nitems;
828 1.1 christos
829 1.6 christos if (!(flags & (DISASSEMBLY_SOURCE_DEPRECATED | DISASSEMBLY_SOURCE))
830 1.6 christos || nlines <= 0)
831 1.7 christos do_assembly_only (gdbarch, uiout, low, high, how_many, flags);
832 1.1 christos
833 1.1 christos else if (flags & DISASSEMBLY_SOURCE)
834 1.7 christos do_mixed_source_and_assembly (gdbarch, uiout, symtab, low, high,
835 1.7 christos how_many, flags);
836 1.6 christos
837 1.6 christos else if (flags & DISASSEMBLY_SOURCE_DEPRECATED)
838 1.7 christos do_mixed_source_and_assembly_deprecated (gdbarch, uiout, symtab,
839 1.7 christos low, high, how_many, flags);
840 1.1 christos
841 1.1 christos gdb_flush (gdb_stdout);
842 1.1 christos }
843 1.1 christos
844 1.1 christos /* Print the instruction at address MEMADDR in debugged memory,
845 1.1 christos on STREAM. Returns the length of the instruction, in bytes,
846 1.1 christos and, if requested, the number of branch delay slot instructions. */
847 1.1 christos
848 1.1 christos int
849 1.1 christos gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
850 1.1 christos struct ui_file *stream, int *branch_delay_insns)
851 1.1 christos {
852 1.1 christos
853 1.7 christos gdb_disassembler di (gdbarch, stream);
854 1.1 christos
855 1.7 christos return di.print_insn (memaddr, branch_delay_insns);
856 1.1 christos }
857 1.1 christos
858 1.1 christos /* Return the length in bytes of the instruction at address MEMADDR in
859 1.1 christos debugged memory. */
860 1.1 christos
861 1.1 christos int
862 1.1 christos gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR addr)
863 1.1 christos {
864 1.7 christos return gdb_print_insn (gdbarch, addr, &null_stream, NULL);
865 1.1 christos }
866 1.1 christos
867 1.1 christos /* fprintf-function for gdb_buffered_insn_length. This function is a
868 1.1 christos nop, we don't want to print anything, we just want to compute the
869 1.1 christos length of the insn. */
870 1.1 christos
871 1.1 christos static int ATTRIBUTE_PRINTF (2, 3)
872 1.1 christos gdb_buffered_insn_length_fprintf (void *stream, const char *format, ...)
873 1.1 christos {
874 1.1 christos return 0;
875 1.1 christos }
876 1.1 christos
877 1.1 christos /* Initialize a struct disassemble_info for gdb_buffered_insn_length. */
878 1.1 christos
879 1.1 christos static void
880 1.1 christos gdb_buffered_insn_length_init_dis (struct gdbarch *gdbarch,
881 1.1 christos struct disassemble_info *di,
882 1.1 christos const gdb_byte *insn, int max_len,
883 1.1 christos CORE_ADDR addr)
884 1.1 christos {
885 1.1 christos init_disassemble_info (di, NULL, gdb_buffered_insn_length_fprintf);
886 1.1 christos
887 1.1 christos /* init_disassemble_info installs buffer_read_memory, etc.
888 1.1 christos so we don't need to do that here.
889 1.1 christos The cast is necessary until disassemble_info is const-ified. */
890 1.1 christos di->buffer = (gdb_byte *) insn;
891 1.1 christos di->buffer_length = max_len;
892 1.1 christos di->buffer_vma = addr;
893 1.1 christos
894 1.1 christos di->arch = gdbarch_bfd_arch_info (gdbarch)->arch;
895 1.1 christos di->mach = gdbarch_bfd_arch_info (gdbarch)->mach;
896 1.1 christos di->endian = gdbarch_byte_order (gdbarch);
897 1.1 christos di->endian_code = gdbarch_byte_order_for_code (gdbarch);
898 1.1 christos
899 1.7 christos di->disassembler_options = get_disassembler_options (gdbarch);
900 1.1 christos disassemble_init_for_target (di);
901 1.1 christos }
902 1.1 christos
903 1.1 christos /* Return the length in bytes of INSN. MAX_LEN is the size of the
904 1.1 christos buffer containing INSN. */
905 1.1 christos
906 1.1 christos int
907 1.1 christos gdb_buffered_insn_length (struct gdbarch *gdbarch,
908 1.1 christos const gdb_byte *insn, int max_len, CORE_ADDR addr)
909 1.1 christos {
910 1.1 christos struct disassemble_info di;
911 1.1 christos
912 1.1 christos gdb_buffered_insn_length_init_dis (gdbarch, &di, insn, max_len, addr);
913 1.1 christos
914 1.1 christos return gdbarch_print_insn (gdbarch, addr, &di);
915 1.1 christos }
916 1.7 christos
917 1.7 christos char *
918 1.7 christos get_disassembler_options (struct gdbarch *gdbarch)
919 1.7 christos {
920 1.7 christos char **disassembler_options = gdbarch_disassembler_options (gdbarch);
921 1.7 christos if (disassembler_options == NULL)
922 1.7 christos return NULL;
923 1.7 christos return *disassembler_options;
924 1.7 christos }
925 1.7 christos
926 1.7 christos void
927 1.7 christos set_disassembler_options (char *prospective_options)
928 1.7 christos {
929 1.7 christos struct gdbarch *gdbarch = get_current_arch ();
930 1.7 christos char **disassembler_options = gdbarch_disassembler_options (gdbarch);
931 1.7 christos const disasm_options_t *valid_options;
932 1.7 christos char *options = remove_whitespace_and_extra_commas (prospective_options);
933 1.7 christos const char *opt;
934 1.7 christos
935 1.7 christos /* Allow all architectures, even ones that do not support 'set disassembler',
936 1.7 christos to reset their disassembler options to NULL. */
937 1.7 christos if (options == NULL)
938 1.7 christos {
939 1.7 christos if (disassembler_options != NULL)
940 1.7 christos {
941 1.7 christos free (*disassembler_options);
942 1.7 christos *disassembler_options = NULL;
943 1.7 christos }
944 1.7 christos return;
945 1.7 christos }
946 1.7 christos
947 1.7 christos valid_options = gdbarch_valid_disassembler_options (gdbarch);
948 1.7 christos if (valid_options == NULL)
949 1.7 christos {
950 1.7 christos fprintf_filtered (gdb_stdlog, _("\
951 1.7 christos 'set disassembler-options ...' is not supported on this architecture.\n"));
952 1.7 christos return;
953 1.7 christos }
954 1.7 christos
955 1.7 christos /* Verify we have valid disassembler options. */
956 1.7 christos FOR_EACH_DISASSEMBLER_OPTION (opt, options)
957 1.7 christos {
958 1.7 christos size_t i;
959 1.7 christos for (i = 0; valid_options->name[i] != NULL; i++)
960 1.7 christos if (disassembler_options_cmp (opt, valid_options->name[i]) == 0)
961 1.7 christos break;
962 1.7 christos if (valid_options->name[i] == NULL)
963 1.7 christos {
964 1.7 christos fprintf_filtered (gdb_stdlog,
965 1.7 christos _("Invalid disassembler option value: '%s'.\n"),
966 1.7 christos opt);
967 1.7 christos return;
968 1.7 christos }
969 1.7 christos }
970 1.7 christos
971 1.7 christos free (*disassembler_options);
972 1.7 christos *disassembler_options = xstrdup (options);
973 1.7 christos }
974 1.7 christos
975 1.7 christos static void
976 1.7 christos set_disassembler_options_sfunc (char *args, int from_tty,
977 1.7 christos struct cmd_list_element *c)
978 1.7 christos {
979 1.7 christos set_disassembler_options (prospective_options);
980 1.7 christos }
981 1.7 christos
982 1.7 christos static void
983 1.7 christos show_disassembler_options_sfunc (struct ui_file *file, int from_tty,
984 1.7 christos struct cmd_list_element *c, const char *value)
985 1.7 christos {
986 1.7 christos struct gdbarch *gdbarch = get_current_arch ();
987 1.7 christos const disasm_options_t *valid_options;
988 1.7 christos
989 1.7 christos const char *options = get_disassembler_options (gdbarch);
990 1.7 christos if (options == NULL)
991 1.7 christos options = "";
992 1.7 christos
993 1.7 christos fprintf_filtered (file, _("The current disassembler options are '%s'\n"),
994 1.7 christos options);
995 1.7 christos
996 1.7 christos valid_options = gdbarch_valid_disassembler_options (gdbarch);
997 1.7 christos
998 1.7 christos if (valid_options == NULL)
999 1.7 christos return;
1000 1.7 christos
1001 1.7 christos fprintf_filtered (file, _("\n\
1002 1.7 christos The following disassembler options are supported for use with the\n\
1003 1.7 christos 'set disassembler-options <option>[,<option>...]' command:\n"));
1004 1.7 christos
1005 1.7 christos if (valid_options->description != NULL)
1006 1.7 christos {
1007 1.7 christos size_t i, max_len = 0;
1008 1.7 christos
1009 1.7 christos /* Compute the length of the longest option name. */
1010 1.7 christos for (i = 0; valid_options->name[i] != NULL; i++)
1011 1.7 christos {
1012 1.7 christos size_t len = strlen (valid_options->name[i]);
1013 1.7 christos if (max_len < len)
1014 1.7 christos max_len = len;
1015 1.7 christos }
1016 1.7 christos
1017 1.7 christos for (i = 0, max_len++; valid_options->name[i] != NULL; i++)
1018 1.7 christos {
1019 1.7 christos fprintf_filtered (file, " %s", valid_options->name[i]);
1020 1.7 christos if (valid_options->description[i] != NULL)
1021 1.7 christos fprintf_filtered (file, "%*c %s",
1022 1.7 christos (int)(max_len - strlen (valid_options->name[i])), ' ',
1023 1.7 christos valid_options->description[i]);
1024 1.7 christos fprintf_filtered (file, "\n");
1025 1.7 christos }
1026 1.7 christos }
1027 1.7 christos else
1028 1.7 christos {
1029 1.7 christos size_t i;
1030 1.7 christos fprintf_filtered (file, " ");
1031 1.7 christos for (i = 0; valid_options->name[i] != NULL; i++)
1032 1.7 christos {
1033 1.7 christos fprintf_filtered (file, "%s", valid_options->name[i]);
1034 1.7 christos if (valid_options->name[i + 1] != NULL)
1035 1.7 christos fprintf_filtered (file, ", ");
1036 1.7 christos wrap_here (" ");
1037 1.7 christos }
1038 1.7 christos fprintf_filtered (file, "\n");
1039 1.7 christos }
1040 1.7 christos }
1041 1.7 christos
1042 1.7 christos /* A completion function for "set disassembler". */
1043 1.7 christos
1044 1.7 christos static VEC (char_ptr) *
1045 1.7 christos disassembler_options_completer (struct cmd_list_element *ignore,
1046 1.7 christos const char *text, const char *word)
1047 1.7 christos {
1048 1.7 christos struct gdbarch *gdbarch = get_current_arch ();
1049 1.7 christos const disasm_options_t *opts = gdbarch_valid_disassembler_options (gdbarch);
1050 1.7 christos
1051 1.7 christos if (opts != NULL)
1052 1.7 christos {
1053 1.7 christos /* Only attempt to complete on the last option text. */
1054 1.7 christos const char *separator = strrchr (text, ',');
1055 1.7 christos if (separator != NULL)
1056 1.7 christos text = separator + 1;
1057 1.7 christos text = skip_spaces_const (text);
1058 1.7 christos return complete_on_enum (opts->name, text, word);
1059 1.7 christos }
1060 1.7 christos return NULL;
1061 1.7 christos }
1062 1.7 christos
1063 1.7 christos
1064 1.7 christos /* Initialization code. */
1065 1.7 christos
1066 1.7 christos /* -Wmissing-prototypes */
1067 1.7 christos extern initialize_file_ftype _initialize_disasm;
1068 1.7 christos
1069 1.7 christos void
1070 1.7 christos _initialize_disasm (void)
1071 1.7 christos {
1072 1.7 christos struct cmd_list_element *cmd;
1073 1.7 christos
1074 1.7 christos /* Add the command that controls the disassembler options. */
1075 1.7 christos cmd = add_setshow_string_noescape_cmd ("disassembler-options", no_class,
1076 1.7 christos &prospective_options, _("\
1077 1.7 christos Set the disassembler options.\n\
1078 1.7 christos Usage: set disassembler-options <option>[,<option>...]\n\n\
1079 1.7 christos See: 'show disassembler-options' for valid option values.\n"), _("\
1080 1.7 christos Show the disassembler options."), NULL,
1081 1.7 christos set_disassembler_options_sfunc,
1082 1.7 christos show_disassembler_options_sfunc,
1083 1.7 christos &setlist, &showlist);
1084 1.7 christos set_cmd_completer (cmd, disassembler_options_completer);
1085 1.7 christos }
1086