]> Git Repo - binutils.git/blob - gdb/mi/mi-cmd-disas.c
Replace free() with xfree().
[binutils.git] / gdb / mi / mi-cmd-disas.c
1 /* MI Command Set - disassemble commands.
2    Copyright (C) 2000, Free Software Foundation, Inc.
3    Contributed by Cygnus Solutions (a Red Hat company).
4
5    This file is part of GDB.
6
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.
11
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.
16
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.  */
21
22 #include "defs.h"
23 #include "target.h"
24 #include "value.h"
25 #include "mi-cmds.h"
26 #include "mi-getopt.h"
27 #include "ui-out.h"
28
29 static int gdb_dis_asm_read_memory (bfd_vma memaddr, bfd_byte * myaddr, unsigned int len,
30                                     disassemble_info * info);
31 static int compare_lines (const PTR mle1p, const PTR mle2p);
32
33 /* Disassemble functions. FIXME: these do not really belong here. We
34    should get rid of all the duplicate code in gdb that does the same
35    thing: disassemble_command() and the gdbtk variation. */
36
37 /* This Structure is used in mi_cmd_disassemble.
38    We need a different sort of line table from the normal one cuz we can't
39    depend upon implicit line-end pc's for lines to do the
40    reordering in this function.  */
41
42 struct dis_line_entry
43   {
44     int line;
45     CORE_ADDR start_pc;
46     CORE_ADDR end_pc;
47   };
48
49 /* This variable determines where memory used for disassembly is read from. */
50 int gdb_disassemble_from_exec = -1;
51
52 /* This is the memory_read_func for gdb_disassemble when we are
53    disassembling from the exec file. */
54 static int
55 gdb_dis_asm_read_memory (bfd_vma memaddr, bfd_byte * myaddr,
56                          unsigned int len, disassemble_info * info)
57 {
58   extern struct target_ops exec_ops;
59   int res;
60
61   errno = 0;
62   res = xfer_memory (memaddr, myaddr, len, 0, &exec_ops);
63
64   if (res == len)
65     return 0;
66   else if (errno == 0)
67     return EIO;
68   else
69     return errno;
70 }
71
72 static int
73 compare_lines (const PTR mle1p, const PTR mle2p)
74 {
75   struct dis_line_entry *mle1, *mle2;
76   int val;
77
78   mle1 = (struct dis_line_entry *) mle1p;
79   mle2 = (struct dis_line_entry *) mle2p;
80
81   val = mle1->line - mle2->line;
82
83   if (val != 0)
84     return val;
85
86   return mle1->start_pc - mle2->start_pc;
87 }
88
89 /* The arguments to be passed on the command line and parsed here are:
90
91    either:
92
93    START-ADDRESS: address to start the disassembly at.
94    END-ADDRESS: address to end the disassembly at.
95
96    or:
97
98    FILENAME: The name of the file where we want disassemble from.
99    LINE: The line around which we want to disassemble. It will
100    disassemble the function that contins that line.
101    HOW_MANY: Number of disassembly lines to display. In mixed mode, it
102    is the number of disassembly lines only, not counting the source
103    lines.  
104
105    always required:
106
107    MODE: 0 or 1 for disassembly only, or mixed source and disassembly,
108    respectively. */
109
110 enum mi_cmd_result
111 mi_cmd_disassemble (char *command, char **argv, int argc)
112 {
113   CORE_ADDR pc;
114   CORE_ADDR start;
115   CORE_ADDR low = 0;
116   CORE_ADDR high = 0;
117
118   int how_many = -1;
119   int mixed_source_and_assembly;
120   int num_displayed;
121   int line_num;
122
123   char *file_string;
124   static disassemble_info di;
125   static int di_initialized;
126
127   struct symtab *s;
128
129   /* To collect the instruction outputted from opcodes. */
130   static struct ui_stream *stb = NULL;
131
132   /* parts of the symbolic representation of the address */
133   int line;
134   int offset;
135   int unmapped;
136   char *filename = NULL;
137   char *name = NULL;
138
139   /* Which options have we processed? */
140   int file_seen = 0;
141   int line_seen = 0;
142   int num_seen = 0;
143   int start_seen = 0;
144   int end_seen = 0;
145
146   /* Options processing stuff. */
147   int optind = 0;
148   char *optarg;
149   enum opt
150     {
151       FILE_OPT, LINE_OPT, NUM_OPT, START_OPT, END_OPT
152     };
153   static struct mi_opt opts[] =
154   {
155     {"f", FILE_OPT, 1},
156     {"l", LINE_OPT, 1},
157     {"n", NUM_OPT, 1},
158     {"s", START_OPT, 1},
159     {"e", END_OPT, 1},
160     0
161   };
162
163   /* Get the options with their arguments. Keep track of what we
164      encountered. */
165   while (1)
166     {
167       int opt = mi_getopt ("mi_cmd_disassemble", argc, argv, opts,
168                            &optind, &optarg);
169       if (opt < 0)
170         break;
171       switch ((enum opt) opt)
172         {
173         case FILE_OPT:
174           file_string = xstrdup (optarg);
175           file_seen = 1;
176           break;
177         case LINE_OPT:
178           line_num = atoi (optarg);
179           line_seen = 1;
180           break;
181         case NUM_OPT:
182           how_many = atoi (optarg);
183           num_seen = 1;
184           break;
185         case START_OPT:
186           low = parse_and_eval_address (optarg);
187           start_seen = 1;
188           break;
189         case END_OPT:
190           high = parse_and_eval_address (optarg);
191           end_seen = 1;
192           break;
193         }
194     }
195   argv += optind;
196   argc -= optind;
197
198   /* Allow only filename + linenum (with how_many which is not
199      required) OR start_addr + and_addr */
200
201   if (!((line_seen && file_seen && num_seen && !start_seen && !end_seen)
202         || (line_seen && file_seen && !num_seen && !start_seen && !end_seen)
203       || (!line_seen && !file_seen && !num_seen && start_seen && end_seen)))
204     error ("mi_cmd_disassemble: Usage: ( [-f filename -l linenum [-n howmany]] | [-s startaddr -e endaddr]) [--] mixed_mode.");
205
206   if (argc != 1)
207     error ("mi_cmd_disassemble: Usage: [-f filename -l linenum [-n howmany]] [-s startaddr -e endaddr] [--] mixed_mode.");
208
209   mixed_source_and_assembly = atoi (argv[0]);
210   if ((mixed_source_and_assembly != 0) && (mixed_source_and_assembly != 1))
211     error ("mi_cmd_disassemble: Mixed_mode argument must be 0 or 1.");
212
213   /* We must get the function beginning and end where line_num is
214      contained. */
215
216   if (line_seen && file_seen)
217     {
218       s = lookup_symtab (file_string);
219       if (s == NULL)
220         error ("mi_cmd_disassemble: Invalid filename.");
221       if (!find_line_pc (s, line_num, &start))
222         error ("mi_cmd_disassemble: Invalid line number");
223       if (find_pc_partial_function (start, NULL, &low, &high) == 0)
224         error ("mi_cmd_disassemble: No function contains specified address");
225     }
226
227   if (!di_initialized)
228     {
229       /* We don't add a cleanup for this, because the allocation of
230          the stream is done once only for each gdb run, and we need to
231          keep it around until the end. Hopefully there won't be any
232          errors in the init code below, that make this function bail
233          out. */
234       stb = ui_out_stream_new (uiout);
235       INIT_DISASSEMBLE_INFO_NO_ARCH (di, stb->stream,
236                                      (fprintf_ftype) fprintf_unfiltered);
237       di.flavour = bfd_target_unknown_flavour;
238       di.memory_error_func = dis_asm_memory_error;
239       di.print_address_func = dis_asm_print_address;
240       di_initialized = 1;
241     }
242
243   di.mach = TARGET_PRINT_INSN_INFO->mach;
244   if (TARGET_BYTE_ORDER == BIG_ENDIAN)
245     di.endian = BFD_ENDIAN_BIG;
246   else
247     di.endian = BFD_ENDIAN_LITTLE;
248
249   /* If gdb_disassemble_from_exec == -1, then we use the following heuristic to
250      determine whether or not to do disassembly from target memory or from the
251      exec file:
252
253      If we're debugging a local process, read target memory, instead of the
254      exec file.  This makes disassembly of functions in shared libs work
255      correctly.  Also, read target memory if we are debugging native threads.
256
257      Else, we're debugging a remote process, and should disassemble from the
258      exec file for speed.  However, this is no good if the target modifies its
259      code (for relocation, or whatever).
260    */
261
262   if (gdb_disassemble_from_exec == -1)
263     {
264       if (strcmp (target_shortname, "child") == 0
265           || strcmp (target_shortname, "procfs") == 0
266           || strcmp (target_shortname, "vxprocess") == 0
267           || strstr (target_shortname, "-threads") != NULL)
268         gdb_disassemble_from_exec = 0;  /* It's a child process, read inferior mem */
269       else
270         gdb_disassemble_from_exec = 1;  /* It's remote, read the exec file */
271     }
272
273   if (gdb_disassemble_from_exec)
274     di.read_memory_func = gdb_dis_asm_read_memory;
275   else
276     di.read_memory_func = dis_asm_read_memory;
277
278   /* If just doing straight assembly, all we need to do is disassemble
279      everything between low and high.  If doing mixed source/assembly,
280      we've got a totally different path to follow.  */
281
282   if (mixed_source_and_assembly)
283     {
284       /* Come here for mixed source/assembly */
285       /* The idea here is to present a source-O-centric view of a
286          function to the user.  This means that things are presented
287          in source order, with (possibly) out of order assembly
288          immediately following.  */
289       struct symtab *symtab;
290       struct linetable_entry *le;
291       int nlines;
292       int newlines;
293       struct dis_line_entry *mle;
294       struct symtab_and_line sal;
295       int i;
296       int out_of_order;
297       int next_line;
298
299       /* Assume symtab is valid for whole PC range */
300       symtab = find_pc_symtab (low);
301
302       if (!symtab || !symtab->linetable)
303         goto assembly_only;
304
305       /* First, convert the linetable to a bunch of my_line_entry's.  */
306
307       le = symtab->linetable->item;
308       nlines = symtab->linetable->nitems;
309
310       if (nlines <= 0)
311         goto assembly_only;
312
313       mle = (struct dis_line_entry *) alloca (nlines * sizeof (struct dis_line_entry));
314
315       out_of_order = 0;
316
317       /* Copy linetable entries for this function into our data
318          structure, creating end_pc's and setting out_of_order as
319          appropriate.  */
320
321       /* First, skip all the preceding functions.  */
322
323       for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
324
325       /* Now, copy all entries before the end of this function.  */
326
327       newlines = 0;
328       for (; i < nlines - 1 && le[i].pc < high; i++)
329         {
330           if (le[i].line == le[i + 1].line
331               && le[i].pc == le[i + 1].pc)
332             continue;           /* Ignore duplicates */
333
334           mle[newlines].line = le[i].line;
335           if (le[i].line > le[i + 1].line)
336             out_of_order = 1;
337           mle[newlines].start_pc = le[i].pc;
338           mle[newlines].end_pc = le[i + 1].pc;
339           newlines++;
340         }
341
342       /* If we're on the last line, and it's part of the function,
343          then we need to get the end pc in a special way.  */
344
345       if (i == nlines - 1
346           && le[i].pc < high)
347         {
348           mle[newlines].line = le[i].line;
349           mle[newlines].start_pc = le[i].pc;
350           sal = find_pc_line (le[i].pc, 0);
351           mle[newlines].end_pc = sal.end;
352           newlines++;
353         }
354
355       /* Now, sort mle by line #s (and, then by addresses within
356          lines). */
357
358       if (out_of_order)
359         qsort (mle, newlines, sizeof (struct dis_line_entry), compare_lines);
360
361       /* Now, for each line entry, emit the specified lines (unless
362          they have been emitted before), followed by the assembly code
363          for that line.  */
364
365       next_line = 0;            /* Force out first line */
366       ui_out_list_begin (uiout, "asm_insns");
367       num_displayed = 0;
368       for (i = 0; i < newlines; i++)
369         {
370           int close_list = 1;
371           /* Print out everything from next_line to the current line.  */
372           if (mle[i].line >= next_line)
373             {
374               if (next_line != 0)
375                 {
376                   /* Just one line to print. */
377                   if (next_line == mle[i].line)
378                     {
379                       ui_out_list_begin (uiout, "src_and_asm_line");
380                       print_source_lines (symtab, next_line, mle[i].line + 1, 0);
381                     }
382                   else
383                     {
384                       /* Several source lines w/o asm instructions associated. */
385                       for (; next_line < mle[i].line; next_line++)
386                         {
387                           ui_out_list_begin (uiout, "src_and_asm_line");
388                           print_source_lines (symtab, next_line, mle[i].line + 1, 0);
389                           ui_out_list_begin (uiout, "line_asm_insn");
390                           ui_out_list_end (uiout);
391                           ui_out_list_end (uiout);
392                         }
393                       /* Print the last line and leave list open for
394                          asm instructions to be added. */
395                       ui_out_list_begin (uiout, "src_and_asm_line");
396                       print_source_lines (symtab, next_line, mle[i].line + 1, 0);
397                     }
398                 }
399               else
400                 {
401                   ui_out_list_begin (uiout, "src_and_asm_line");
402                   print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0);
403                 }
404
405               next_line = mle[i].line + 1;
406               ui_out_list_begin (uiout, "line_asm_insn");
407               if (i + 1 < newlines && mle[i + 1].line <= mle[i].line)
408                 close_list = 0;
409             }
410           for (pc = mle[i].start_pc; pc < mle[i].end_pc;)
411             {
412               QUIT;
413               if (how_many >= 0)
414                 {
415                   if (num_displayed >= how_many)
416                     break;
417                   else
418                     num_displayed++;
419                 }
420               ui_out_list_begin (uiout, NULL);
421               ui_out_field_core_addr (uiout, "address", pc);
422
423               if (!build_address_symbolic (pc, 0, &name, &offset, &filename, &line, &unmapped))
424                 {
425                   /* We don't care now about line, filename and
426                      unmapped, but we might in the future. */
427                   ui_out_field_string (uiout, "func-name", name);
428                   ui_out_field_int (uiout, "offset", offset);
429                 }
430               if (filename != NULL)
431                 xfree (filename);
432               if (name != NULL)
433                 xfree (name);
434
435               ui_file_rewind (stb->stream);
436               pc += (*tm_print_insn) (pc, &di);
437               ui_out_field_stream (uiout, "inst", stb);
438               ui_file_rewind (stb->stream);
439               ui_out_list_end (uiout);
440             }
441           if (close_list)
442             {
443               ui_out_list_end (uiout);
444               ui_out_list_end (uiout);
445               close_list = 0;
446             }
447           if (how_many >= 0)
448             if (num_displayed >= how_many)
449               break;
450         }
451       ui_out_list_end (uiout);
452     }
453   else
454     {
455     assembly_only:
456       ui_out_list_begin (uiout, "asm_insns");
457       num_displayed = 0;
458       for (pc = low; pc < high;)
459         {
460           QUIT;
461           if (how_many >= 0)
462             {
463               if (num_displayed >= how_many)
464                 break;
465               else
466                 num_displayed++;
467             }
468           ui_out_list_begin (uiout, NULL);
469           ui_out_field_core_addr (uiout, "address", pc);
470
471           if (!build_address_symbolic (pc, 0, &name, &offset, &filename, &line, &unmapped))
472             {
473               /* We don't care now about line, filename and
474                  unmapped. But we might in the future. */
475               ui_out_field_string (uiout, "func-name", name);
476               ui_out_field_int (uiout, "offset", offset);
477             }
478           if (filename != NULL)
479             xfree (filename);
480           if (name != NULL)
481             xfree (name);
482
483           ui_file_rewind (stb->stream);
484           pc += (*tm_print_insn) (pc, &di);
485           ui_out_field_stream (uiout, "inst", stb);
486           ui_file_rewind (stb->stream);
487           ui_out_list_end (uiout);
488         }
489       ui_out_list_end (uiout);
490     }
491   gdb_flush (gdb_stdout);
492
493   return MI_CMD_DONE;
494 }
This page took 0.053125 seconds and 4 git commands to generate.