#include "config.h"
#ifdef HAVE_NCURSES_H
#include <ncurses.h>
#else
#ifdef HAVE_CURSES_H
#include <curses.h>
#endif
#endif
#include "defs.h"
#include "symtab.h"
#include "breakpoint.h"
#include "frame.h"
#include "value.h"
#include "tui.h"
#include "tuiData.h"
#include "tuiWin.h"
#include "tuiLayout.h"
#include "tuiSourceWin.h"
#include "tuiStack.h"
#include "tui-file.h"
static struct breakpoint *_hasBreak (CORE_ADDR);
TuiStatus
tuiSetDisassemContent (struct symtab *s, CORE_ADDR startAddr)
{
TuiStatus ret = TUI_FAILURE;
struct ui_file *gdb_dis_out;
if (startAddr != 0)
{
register int i, desc;
if ((ret = tuiAllocSourceBuffer (disassemWin)) == TUI_SUCCESS)
{
register int offset = disassemWin->detail.sourceInfo.horizontalOffset;
register int threshold, curLine = 0, lineWidth, maxLines;
CORE_ADDR newpc, pc;
disassemble_info asmInfo;
TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
extern void strcat_address (CORE_ADDR, char *, int);
extern void strcat_address_numeric (CORE_ADDR, int, char *, int);
int curLen = 0;
int tab_len = tuiDefaultTabLen ();
maxLines = disassemWin->generic.height - 2;
lineWidth = disassemWin->generic.width - 1;
threshold = (lineWidth - 1) + offset;
gdb_dis_out = tui_sfileopen (threshold);
asmInfo = tm_print_insn_info;
asmInfo.stream = gdb_dis_out;
disassemWin->detail.sourceInfo.startLineOrAddr.addr = startAddr;
for (curLine = 0, pc = startAddr; (curLine < maxLines);)
{
TuiWinElementPtr element = (TuiWinElementPtr) disassemWin->generic.content[curLine];
struct breakpoint *bp;
print_address (pc, gdb_dis_out);
curLen = strlen (tui_file_get_strbuf (gdb_dis_out));
i = curLen - ((curLen / tab_len) * tab_len);
tui_file_adjust_strbuf ((tab_len - i > 0) ? (tab_len - i) : 0, gdb_dis_out);
while (i < tab_len)
{
tui_file_get_strbuf (gdb_dis_out)[curLen] = ' ';
i++;
curLen++;
}
tui_file_get_strbuf (gdb_dis_out)[curLen] = '\0';
newpc = pc + ((*tm_print_insn) (pc, &asmInfo));
if (strlen (tui_file_get_strbuf (gdb_dis_out)) > offset)
strcpy (element->whichElement.source.line,
&(tui_file_get_strbuf (gdb_dis_out)[offset]));
else
element->whichElement.source.line[0] = '\0';
element->whichElement.source.lineOrAddr.addr = pc;
element->whichElement.source.isExecPoint =
(pc == (CORE_ADDR) ((TuiWinElementPtr) locator->content[0])->whichElement.locator.addr);
bp = _hasBreak (pc);
element->whichElement.source.hasBreak =
(bp != (struct breakpoint *) NULL &&
(!element->whichElement.source.isExecPoint ||
(bp->disposition != disp_del || bp->hit_count <= 0)));
curLine++;
pc = newpc;
tui_file_get_strbuf (gdb_dis_out)[0] = '\0';
}
ui_file_delete (gdb_dis_out);
gdb_dis_out = NULL;
disassemWin->generic.contentSize = curLine;
ret = TUI_SUCCESS;
}
}
return ret;
}
void
tuiShowDisassem (CORE_ADDR startAddr)
{
struct symtab *s = find_pc_symtab (startAddr);
TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
TuiLineOrAddress val;
val.addr = startAddr;
tuiAddWinToLayout (DISASSEM_WIN);
tuiUpdateSourceWindow (disassemWin, s, val, FALSE);
if (currentLayout () != SRC_DISASSEM_COMMAND && winWithFocus == srcWin)
tuiSetWinFocusTo (disassemWin);
return;
}
void
tuiShowDisassemAndUpdateSource (CORE_ADDR startAddr)
{
struct symtab_and_line sal;
tuiShowDisassem (startAddr);
if (currentLayout () == SRC_DISASSEM_COMMAND)
{
TuiLineOrAddress val;
TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
sal = find_pc_line (startAddr, 0);
val.lineNo = sal.line;
tuiUpdateSourceWindow (srcWin, sal.symtab, val, TRUE);
if (sal.symtab)
{
current_source_symtab = sal.symtab;
tuiUpdateLocatorFilename (sal.symtab->filename);
}
else
tuiUpdateLocatorFilename ("?");
}
return;
}
CORE_ADDR
tuiGetBeginAsmAddress (void)
{
TuiGenWinInfoPtr locator;
TuiLocatorElementPtr element;
CORE_ADDR addr;
locator = locatorWinInfoPtr ();
element = &((TuiWinElementPtr) locator->content[0])->whichElement.locator;
if (element->addr == 0)
{
addr = parse_and_eval_address ("main");
if (addr == 0)
addr = parse_and_eval_address ("MAIN");
}
else
addr = element->addr;
return addr;
}
void
tuiVerticalDisassemScroll (TuiScrollDirection scrollDirection,
int numToScroll)
{
if (disassemWin->generic.content != (OpaquePtr) NULL)
{
CORE_ADDR pc, lowAddr;
TuiWinContent content;
struct symtab *s;
content = (TuiWinContent) disassemWin->generic.content;
if (current_source_symtab == (struct symtab *) NULL)
s = find_pc_symtab (selected_frame->pc);
else
s = current_source_symtab;
pc = content[0]->whichElement.source.lineOrAddr.addr;
if (find_pc_partial_function (pc, (char **) NULL, &lowAddr,
(CORE_ADDR) 0) == 0)
error ("No function contains program counter for selected frame.\n");
else
{
register int line = 0;
register CORE_ADDR newLow;
bfd_byte buffer[4];
TuiLineOrAddress val;
newLow = pc;
if (scrollDirection == FORWARD_SCROLL)
{
for (; line < numToScroll; line++)
newLow += sizeof (bfd_getb32 (buffer));
}
else
{
for (; newLow != 0 && line < numToScroll; line++)
newLow -= sizeof (bfd_getb32 (buffer));
}
val.addr = newLow;
tuiUpdateSourceWindowAsIs (disassemWin, s, val, FALSE);
}
}
return;
}
static struct breakpoint *
_hasBreak (CORE_ADDR addr)
{
struct breakpoint *bpWithBreak = (struct breakpoint *) NULL;
struct breakpoint *bp;
extern struct breakpoint *breakpoint_chain;
for (bp = breakpoint_chain;
(bp != (struct breakpoint *) NULL &&
bpWithBreak == (struct breakpoint *) NULL);
bp = bp->next)
if (addr == bp->address)
bpWithBreak = bp;
return bpWithBreak;
}