OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [gdb/] [tui/] [tuiDisassem.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* Disassembly display.
2
 
3
   Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
4
   Inc.
5
 
6
   Contributed by Hewlett-Packard Company.
7
 
8
   This file is part of GDB.
9
 
10
   This program is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 2 of the License, or
13
   (at your option) any later version.
14
 
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
 
20
   You should have received a copy of the GNU General Public License
21
   along with this program; if not, write to the Free Software
22
   Foundation, Inc., 59 Temple Place - Suite 330,
23
   Boston, MA 02111-1307, USA.  */
24
 
25
/* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
26
   "defs.h" should be included first.  Unfortunatly some systems
27
   (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
28
   and they clash with "bfd.h"'s definiton of true/false.  The correct
29
   fix is to remove true/false from "bfd.h", however, until that
30
   happens, hack around it by including "config.h" and <curses.h>
31
   first.  */
32
 
33
#include "config.h"
34
#ifdef HAVE_NCURSES_H       
35
#include <ncurses.h>
36
#else
37
#ifdef HAVE_CURSES_H
38
#include <curses.h>
39
#endif
40
#endif
41
 
42
#include "defs.h"
43
#include "symtab.h"
44
#include "breakpoint.h"
45
#include "frame.h"
46
#include "value.h"
47
 
48
#include "tui.h"
49
#include "tuiData.h"
50
#include "tuiWin.h"
51
#include "tuiLayout.h"
52
#include "tuiSourceWin.h"
53
#include "tuiStack.h"
54
#include "tui-file.h"
55
 
56
struct tui_asm_line
57
{
58
  CORE_ADDR addr;
59
  char* addr_string;
60
  char* insn;
61
};
62
 
63
/* Function to set the disassembly window's content.
64
   Disassemble count lines starting at pc.
65
   Return address of the count'th instruction after pc.  */
66
static CORE_ADDR
67
tui_disassemble (struct tui_asm_line* lines, CORE_ADDR pc, int count)
68
{
69
  struct ui_file *gdb_dis_out;
70
  disassemble_info asm_info;
71
 
72
  /* now init the ui_file structure */
73
  gdb_dis_out = tui_sfileopen (256);
74
 
75
  memcpy (&asm_info, TARGET_PRINT_INSN_INFO, sizeof (asm_info));
76
  asm_info.stream = gdb_dis_out;
77
 
78
  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
79
    asm_info.endian = BFD_ENDIAN_BIG;
80
  else
81
    asm_info.endian = BFD_ENDIAN_LITTLE;
82
 
83
  if (TARGET_ARCHITECTURE != NULL)
84
    asm_info.mach = TARGET_ARCHITECTURE->mach;
85
 
86
  /* Now construct each line */
87
  for (; count > 0; count--, lines++)
88
    {
89
      if (lines->addr_string)
90
        xfree (lines->addr_string);
91
      if (lines->insn)
92
        xfree (lines->insn);
93
 
94
      print_address (pc, gdb_dis_out);
95
      lines->addr = pc;
96
      lines->addr_string = xstrdup (tui_file_get_strbuf (gdb_dis_out));
97
 
98
      ui_file_rewind (gdb_dis_out);
99
 
100
      pc = pc + TARGET_PRINT_INSN (pc, &asm_info);
101
 
102
      lines->insn = xstrdup (tui_file_get_strbuf (gdb_dis_out));
103
 
104
      /* reset the buffer to empty */
105
      ui_file_rewind (gdb_dis_out);
106
    }
107
  ui_file_delete (gdb_dis_out);
108
  return pc;
109
}
110
 
111
/* Find the disassembly address that corresponds to FROM lines
112
   above or below the PC.  Variable sized instructions are taken
113
   into account by the algorithm.  */
114
static CORE_ADDR
115
tui_find_disassembly_address (CORE_ADDR pc, int from)
116
{
117
  register CORE_ADDR newLow;
118
  int maxLines;
119
  int i;
120
  struct tui_asm_line* lines;
121
 
122
  maxLines = (from > 0) ? from : - from;
123
  if (maxLines <= 1)
124
     return pc;
125
 
126
  lines = (struct tui_asm_line*) alloca (sizeof (struct tui_asm_line)
127
                                         * maxLines);
128
  memset (lines, 0, sizeof (struct tui_asm_line) * maxLines);
129
 
130
  newLow = pc;
131
  if (from > 0)
132
    {
133
      tui_disassemble (lines, pc, maxLines);
134
      newLow = lines[maxLines - 1].addr;
135
    }
136
  else
137
    {
138
      CORE_ADDR last_addr;
139
      int pos;
140
      struct minimal_symbol* msymbol;
141
 
142
      /* Find backward an address which is a symbol
143
         and for which disassembling from that address will fill
144
         completely the window.  */
145
      pos = maxLines - 1;
146
      do {
147
         newLow -= 1 * maxLines;
148
         msymbol = lookup_minimal_symbol_by_pc_section (newLow, 0);
149
 
150
         if (msymbol)
151
            newLow = SYMBOL_VALUE_ADDRESS (msymbol);
152
         else
153
            newLow += 1 * maxLines;
154
 
155
         tui_disassemble (lines, newLow, maxLines);
156
         last_addr = lines[pos].addr;
157
      } while (last_addr > pc && msymbol);
158
 
159
      /* Scan forward disassembling one instruction at a time
160
         until the last visible instruction of the window
161
         matches the pc.  We keep the disassembled instructions
162
         in the 'lines' window and shift it downward (increasing
163
         its addresses).  */
164
      if (last_addr < pc)
165
        do
166
          {
167
            CORE_ADDR next_addr;
168
 
169
            pos++;
170
            if (pos >= maxLines)
171
              pos = 0;
172
 
173
            next_addr = tui_disassemble (&lines[pos], last_addr, 1);
174
 
175
            /* If there are some problems while disassembling exit.  */
176
            if (next_addr <= last_addr)
177
              break;
178
            last_addr = next_addr;
179
          } while (last_addr <= pc);
180
      pos++;
181
      if (pos >= maxLines)
182
         pos = 0;
183
      newLow = lines[pos].addr;
184
    }
185
  for (i = 0; i < maxLines; i++)
186
    {
187
      xfree (lines[i].addr_string);
188
      xfree (lines[i].insn);
189
    }
190
  return newLow;
191
}
192
 
193
/* Function to set the disassembly window's content.  */
194
TuiStatus
195
tuiSetDisassemContent (CORE_ADDR pc)
196
{
197
  TuiStatus ret = TUI_FAILURE;
198
  register int i;
199
  register int offset = disassemWin->detail.sourceInfo.horizontalOffset;
200
  register int lineWidth, maxLines;
201
  CORE_ADDR cur_pc;
202
  TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
203
  int tab_len = tuiDefaultTabLen ();
204
  struct tui_asm_line* lines;
205
  int insn_pos;
206
  int addr_size, max_size;
207
  char* line;
208
 
209
  if (pc == 0)
210
    return TUI_FAILURE;
211
 
212
  ret = tuiAllocSourceBuffer (disassemWin);
213
  if (ret != TUI_SUCCESS)
214
    return ret;
215
 
216
  disassemWin->detail.sourceInfo.startLineOrAddr.addr = pc;
217
  cur_pc = (CORE_ADDR)
218
    (((TuiWinElementPtr) locator->content[0])->whichElement.locator.addr);
219
 
220
  maxLines = disassemWin->generic.height - 2;   /* account for hilite */
221
 
222
  /* Get temporary table that will hold all strings (addr & insn).  */
223
  lines = (struct tui_asm_line*) alloca (sizeof (struct tui_asm_line)
224
                                         * maxLines);
225
  memset (lines, 0, sizeof (struct tui_asm_line) * maxLines);
226
 
227
  lineWidth = disassemWin->generic.width - 1;
228
 
229
  tui_disassemble (lines, pc, maxLines);
230
 
231
  /* See what is the maximum length of an address and of a line.  */
232
  addr_size = 0;
233
  max_size = 0;
234
  for (i = 0; i < maxLines; i++)
235
    {
236
      size_t len = strlen (lines[i].addr_string);
237
      if (len > addr_size)
238
        addr_size = len;
239
 
240
      len = strlen (lines[i].insn) + tab_len;
241
      if (len > max_size)
242
        max_size = len;
243
    }
244
  max_size += addr_size + tab_len;
245
 
246
  /* Allocate memory to create each line.  */
247
  line = (char*) alloca (max_size);
248
  insn_pos = (1 + (addr_size / tab_len)) * tab_len;
249
 
250
  /* Now construct each line */
251
  for (i = 0; i < maxLines; i++)
252
    {
253
      TuiWinElementPtr element;
254
      TuiSourceElement* src;
255
      int curLen;
256
 
257
      element = (TuiWinElementPtr) disassemWin->generic.content[i];
258
      src = &element->whichElement.source;
259
      strcpy (line, lines[i].addr_string);
260
      curLen = strlen (line);
261
 
262
      /* Add spaces to make the instructions start on the same column */
263
      while (curLen < insn_pos)
264
        {
265
          strcat (line, " ");
266
          curLen++;
267
        }
268
 
269
      strcat (line, lines[i].insn);
270
 
271
      /* Now copy the line taking the offset into account */
272
      if (strlen (line) > offset)
273
        strcpy (src->line, &line[offset]);
274
      else
275
        src->line[0] = '\0';
276
 
277
      src->lineOrAddr.addr = lines[i].addr;
278
      src->isExecPoint = lines[i].addr == cur_pc;
279
 
280
      /* See whether there is a breakpoint installed.  */
281
      src->hasBreak = (!src->isExecPoint
282
                       && breakpoint_here_p (pc) != no_breakpoint_here);
283
 
284
      xfree (lines[i].addr_string);
285
      xfree (lines[i].insn);
286
    }
287
  disassemWin->generic.contentSize = i;
288
  return TUI_SUCCESS;
289
}
290
 
291
 
292
/*
293
   ** tuiShowDisassem().
294
   **        Function to display the disassembly window with disassembled code.
295
 */
296
void
297
tuiShowDisassem (CORE_ADDR startAddr)
298
{
299
  struct symtab *s = find_pc_symtab (startAddr);
300
  TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
301
  TuiLineOrAddress val;
302
 
303
  val.addr = startAddr;
304
  tuiAddWinToLayout (DISASSEM_WIN);
305
  tuiUpdateSourceWindow (disassemWin, s, val, FALSE);
306
  /*
307
     ** if the focus was in the src win, put it in the asm win, if the
308
     ** source view isn't split
309
   */
310
  if (currentLayout () != SRC_DISASSEM_COMMAND && winWithFocus == srcWin)
311
    tuiSetWinFocusTo (disassemWin);
312
 
313
  return;
314
}                               /* tuiShowDisassem */
315
 
316
 
317
/*
318
   ** tuiShowDisassemAndUpdateSource().
319
   **        Function to display the disassembly window.
320
 */
321
void
322
tuiShowDisassemAndUpdateSource (CORE_ADDR startAddr)
323
{
324
  struct symtab_and_line sal;
325
 
326
  tuiShowDisassem (startAddr);
327
  if (currentLayout () == SRC_DISASSEM_COMMAND)
328
    {
329
      TuiLineOrAddress val;
330
 
331
      /*
332
         ** Update what is in the source window if it is displayed too,
333
         ** note that it follows what is in the disassembly window and visa-versa
334
       */
335
      sal = find_pc_line (startAddr, 0);
336
      val.lineNo = sal.line;
337
      tuiUpdateSourceWindow (srcWin, sal.symtab, val, TRUE);
338
      if (sal.symtab)
339
        {
340
          current_source_symtab = sal.symtab;
341
          tuiUpdateLocatorFilename (sal.symtab->filename);
342
        }
343
      else
344
        tuiUpdateLocatorFilename ("?");
345
    }
346
 
347
  return;
348
}                               /* tuiShowDisassemAndUpdateSource */
349
 
350
/*
351
   ** tuiGetBeginAsmAddress().
352
 */
353
CORE_ADDR
354
tuiGetBeginAsmAddress (void)
355
{
356
  TuiGenWinInfoPtr locator;
357
  TuiLocatorElementPtr element;
358
  CORE_ADDR addr;
359
 
360
  locator = locatorWinInfoPtr ();
361
  element = &((TuiWinElementPtr) locator->content[0])->whichElement.locator;
362
 
363
  if (element->addr == 0)
364
    {
365
      struct minimal_symbol *main_symbol;
366
 
367
      /* Find address of the start of program.
368
         Note: this should be language specific.  */
369
      main_symbol = lookup_minimal_symbol ("main", NULL, NULL);
370
      if (main_symbol == 0)
371
        main_symbol = lookup_minimal_symbol ("MAIN", NULL, NULL);
372
      if (main_symbol == 0)
373
        main_symbol = lookup_minimal_symbol ("_start", NULL, NULL);
374
      if (main_symbol)
375
        addr = SYMBOL_VALUE_ADDRESS (main_symbol);
376
      else
377
        addr = 0;
378
    }
379
  else                          /* the target is executing */
380
    addr = element->addr;
381
 
382
  return addr;
383
}                               /* tuiGetBeginAsmAddress */
384
 
385
/* Determine what the low address will be to display in the TUI's
386
   disassembly window.  This may or may not be the same as the
387
   low address input.  */
388
CORE_ADDR
389
tuiGetLowDisassemblyAddress (CORE_ADDR low, CORE_ADDR pc)
390
{
391
  int pos;
392
 
393
  /* Determine where to start the disassembly so that the pc is about in the
394
     middle of the viewport.  */
395
  pos = tuiDefaultWinViewportHeight (DISASSEM_WIN, DISASSEM_COMMAND) / 2;
396
  pc = tui_find_disassembly_address (pc, -pos);
397
 
398
  if (pc < low)
399
    pc = low;
400
  return pc;
401
}
402
 
403
/*
404
   ** tuiVerticalDisassemScroll().
405
   **      Scroll the disassembly forward or backward vertically
406
 */
407
void
408
tuiVerticalDisassemScroll (TuiScrollDirection scrollDirection,
409
                           int numToScroll)
410
{
411
  if (disassemWin->generic.content != (OpaquePtr) NULL)
412
    {
413
      CORE_ADDR pc;
414
      TuiWinContent content;
415
      struct symtab *s;
416
      TuiLineOrAddress val;
417
      int maxLines, dir;
418
 
419
      content = (TuiWinContent) disassemWin->generic.content;
420
      if (current_source_symtab == (struct symtab *) NULL)
421
        s = find_pc_symtab (selected_frame->pc);
422
      else
423
        s = current_source_symtab;
424
 
425
      /* account for hilite */
426
      maxLines = disassemWin->generic.height - 2;
427
      pc = content[0]->whichElement.source.lineOrAddr.addr;
428
      dir = (scrollDirection == FORWARD_SCROLL) ? maxLines : - maxLines;
429
 
430
      val.addr = tui_find_disassembly_address (pc, dir);
431
      tuiUpdateSourceWindowAsIs (disassemWin, s, val, FALSE);
432
    }
433
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.