e69458d6e56d2468587fb4dbbd415d948bdd7e0b
[platform/upstream/binutils.git] / gdb / disasm.c
1 /* Disassemble support for GDB.
2    Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
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
8    the Free Software Foundation; either version 2 of the License, or
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
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place - Suite 330,
19    Boston, MA 02111-1307, USA.  */
20
21 #include "defs.h"
22 #include "target.h"
23 #include "value.h"
24 #include "ui-out.h"
25 #include "gdb_string.h"
26
27 #include "disasm.h"
28
29 /* Disassemble functions.
30    FIXME: We should get rid of all the duplicate code in gdb that does
31    the same thing: disassemble_command() and the gdbtk variation. */
32
33 /* This Structure is used to store line number information.
34    We need a different sort of line table from the normal one cuz we can't
35    depend upon implicit line-end pc's for lines to do the
36    reordering in this function.  */
37
38 struct dis_line_entry
39 {
40   int line;
41   CORE_ADDR start_pc;
42   CORE_ADDR end_pc;
43 };
44
45 /* This variable determines where memory used for disassembly is read from. */
46 int gdb_disassemble_from_exec = -1;
47
48 /* This is the memory_read_func for gdb_disassemble when we are
49    disassembling from the exec file. */
50 static int
51 gdb_dis_asm_read_memory (bfd_vma memaddr, bfd_byte * myaddr,
52                          unsigned int len, disassemble_info * info)
53 {
54   extern struct target_ops exec_ops;
55   int res;
56
57   errno = 0;
58   res = xfer_memory (memaddr, myaddr, len, 0, 0, &exec_ops);
59
60   if (res == len)
61     return 0;
62   else if (errno == 0)
63     return EIO;
64   else
65     return errno;
66 }
67
68 static int
69 compare_lines (const void *mle1p, const void *mle2p)
70 {
71   struct dis_line_entry *mle1, *mle2;
72   int val;
73
74   mle1 = (struct dis_line_entry *) mle1p;
75   mle2 = (struct dis_line_entry *) mle2p;
76
77   val = mle1->line - mle2->line;
78
79   if (val != 0)
80     return val;
81
82   return mle1->start_pc - mle2->start_pc;
83 }
84
85 static int
86 dump_insns (struct ui_out *uiout, disassemble_info * di,
87             CORE_ADDR low, CORE_ADDR high,
88             int how_many, struct ui_stream *stb)
89 {
90   int num_displayed = 0;
91   CORE_ADDR pc;
92
93   /* parts of the symbolic representation of the address */
94   int unmapped;
95   char *filename = NULL;
96   char *name = NULL;
97   int offset;
98   int line;
99
100   for (pc = low; pc < high;)
101     {
102       QUIT;
103       if (how_many >= 0)
104         {
105           if (num_displayed >= how_many)
106             break;
107           else
108             num_displayed++;
109         }
110       ui_out_tuple_begin (uiout, NULL);
111       ui_out_field_core_addr (uiout, "address", pc);
112
113       if (!build_address_symbolic (pc, 0, &name, &offset, &filename,
114                                    &line, &unmapped))
115         {
116           /* We don't care now about line, filename and
117              unmapped. But we might in the future. */
118           ui_out_text (uiout, " <");
119           ui_out_field_string (uiout, "func-name", name);
120           ui_out_text (uiout, "+");
121           ui_out_field_int (uiout, "offset", offset);
122           ui_out_text (uiout, ">:\t");
123         }
124       if (filename != NULL)
125         xfree (filename);
126       if (name != NULL)
127         xfree (name);
128
129       ui_file_rewind (stb->stream);
130       pc += TARGET_PRINT_INSN (pc, di);
131       ui_out_field_stream (uiout, "inst", stb);
132       ui_file_rewind (stb->stream);
133       ui_out_tuple_end (uiout);
134       ui_out_text (uiout, "\n");
135     }
136   return num_displayed;
137 }
138
139 /* The idea here is to present a source-O-centric view of a
140    function to the user.  This means that things are presented
141    in source order, with (possibly) out of order assembly
142    immediately following.  */
143 static void
144 do_mixed_source_and_assembly (struct ui_out *uiout,
145                               struct disassemble_info *di, int nlines,
146                               struct linetable_entry *le,
147                               CORE_ADDR low, CORE_ADDR high,
148                               struct symtab *symtab,
149                               int how_many, struct ui_stream *stb)
150 {
151   int newlines = 0;
152   struct dis_line_entry *mle;
153   struct symtab_and_line sal;
154   int i;
155   int out_of_order = 0;
156   int next_line = 0;
157   CORE_ADDR pc;
158   int num_displayed = 0;
159
160   mle = (struct dis_line_entry *) alloca (nlines
161                                           * sizeof (struct dis_line_entry));
162
163   /* Copy linetable entries for this function into our data
164      structure, creating end_pc's and setting out_of_order as
165      appropriate.  */
166
167   /* First, skip all the preceding functions.  */
168
169   for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
170
171   /* Now, copy all entries before the end of this function.  */
172
173   for (; i < nlines - 1 && le[i].pc < high; i++)
174     {
175       if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc)
176         continue;               /* Ignore duplicates */
177
178       /* Skip any end-of-function markers.  */
179       if (le[i].line == 0)
180         continue;
181
182       mle[newlines].line = le[i].line;
183       if (le[i].line > le[i + 1].line)
184         out_of_order = 1;
185       mle[newlines].start_pc = le[i].pc;
186       mle[newlines].end_pc = le[i + 1].pc;
187       newlines++;
188     }
189
190   /* If we're on the last line, and it's part of the function,
191      then we need to get the end pc in a special way.  */
192
193   if (i == nlines - 1 && le[i].pc < high)
194     {
195       mle[newlines].line = le[i].line;
196       mle[newlines].start_pc = le[i].pc;
197       sal = find_pc_line (le[i].pc, 0);
198       mle[newlines].end_pc = sal.end;
199       newlines++;
200     }
201
202   /* Now, sort mle by line #s (and, then by addresses within
203      lines). */
204
205   if (out_of_order)
206     qsort (mle, newlines, sizeof (struct dis_line_entry), compare_lines);
207
208   /* Now, for each line entry, emit the specified lines (unless
209      they have been emitted before), followed by the assembly code
210      for that line.  */
211
212   ui_out_list_begin (uiout, "asm_insns");
213
214   for (i = 0; i < newlines; i++)
215     {
216       int close_list = 1;
217       /* Print out everything from next_line to the current line.  */
218       if (mle[i].line >= next_line)
219         {
220           if (next_line != 0)
221             {
222               /* Just one line to print. */
223               if (next_line == mle[i].line)
224                 {
225                   ui_out_tuple_begin (uiout, "src_and_asm_line");
226                   print_source_lines (symtab, next_line, mle[i].line + 1, 0);
227                 }
228               else
229                 {
230                   /* Several source lines w/o asm instructions associated. */
231                   for (; next_line < mle[i].line; next_line++)
232                     {
233                       ui_out_tuple_begin (uiout, "src_and_asm_line");
234                       print_source_lines (symtab, next_line, next_line + 1,
235                                           0);
236                       ui_out_list_begin (uiout, "line_asm_insn");
237                       ui_out_list_end (uiout);
238                       ui_out_tuple_end (uiout);
239                     }
240                   /* Print the last line and leave list open for
241                      asm instructions to be added. */
242                   ui_out_tuple_begin (uiout, "src_and_asm_line");
243                   print_source_lines (symtab, next_line, mle[i].line + 1, 0);
244                 }
245             }
246           else
247             {
248               ui_out_tuple_begin (uiout, "src_and_asm_line");
249               print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0);
250             }
251
252           next_line = mle[i].line + 1;
253           ui_out_list_begin (uiout, "line_asm_insn");
254           /* Don't close the list if the lines are not in order. */
255           if (i < (newlines - 1) && mle[i + 1].line <= mle[i].line)
256             close_list = 0;
257         }
258
259       num_displayed += dump_insns (uiout, di, mle[i].start_pc, mle[i].end_pc,
260                                    how_many, stb);
261       if (close_list)
262         {
263           ui_out_list_end (uiout);
264           ui_out_tuple_end (uiout);
265           ui_out_text (uiout, "\n");
266           close_list = 0;
267         }
268       if (how_many >= 0)
269         if (num_displayed >= how_many)
270           break;
271     }
272   ui_out_list_end (uiout);
273 }
274
275
276 static void
277 do_assembly_only (struct ui_out *uiout, disassemble_info * di,
278                   CORE_ADDR low, CORE_ADDR high,
279                   int how_many, struct ui_stream *stb)
280 {
281   int num_displayed = 0;
282
283   ui_out_list_begin (uiout, "asm_insns");
284
285   num_displayed = dump_insns (uiout, di, low, high, how_many, stb);
286
287   ui_out_list_end (uiout);
288 }
289
290 void
291 gdb_disassembly (struct ui_out *uiout,
292                 char *file_string,
293                 int line_num,
294                 int mixed_source_and_assembly,
295                 int how_many, CORE_ADDR low, CORE_ADDR high)
296 {
297   static disassemble_info di;
298   static int di_initialized;
299   /* To collect the instruction outputted from opcodes. */
300   static struct ui_stream *stb = NULL;
301   struct symtab *symtab = NULL;
302   struct linetable_entry *le = NULL;
303   int nlines = -1;
304
305   if (!di_initialized)
306     {
307       /* We don't add a cleanup for this, because the allocation of
308          the stream is done once only for each gdb run, and we need to
309          keep it around until the end. Hopefully there won't be any
310          errors in the init code below, that make this function bail
311          out. */
312       stb = ui_out_stream_new (uiout);
313       INIT_DISASSEMBLE_INFO_NO_ARCH (di, stb->stream,
314                                      (fprintf_ftype) fprintf_unfiltered);
315       di.flavour = bfd_target_unknown_flavour;
316       di.memory_error_func = dis_asm_memory_error;
317       di.print_address_func = dis_asm_print_address;
318       di_initialized = 1;
319     }
320
321   di.mach = TARGET_PRINT_INSN_INFO->mach;
322   if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
323     di.endian = BFD_ENDIAN_BIG;
324   else
325     di.endian = BFD_ENDIAN_LITTLE;
326
327   /* If gdb_disassemble_from_exec == -1, then we use the following heuristic to
328      determine whether or not to do disassembly from target memory or from the
329      exec file:
330
331      If we're debugging a local process, read target memory, instead of the
332      exec file.  This makes disassembly of functions in shared libs work
333      correctly.  Also, read target memory if we are debugging native threads.
334
335      Else, we're debugging a remote process, and should disassemble from the
336      exec file for speed.  However, this is no good if the target modifies its
337      code (for relocation, or whatever).  */
338
339   if (gdb_disassemble_from_exec == -1)
340     {
341       if (strcmp (target_shortname, "child") == 0
342           || strcmp (target_shortname, "procfs") == 0
343           || strcmp (target_shortname, "vxprocess") == 0
344           || strstr (target_shortname, "-threads") != NULL)
345         gdb_disassemble_from_exec = 0;  /* It's a child process, read inferior mem */
346       else
347         gdb_disassemble_from_exec = 1;  /* It's remote, read the exec file */
348     }
349
350   if (gdb_disassemble_from_exec)
351     di.read_memory_func = gdb_dis_asm_read_memory;
352   else
353     di.read_memory_func = dis_asm_read_memory;
354
355   /* Assume symtab is valid for whole PC range */
356   symtab = find_pc_symtab (low);
357
358   if (symtab != NULL && symtab->linetable != NULL)
359     {
360       /* Convert the linetable to a bunch of my_line_entry's.  */
361       le = symtab->linetable->item;
362       nlines = symtab->linetable->nitems;
363     }
364
365   if (!mixed_source_and_assembly || nlines <= 0
366       || symtab == NULL || symtab->linetable == NULL)
367     do_assembly_only (uiout, &di, low, high, how_many, stb);
368
369   else if (mixed_source_and_assembly)
370     do_mixed_source_and_assembly (uiout, &di, nlines, le, low,
371                                   high, symtab, how_many, stb);
372
373   gdb_flush (gdb_stdout);
374 }