1 /* Disassemble support for GDB.
3 Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
26 #include "gdb_string.h"
30 /* Disassemble functions.
31 FIXME: We should get rid of all the duplicate code in gdb that does
32 the same thing: disassemble_command() and the gdbtk variation. */
34 /* This Structure is used to store line number information.
35 We need a different sort of line table from the normal one cuz we can't
36 depend upon implicit line-end pc's for lines to do the
37 reordering in this function. */
46 /* This variable determines where memory used for disassembly is read from. */
47 int gdb_disassemble_from_exec = -1;
49 /* This is the memory_read_func for gdb_disassemble when we are
50 disassembling from the exec file. */
52 gdb_dis_asm_read_memory (bfd_vma memaddr, bfd_byte * myaddr,
53 unsigned int len, disassemble_info * info)
55 extern struct target_ops exec_ops;
59 res = xfer_memory (memaddr, myaddr, len, 0, 0, &exec_ops);
70 compare_lines (const void *mle1p, const void *mle2p)
72 struct dis_line_entry *mle1, *mle2;
75 mle1 = (struct dis_line_entry *) mle1p;
76 mle2 = (struct dis_line_entry *) mle2p;
78 val = mle1->line - mle2->line;
83 return mle1->start_pc - mle2->start_pc;
87 dump_insns (struct ui_out *uiout, disassemble_info * di,
88 CORE_ADDR low, CORE_ADDR high,
89 int how_many, struct ui_stream *stb)
91 int num_displayed = 0;
94 /* parts of the symbolic representation of the address */
98 struct cleanup *ui_out_chain;
100 for (pc = low; pc < high;)
102 char *filename = NULL;
108 if (num_displayed >= how_many)
113 ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
114 ui_out_field_core_addr (uiout, "address", pc);
116 if (!build_address_symbolic (pc, 0, &name, &offset, &filename,
119 /* We don't care now about line, filename and
120 unmapped. But we might in the future. */
121 ui_out_text (uiout, " <");
122 ui_out_field_string (uiout, "func-name", name);
123 ui_out_text (uiout, "+");
124 ui_out_field_int (uiout, "offset", offset);
125 ui_out_text (uiout, ">:\t");
127 if (filename != NULL)
132 ui_file_rewind (stb->stream);
133 pc += TARGET_PRINT_INSN (pc, di);
134 ui_out_field_stream (uiout, "inst", stb);
135 ui_file_rewind (stb->stream);
136 do_cleanups (ui_out_chain);
137 ui_out_text (uiout, "\n");
139 return num_displayed;
142 /* The idea here is to present a source-O-centric view of a
143 function to the user. This means that things are presented
144 in source order, with (possibly) out of order assembly
145 immediately following. */
147 do_mixed_source_and_assembly (struct ui_out *uiout,
148 struct disassemble_info *di, int nlines,
149 struct linetable_entry *le,
150 CORE_ADDR low, CORE_ADDR high,
151 struct symtab *symtab,
152 int how_many, struct ui_stream *stb)
155 struct dis_line_entry *mle;
156 struct symtab_and_line sal;
158 int out_of_order = 0;
161 int num_displayed = 0;
162 struct cleanup *ui_out_chain;
164 mle = (struct dis_line_entry *) alloca (nlines
165 * sizeof (struct dis_line_entry));
167 /* Copy linetable entries for this function into our data
168 structure, creating end_pc's and setting out_of_order as
171 /* First, skip all the preceding functions. */
173 for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
175 /* Now, copy all entries before the end of this function. */
177 for (; i < nlines - 1 && le[i].pc < high; i++)
179 if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc)
180 continue; /* Ignore duplicates */
182 /* Skip any end-of-function markers. */
186 mle[newlines].line = le[i].line;
187 if (le[i].line > le[i + 1].line)
189 mle[newlines].start_pc = le[i].pc;
190 mle[newlines].end_pc = le[i + 1].pc;
194 /* If we're on the last line, and it's part of the function,
195 then we need to get the end pc in a special way. */
197 if (i == nlines - 1 && le[i].pc < high)
199 mle[newlines].line = le[i].line;
200 mle[newlines].start_pc = le[i].pc;
201 sal = find_pc_line (le[i].pc, 0);
202 mle[newlines].end_pc = sal.end;
206 /* Now, sort mle by line #s (and, then by addresses within
210 qsort (mle, newlines, sizeof (struct dis_line_entry), compare_lines);
212 /* Now, for each line entry, emit the specified lines (unless
213 they have been emitted before), followed by the assembly code
216 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
218 for (i = 0; i < newlines; i++)
220 struct cleanup *ui_out_tuple_chain = NULL;
221 struct cleanup *ui_out_list_chain = NULL;
224 /* Print out everything from next_line to the current line. */
225 if (mle[i].line >= next_line)
229 /* Just one line to print. */
230 if (next_line == mle[i].line)
233 = make_cleanup_ui_out_tuple_begin_end (uiout,
235 print_source_lines (symtab, next_line, mle[i].line + 1, 0);
239 /* Several source lines w/o asm instructions associated. */
240 for (; next_line < mle[i].line; next_line++)
242 struct cleanup *ui_out_list_chain_line;
243 struct cleanup *ui_out_tuple_chain_line;
245 ui_out_tuple_chain_line
246 = make_cleanup_ui_out_tuple_begin_end (uiout,
248 print_source_lines (symtab, next_line, next_line + 1,
250 ui_out_list_chain_line
251 = make_cleanup_ui_out_list_begin_end (uiout,
253 do_cleanups (ui_out_list_chain_line);
254 do_cleanups (ui_out_tuple_chain_line);
256 /* Print the last line and leave list open for
257 asm instructions to be added. */
259 = make_cleanup_ui_out_tuple_begin_end (uiout,
261 print_source_lines (symtab, next_line, mle[i].line + 1, 0);
267 = make_cleanup_ui_out_tuple_begin_end (uiout, "src_and_asm_line");
268 print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0);
271 next_line = mle[i].line + 1;
273 = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
274 /* Don't close the list if the lines are not in order. */
275 if (i < (newlines - 1) && mle[i + 1].line <= mle[i].line)
279 num_displayed += dump_insns (uiout, di, mle[i].start_pc, mle[i].end_pc,
283 do_cleanups (ui_out_list_chain);
284 do_cleanups (ui_out_tuple_chain);
285 ui_out_text (uiout, "\n");
289 if (num_displayed >= how_many)
292 do_cleanups (ui_out_chain);
297 do_assembly_only (struct ui_out *uiout, disassemble_info * di,
298 CORE_ADDR low, CORE_ADDR high,
299 int how_many, struct ui_stream *stb)
301 int num_displayed = 0;
302 struct cleanup *ui_out_chain;
304 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
306 num_displayed = dump_insns (uiout, di, low, high, how_many, stb);
308 do_cleanups (ui_out_chain);
312 gdb_disassembly (struct ui_out *uiout,
315 int mixed_source_and_assembly,
316 int how_many, CORE_ADDR low, CORE_ADDR high)
318 static disassemble_info di;
319 static int di_initialized;
320 /* To collect the instruction outputted from opcodes. */
321 static struct ui_stream *stb = NULL;
322 struct symtab *symtab = NULL;
323 struct linetable_entry *le = NULL;
328 /* We don't add a cleanup for this, because the allocation of
329 the stream is done once only for each gdb run, and we need to
330 keep it around until the end. Hopefully there won't be any
331 errors in the init code below, that make this function bail
333 stb = ui_out_stream_new (uiout);
334 INIT_DISASSEMBLE_INFO_NO_ARCH (di, stb->stream,
335 (fprintf_ftype) fprintf_unfiltered);
336 di.flavour = bfd_target_unknown_flavour;
337 di.memory_error_func = dis_asm_memory_error;
338 di.print_address_func = dis_asm_print_address;
342 di.mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
343 di.endian = gdbarch_byte_order (current_gdbarch);
345 /* If gdb_disassemble_from_exec == -1, then we use the following heuristic to
346 determine whether or not to do disassembly from target memory or from the
349 If we're debugging a local process, read target memory, instead of the
350 exec file. This makes disassembly of functions in shared libs work
351 correctly. Also, read target memory if we are debugging native threads.
353 Else, we're debugging a remote process, and should disassemble from the
354 exec file for speed. However, this is no good if the target modifies its
355 code (for relocation, or whatever). */
357 if (gdb_disassemble_from_exec == -1)
359 if (strcmp (target_shortname, "child") == 0
360 || strcmp (target_shortname, "procfs") == 0
361 || strcmp (target_shortname, "vxprocess") == 0
362 || strcmp (target_shortname, "core") == 0
363 || strstr (target_shortname, "-thread") != NULL)
364 gdb_disassemble_from_exec = 0; /* It's a child process, read inferior mem */
366 gdb_disassemble_from_exec = 1; /* It's remote, read the exec file */
369 if (gdb_disassemble_from_exec)
370 di.read_memory_func = gdb_dis_asm_read_memory;
372 di.read_memory_func = dis_asm_read_memory;
374 /* Assume symtab is valid for whole PC range */
375 symtab = find_pc_symtab (low);
377 if (symtab != NULL && symtab->linetable != NULL)
379 /* Convert the linetable to a bunch of my_line_entry's. */
380 le = symtab->linetable->item;
381 nlines = symtab->linetable->nitems;
384 if (!mixed_source_and_assembly || nlines <= 0
385 || symtab == NULL || symtab->linetable == NULL)
386 do_assembly_only (uiout, &di, low, high, how_many, stb);
388 else if (mixed_source_and_assembly)
389 do_mixed_source_and_assembly (uiout, &di, nlines, le, low,
390 high, symtab, how_many, stb);
392 gdb_flush (gdb_stdout);