xref: /dflybsd-src/contrib/gdb-7/gdb/tui/tui-disasm.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* Disassembly display.
25796c8dcSSimon Schubert 
3*ef5ccd6cSJohn Marino    Copyright (C) 1998-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert 
55796c8dcSSimon Schubert    Contributed by Hewlett-Packard Company.
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This file is part of GDB.
85796c8dcSSimon Schubert 
95796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
105796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
115796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
125796c8dcSSimon Schubert    (at your option) any later version.
135796c8dcSSimon Schubert 
145796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
155796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
165796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
175796c8dcSSimon Schubert    GNU General Public License for more details.
185796c8dcSSimon Schubert 
195796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
205796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
215796c8dcSSimon Schubert 
225796c8dcSSimon Schubert #include "defs.h"
23cf7f2e2dSJohn Marino #include "arch-utils.h"
245796c8dcSSimon Schubert #include "symtab.h"
255796c8dcSSimon Schubert #include "breakpoint.h"
265796c8dcSSimon Schubert #include "frame.h"
275796c8dcSSimon Schubert #include "value.h"
285796c8dcSSimon Schubert #include "source.h"
295796c8dcSSimon Schubert #include "disasm.h"
305796c8dcSSimon Schubert #include "gdb_string.h"
315796c8dcSSimon Schubert #include "tui/tui.h"
325796c8dcSSimon Schubert #include "tui/tui-data.h"
335796c8dcSSimon Schubert #include "tui/tui-win.h"
345796c8dcSSimon Schubert #include "tui/tui-layout.h"
355796c8dcSSimon Schubert #include "tui/tui-winsource.h"
365796c8dcSSimon Schubert #include "tui/tui-stack.h"
375796c8dcSSimon Schubert #include "tui/tui-file.h"
385796c8dcSSimon Schubert #include "tui/tui-disasm.h"
39cf7f2e2dSJohn Marino #include "progspace.h"
405796c8dcSSimon Schubert 
415796c8dcSSimon Schubert #include "gdb_curses.h"
425796c8dcSSimon Schubert 
435796c8dcSSimon Schubert struct tui_asm_line
445796c8dcSSimon Schubert {
455796c8dcSSimon Schubert   CORE_ADDR addr;
465796c8dcSSimon Schubert   char *addr_string;
475796c8dcSSimon Schubert   char *insn;
485796c8dcSSimon Schubert };
495796c8dcSSimon Schubert 
505796c8dcSSimon Schubert /* Function to set the disassembly window's content.
515796c8dcSSimon Schubert    Disassemble count lines starting at pc.
525796c8dcSSimon Schubert    Return address of the count'th instruction after pc.  */
535796c8dcSSimon Schubert static CORE_ADDR
tui_disassemble(struct gdbarch * gdbarch,struct tui_asm_line * asm_lines,CORE_ADDR pc,int count)545796c8dcSSimon Schubert tui_disassemble (struct gdbarch *gdbarch, struct tui_asm_line *asm_lines,
555796c8dcSSimon Schubert 		 CORE_ADDR pc, int count)
565796c8dcSSimon Schubert {
575796c8dcSSimon Schubert   struct ui_file *gdb_dis_out;
585796c8dcSSimon Schubert 
595796c8dcSSimon Schubert   /* Now init the ui_file structure.  */
605796c8dcSSimon Schubert   gdb_dis_out = tui_sfileopen (256);
615796c8dcSSimon Schubert 
625796c8dcSSimon Schubert   /* Now construct each line.  */
635796c8dcSSimon Schubert   for (; count > 0; count--, asm_lines++)
645796c8dcSSimon Schubert     {
655796c8dcSSimon Schubert       if (asm_lines->addr_string)
665796c8dcSSimon Schubert         xfree (asm_lines->addr_string);
675796c8dcSSimon Schubert       if (asm_lines->insn)
685796c8dcSSimon Schubert         xfree (asm_lines->insn);
695796c8dcSSimon Schubert 
705796c8dcSSimon Schubert       print_address (gdbarch, pc, gdb_dis_out);
715796c8dcSSimon Schubert       asm_lines->addr = pc;
725796c8dcSSimon Schubert       asm_lines->addr_string = xstrdup (tui_file_get_strbuf (gdb_dis_out));
735796c8dcSSimon Schubert 
745796c8dcSSimon Schubert       ui_file_rewind (gdb_dis_out);
755796c8dcSSimon Schubert 
765796c8dcSSimon Schubert       pc = pc + gdb_print_insn (gdbarch, pc, gdb_dis_out, NULL);
775796c8dcSSimon Schubert 
785796c8dcSSimon Schubert       asm_lines->insn = xstrdup (tui_file_get_strbuf (gdb_dis_out));
795796c8dcSSimon Schubert 
805796c8dcSSimon Schubert       /* Reset the buffer to empty.  */
815796c8dcSSimon Schubert       ui_file_rewind (gdb_dis_out);
825796c8dcSSimon Schubert     }
835796c8dcSSimon Schubert   ui_file_delete (gdb_dis_out);
845796c8dcSSimon Schubert   return pc;
855796c8dcSSimon Schubert }
865796c8dcSSimon Schubert 
875796c8dcSSimon Schubert /* Find the disassembly address that corresponds to FROM lines above
885796c8dcSSimon Schubert    or below the PC.  Variable sized instructions are taken into
895796c8dcSSimon Schubert    account by the algorithm.  */
905796c8dcSSimon Schubert static CORE_ADDR
tui_find_disassembly_address(struct gdbarch * gdbarch,CORE_ADDR pc,int from)915796c8dcSSimon Schubert tui_find_disassembly_address (struct gdbarch *gdbarch, CORE_ADDR pc, int from)
925796c8dcSSimon Schubert {
935796c8dcSSimon Schubert   CORE_ADDR new_low;
945796c8dcSSimon Schubert   int max_lines;
955796c8dcSSimon Schubert   int i;
965796c8dcSSimon Schubert   struct tui_asm_line *asm_lines;
975796c8dcSSimon Schubert 
985796c8dcSSimon Schubert   max_lines = (from > 0) ? from : - from;
995796c8dcSSimon Schubert   if (max_lines <= 1)
1005796c8dcSSimon Schubert      return pc;
1015796c8dcSSimon Schubert 
1025796c8dcSSimon Schubert   asm_lines = (struct tui_asm_line*) alloca (sizeof (struct tui_asm_line)
1035796c8dcSSimon Schubert                                          * max_lines);
1045796c8dcSSimon Schubert   memset (asm_lines, 0, sizeof (struct tui_asm_line) * max_lines);
1055796c8dcSSimon Schubert 
1065796c8dcSSimon Schubert   new_low = pc;
1075796c8dcSSimon Schubert   if (from > 0)
1085796c8dcSSimon Schubert     {
1095796c8dcSSimon Schubert       tui_disassemble (gdbarch, asm_lines, pc, max_lines);
1105796c8dcSSimon Schubert       new_low = asm_lines[max_lines - 1].addr;
1115796c8dcSSimon Schubert     }
1125796c8dcSSimon Schubert   else
1135796c8dcSSimon Schubert     {
1145796c8dcSSimon Schubert       CORE_ADDR last_addr;
1155796c8dcSSimon Schubert       int pos;
1165796c8dcSSimon Schubert       struct minimal_symbol *msymbol;
1175796c8dcSSimon Schubert 
1185796c8dcSSimon Schubert       /* Find backward an address which is a symbol and for which
1195796c8dcSSimon Schubert          disassembling from that address will fill completely the
1205796c8dcSSimon Schubert          window.  */
1215796c8dcSSimon Schubert       pos = max_lines - 1;
1225796c8dcSSimon Schubert       do {
1235796c8dcSSimon Schubert          new_low -= 1 * max_lines;
1245796c8dcSSimon Schubert          msymbol = lookup_minimal_symbol_by_pc_section (new_low, 0);
1255796c8dcSSimon Schubert 
1265796c8dcSSimon Schubert          if (msymbol)
1275796c8dcSSimon Schubert             new_low = SYMBOL_VALUE_ADDRESS (msymbol);
1285796c8dcSSimon Schubert          else
1295796c8dcSSimon Schubert             new_low += 1 * max_lines;
1305796c8dcSSimon Schubert 
1315796c8dcSSimon Schubert          tui_disassemble (gdbarch, asm_lines, new_low, max_lines);
1325796c8dcSSimon Schubert          last_addr = asm_lines[pos].addr;
1335796c8dcSSimon Schubert       } while (last_addr > pc && msymbol);
1345796c8dcSSimon Schubert 
1355796c8dcSSimon Schubert       /* Scan forward disassembling one instruction at a time until
1365796c8dcSSimon Schubert          the last visible instruction of the window matches the pc.
1375796c8dcSSimon Schubert          We keep the disassembled instructions in the 'lines' window
1385796c8dcSSimon Schubert          and shift it downward (increasing its addresses).  */
1395796c8dcSSimon Schubert       if (last_addr < pc)
1405796c8dcSSimon Schubert         do
1415796c8dcSSimon Schubert           {
1425796c8dcSSimon Schubert             CORE_ADDR next_addr;
1435796c8dcSSimon Schubert 
1445796c8dcSSimon Schubert             pos++;
1455796c8dcSSimon Schubert             if (pos >= max_lines)
1465796c8dcSSimon Schubert               pos = 0;
1475796c8dcSSimon Schubert 
1485796c8dcSSimon Schubert             next_addr = tui_disassemble (gdbarch, &asm_lines[pos],
1495796c8dcSSimon Schubert 					 last_addr, 1);
1505796c8dcSSimon Schubert 
1515796c8dcSSimon Schubert             /* If there are some problems while disassembling exit.  */
1525796c8dcSSimon Schubert             if (next_addr <= last_addr)
1535796c8dcSSimon Schubert               break;
1545796c8dcSSimon Schubert             last_addr = next_addr;
1555796c8dcSSimon Schubert           } while (last_addr <= pc);
1565796c8dcSSimon Schubert       pos++;
1575796c8dcSSimon Schubert       if (pos >= max_lines)
1585796c8dcSSimon Schubert          pos = 0;
1595796c8dcSSimon Schubert       new_low = asm_lines[pos].addr;
1605796c8dcSSimon Schubert     }
1615796c8dcSSimon Schubert   for (i = 0; i < max_lines; i++)
1625796c8dcSSimon Schubert     {
1635796c8dcSSimon Schubert       xfree (asm_lines[i].addr_string);
1645796c8dcSSimon Schubert       xfree (asm_lines[i].insn);
1655796c8dcSSimon Schubert     }
1665796c8dcSSimon Schubert   return new_low;
1675796c8dcSSimon Schubert }
1685796c8dcSSimon Schubert 
1695796c8dcSSimon Schubert /* Function to set the disassembly window's content.  */
1705796c8dcSSimon Schubert enum tui_status
tui_set_disassem_content(struct gdbarch * gdbarch,CORE_ADDR pc)1715796c8dcSSimon Schubert tui_set_disassem_content (struct gdbarch *gdbarch, CORE_ADDR pc)
1725796c8dcSSimon Schubert {
1735796c8dcSSimon Schubert   enum tui_status ret = TUI_FAILURE;
1745796c8dcSSimon Schubert   int i;
1755796c8dcSSimon Schubert   int offset = TUI_DISASM_WIN->detail.source_info.horizontal_offset;
176*ef5ccd6cSJohn Marino   int max_lines;
1775796c8dcSSimon Schubert   CORE_ADDR cur_pc;
1785796c8dcSSimon Schubert   struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
1795796c8dcSSimon Schubert   int tab_len = tui_default_tab_len ();
1805796c8dcSSimon Schubert   struct tui_asm_line *asm_lines;
1815796c8dcSSimon Schubert   int insn_pos;
1825796c8dcSSimon Schubert   int addr_size, max_size;
1835796c8dcSSimon Schubert   char *line;
1845796c8dcSSimon Schubert 
1855796c8dcSSimon Schubert   if (pc == 0)
1865796c8dcSSimon Schubert     return TUI_FAILURE;
1875796c8dcSSimon Schubert 
1885796c8dcSSimon Schubert   ret = tui_alloc_source_buffer (TUI_DISASM_WIN);
1895796c8dcSSimon Schubert   if (ret != TUI_SUCCESS)
1905796c8dcSSimon Schubert     return ret;
1915796c8dcSSimon Schubert 
1925796c8dcSSimon Schubert   TUI_DISASM_WIN->detail.source_info.gdbarch = gdbarch;
1935796c8dcSSimon Schubert   TUI_DISASM_WIN->detail.source_info.start_line_or_addr.loa = LOA_ADDRESS;
1945796c8dcSSimon Schubert   TUI_DISASM_WIN->detail.source_info.start_line_or_addr.u.addr = pc;
195c50c785cSJohn Marino   cur_pc = (CORE_ADDR) (((struct tui_win_element *)
196c50c785cSJohn Marino 			 locator->content[0])->which_element.locator.addr);
1975796c8dcSSimon Schubert 
1985796c8dcSSimon Schubert   max_lines = TUI_DISASM_WIN->generic.height - 2;	/* Account for
1995796c8dcSSimon Schubert 							   hilite.  */
2005796c8dcSSimon Schubert 
2015796c8dcSSimon Schubert   /* Get temporary table that will hold all strings (addr & insn).  */
2025796c8dcSSimon Schubert   asm_lines = (struct tui_asm_line*) alloca (sizeof (struct tui_asm_line)
2035796c8dcSSimon Schubert                                          * max_lines);
2045796c8dcSSimon Schubert   memset (asm_lines, 0, sizeof (struct tui_asm_line) * max_lines);
2055796c8dcSSimon Schubert 
2065796c8dcSSimon Schubert   tui_disassemble (gdbarch, asm_lines, pc, max_lines);
2075796c8dcSSimon Schubert 
2085796c8dcSSimon Schubert   /* See what is the maximum length of an address and of a line.  */
2095796c8dcSSimon Schubert   addr_size = 0;
2105796c8dcSSimon Schubert   max_size = 0;
2115796c8dcSSimon Schubert   for (i = 0; i < max_lines; i++)
2125796c8dcSSimon Schubert     {
2135796c8dcSSimon Schubert       size_t len = strlen (asm_lines[i].addr_string);
214cf7f2e2dSJohn Marino 
2155796c8dcSSimon Schubert       if (len > addr_size)
2165796c8dcSSimon Schubert         addr_size = len;
2175796c8dcSSimon Schubert 
2185796c8dcSSimon Schubert       len = strlen (asm_lines[i].insn) + tab_len;
2195796c8dcSSimon Schubert       if (len > max_size)
2205796c8dcSSimon Schubert         max_size = len;
2215796c8dcSSimon Schubert     }
2225796c8dcSSimon Schubert   max_size += addr_size + tab_len;
2235796c8dcSSimon Schubert 
2245796c8dcSSimon Schubert   /* Allocate memory to create each line.  */
2255796c8dcSSimon Schubert   line = (char*) alloca (max_size);
2265796c8dcSSimon Schubert   insn_pos = (1 + (addr_size / tab_len)) * tab_len;
2275796c8dcSSimon Schubert 
2285796c8dcSSimon Schubert   /* Now construct each line.  */
2295796c8dcSSimon Schubert   for (i = 0; i < max_lines; i++)
2305796c8dcSSimon Schubert     {
2315796c8dcSSimon Schubert       struct tui_win_element *element;
2325796c8dcSSimon Schubert       struct tui_source_element *src;
2335796c8dcSSimon Schubert       int cur_len;
2345796c8dcSSimon Schubert 
2355796c8dcSSimon Schubert       element = (struct tui_win_element *) TUI_DISASM_WIN->generic.content[i];
2365796c8dcSSimon Schubert       src = &element->which_element.source;
2375796c8dcSSimon Schubert       strcpy (line, asm_lines[i].addr_string);
2385796c8dcSSimon Schubert       cur_len = strlen (line);
2395796c8dcSSimon Schubert 
2405796c8dcSSimon Schubert       /* Add spaces to make the instructions start on the same
2415796c8dcSSimon Schubert 	 column.  */
2425796c8dcSSimon Schubert       while (cur_len < insn_pos)
2435796c8dcSSimon Schubert         {
2445796c8dcSSimon Schubert           strcat (line, " ");
2455796c8dcSSimon Schubert           cur_len++;
2465796c8dcSSimon Schubert         }
2475796c8dcSSimon Schubert 
2485796c8dcSSimon Schubert       strcat (line, asm_lines[i].insn);
2495796c8dcSSimon Schubert 
2505796c8dcSSimon Schubert       /* Now copy the line taking the offset into account.  */
2515796c8dcSSimon Schubert       if (strlen (line) > offset)
2525796c8dcSSimon Schubert         strcpy (src->line, &line[offset]);
2535796c8dcSSimon Schubert       else
2545796c8dcSSimon Schubert         src->line[0] = '\0';
2555796c8dcSSimon Schubert 
2565796c8dcSSimon Schubert       src->line_or_addr.loa = LOA_ADDRESS;
2575796c8dcSSimon Schubert       src->line_or_addr.u.addr = asm_lines[i].addr;
2585796c8dcSSimon Schubert       src->is_exec_point = asm_lines[i].addr == cur_pc;
2595796c8dcSSimon Schubert 
2605796c8dcSSimon Schubert       /* See whether there is a breakpoint installed.  */
2615796c8dcSSimon Schubert       src->has_break = (!src->is_exec_point
262c50c785cSJohn Marino 			&& breakpoint_here_p (current_program_space->aspace,
263c50c785cSJohn Marino 					      pc)
264cf7f2e2dSJohn Marino 			!= no_breakpoint_here);
2655796c8dcSSimon Schubert 
2665796c8dcSSimon Schubert       xfree (asm_lines[i].addr_string);
2675796c8dcSSimon Schubert       xfree (asm_lines[i].insn);
2685796c8dcSSimon Schubert     }
2695796c8dcSSimon Schubert   TUI_DISASM_WIN->generic.content_size = i;
2705796c8dcSSimon Schubert   return TUI_SUCCESS;
2715796c8dcSSimon Schubert }
2725796c8dcSSimon Schubert 
2735796c8dcSSimon Schubert 
2745796c8dcSSimon Schubert /* Function to display the disassembly window with disassembled code.  */
2755796c8dcSSimon Schubert void
tui_show_disassem(struct gdbarch * gdbarch,CORE_ADDR start_addr)2765796c8dcSSimon Schubert tui_show_disassem (struct gdbarch *gdbarch, CORE_ADDR start_addr)
2775796c8dcSSimon Schubert {
2785796c8dcSSimon Schubert   struct symtab *s = find_pc_symtab (start_addr);
2795796c8dcSSimon Schubert   struct tui_win_info *win_with_focus = tui_win_with_focus ();
2805796c8dcSSimon Schubert   struct tui_line_or_address val;
2815796c8dcSSimon Schubert 
2825796c8dcSSimon Schubert   val.loa = LOA_ADDRESS;
2835796c8dcSSimon Schubert   val.u.addr = start_addr;
2845796c8dcSSimon Schubert   tui_add_win_to_layout (DISASSEM_WIN);
2855796c8dcSSimon Schubert   tui_update_source_window (TUI_DISASM_WIN, gdbarch, s, val, FALSE);
2865796c8dcSSimon Schubert 
2875796c8dcSSimon Schubert   /* If the focus was in the src win, put it in the asm win, if the
2885796c8dcSSimon Schubert      source view isn't split.  */
2895796c8dcSSimon Schubert   if (tui_current_layout () != SRC_DISASSEM_COMMAND
2905796c8dcSSimon Schubert       && win_with_focus == TUI_SRC_WIN)
2915796c8dcSSimon Schubert     tui_set_win_focus_to (TUI_DISASM_WIN);
2925796c8dcSSimon Schubert 
2935796c8dcSSimon Schubert   return;
2945796c8dcSSimon Schubert }
2955796c8dcSSimon Schubert 
2965796c8dcSSimon Schubert 
2975796c8dcSSimon Schubert /* Function to display the disassembly window.  */
2985796c8dcSSimon Schubert void
tui_show_disassem_and_update_source(struct gdbarch * gdbarch,CORE_ADDR start_addr)2995796c8dcSSimon Schubert tui_show_disassem_and_update_source (struct gdbarch *gdbarch,
3005796c8dcSSimon Schubert 				     CORE_ADDR start_addr)
3015796c8dcSSimon Schubert {
3025796c8dcSSimon Schubert   struct symtab_and_line sal;
3035796c8dcSSimon Schubert 
3045796c8dcSSimon Schubert   tui_show_disassem (gdbarch, start_addr);
3055796c8dcSSimon Schubert   if (tui_current_layout () == SRC_DISASSEM_COMMAND)
3065796c8dcSSimon Schubert     {
3075796c8dcSSimon Schubert       struct tui_line_or_address val;
3085796c8dcSSimon Schubert 
3095796c8dcSSimon Schubert       /* Update what is in the source window if it is displayed too,
3105796c8dcSSimon Schubert          note that it follows what is in the disassembly window and
3115796c8dcSSimon Schubert          visa-versa.  */
3125796c8dcSSimon Schubert       sal = find_pc_line (start_addr, 0);
3135796c8dcSSimon Schubert       val.loa = LOA_LINE;
3145796c8dcSSimon Schubert       val.u.line_no = sal.line;
3155796c8dcSSimon Schubert       tui_update_source_window (TUI_SRC_WIN, gdbarch, sal.symtab, val, TRUE);
3165796c8dcSSimon Schubert       if (sal.symtab)
3175796c8dcSSimon Schubert 	{
3185796c8dcSSimon Schubert 	  set_current_source_symtab_and_line (&sal);
319*ef5ccd6cSJohn Marino 	  tui_update_locator_fullname (symtab_to_fullname (sal.symtab));
3205796c8dcSSimon Schubert 	}
3215796c8dcSSimon Schubert       else
322*ef5ccd6cSJohn Marino 	tui_update_locator_fullname ("?");
3235796c8dcSSimon Schubert     }
3245796c8dcSSimon Schubert 
3255796c8dcSSimon Schubert   return;
3265796c8dcSSimon Schubert }
3275796c8dcSSimon Schubert 
3285796c8dcSSimon Schubert void
tui_get_begin_asm_address(struct gdbarch ** gdbarch_p,CORE_ADDR * addr_p)3295796c8dcSSimon Schubert tui_get_begin_asm_address (struct gdbarch **gdbarch_p, CORE_ADDR *addr_p)
3305796c8dcSSimon Schubert {
3315796c8dcSSimon Schubert   struct tui_gen_win_info *locator;
3325796c8dcSSimon Schubert   struct tui_locator_element *element;
333cf7f2e2dSJohn Marino   struct gdbarch *gdbarch = get_current_arch ();
3345796c8dcSSimon Schubert   CORE_ADDR addr;
3355796c8dcSSimon Schubert 
3365796c8dcSSimon Schubert   locator = tui_locator_win_info_ptr ();
337c50c785cSJohn Marino   element = &((struct tui_win_element *)
338c50c785cSJohn Marino 	      locator->content[0])->which_element.locator;
3395796c8dcSSimon Schubert 
3405796c8dcSSimon Schubert   if (element->addr == 0)
3415796c8dcSSimon Schubert     {
3425796c8dcSSimon Schubert       struct minimal_symbol *main_symbol;
3435796c8dcSSimon Schubert 
3445796c8dcSSimon Schubert       /* Find address of the start of program.
3455796c8dcSSimon Schubert          Note: this should be language specific.  */
3465796c8dcSSimon Schubert       main_symbol = lookup_minimal_symbol ("main", NULL, NULL);
3475796c8dcSSimon Schubert       if (main_symbol == 0)
3485796c8dcSSimon Schubert         main_symbol = lookup_minimal_symbol ("MAIN", NULL, NULL);
3495796c8dcSSimon Schubert       if (main_symbol == 0)
3505796c8dcSSimon Schubert         main_symbol = lookup_minimal_symbol ("_start", NULL, NULL);
3515796c8dcSSimon Schubert       if (main_symbol)
3525796c8dcSSimon Schubert         addr = SYMBOL_VALUE_ADDRESS (main_symbol);
3535796c8dcSSimon Schubert       else
3545796c8dcSSimon Schubert         addr = 0;
3555796c8dcSSimon Schubert     }
3565796c8dcSSimon Schubert   else				/* The target is executing.  */
3575796c8dcSSimon Schubert     {
3585796c8dcSSimon Schubert       gdbarch = element->gdbarch;
3595796c8dcSSimon Schubert       addr = element->addr;
3605796c8dcSSimon Schubert     }
3615796c8dcSSimon Schubert 
3625796c8dcSSimon Schubert   *gdbarch_p = gdbarch;
3635796c8dcSSimon Schubert   *addr_p = addr;
3645796c8dcSSimon Schubert }
3655796c8dcSSimon Schubert 
3665796c8dcSSimon Schubert /* Determine what the low address will be to display in the TUI's
3675796c8dcSSimon Schubert    disassembly window.  This may or may not be the same as the low
3685796c8dcSSimon Schubert    address input.  */
3695796c8dcSSimon Schubert CORE_ADDR
tui_get_low_disassembly_address(struct gdbarch * gdbarch,CORE_ADDR low,CORE_ADDR pc)3705796c8dcSSimon Schubert tui_get_low_disassembly_address (struct gdbarch *gdbarch,
3715796c8dcSSimon Schubert 				 CORE_ADDR low, CORE_ADDR pc)
3725796c8dcSSimon Schubert {
3735796c8dcSSimon Schubert   int pos;
3745796c8dcSSimon Schubert 
3755796c8dcSSimon Schubert   /* Determine where to start the disassembly so that the pc is about
3765796c8dcSSimon Schubert      in the middle of the viewport.  */
3775796c8dcSSimon Schubert   pos = tui_default_win_viewport_height (DISASSEM_WIN, DISASSEM_COMMAND) / 2;
3785796c8dcSSimon Schubert   pc = tui_find_disassembly_address (gdbarch, pc, -pos);
3795796c8dcSSimon Schubert 
3805796c8dcSSimon Schubert   if (pc < low)
3815796c8dcSSimon Schubert     pc = low;
3825796c8dcSSimon Schubert   return pc;
3835796c8dcSSimon Schubert }
3845796c8dcSSimon Schubert 
3855796c8dcSSimon Schubert /* Scroll the disassembly forward or backward vertically.  */
3865796c8dcSSimon Schubert void
tui_vertical_disassem_scroll(enum tui_scroll_direction scroll_direction,int num_to_scroll)3875796c8dcSSimon Schubert tui_vertical_disassem_scroll (enum tui_scroll_direction scroll_direction,
3885796c8dcSSimon Schubert 			      int num_to_scroll)
3895796c8dcSSimon Schubert {
3905796c8dcSSimon Schubert   if (TUI_DISASM_WIN->generic.content != NULL)
3915796c8dcSSimon Schubert     {
3925796c8dcSSimon Schubert       struct gdbarch *gdbarch = TUI_DISASM_WIN->detail.source_info.gdbarch;
3935796c8dcSSimon Schubert       CORE_ADDR pc;
3945796c8dcSSimon Schubert       tui_win_content content;
3955796c8dcSSimon Schubert       struct tui_line_or_address val;
3965796c8dcSSimon Schubert       int dir;
3975796c8dcSSimon Schubert 
3985796c8dcSSimon Schubert       content = (tui_win_content) TUI_DISASM_WIN->generic.content;
3995796c8dcSSimon Schubert 
4005796c8dcSSimon Schubert       pc = content[0]->which_element.source.line_or_addr.u.addr;
4015796c8dcSSimon Schubert       num_to_scroll++;
402c50c785cSJohn Marino       dir = (scroll_direction == FORWARD_SCROLL)
403c50c785cSJohn Marino 	? num_to_scroll : -num_to_scroll;
4045796c8dcSSimon Schubert 
4055796c8dcSSimon Schubert       val.loa = LOA_ADDRESS;
4065796c8dcSSimon Schubert       val.u.addr = tui_find_disassembly_address (gdbarch, pc, dir);
407c50c785cSJohn Marino       tui_update_source_window_as_is (TUI_DISASM_WIN, gdbarch,
408c50c785cSJohn Marino 				      NULL, val, FALSE);
4095796c8dcSSimon Schubert     }
4105796c8dcSSimon Schubert }
411