* configure,configure.in: Add target sparclet.

* monitor.h,monitor.c:
    Added monitor flags MO_NO_ECHO_ON_SETMEM (don't expect echo on
    setmem command), MO_RUN_FIRST_TIME (if command to start process
    running on target is different from one to continue execution),
    MO_HEX_PREFIX (if addresses from monitor have a "0x" prefix).
    * monitor.c,parse.c,sparc-tdep.c:
    Don't require strings in the registers array.  This is to allow
    NULLs to be place holders in the tm-*.h file so that only minor
    changes are needed when a new processor is introduced (eg, one
    without floating point).
    * sparc-tdep.c: Conditionally remove dependancies on floating point.
    * sparclet-rom.c,config/sparc/sparclet.mt,config/sparc/tm-sparclet.h:
    New files for target sparclet.
    * symfile.c: Add option for 2nd parameter on load command : a load
    offset added to the vma of each section.
This commit is contained in:
Dawn Perchik 1996-06-28 14:03:13 +00:00
parent 265c044ac1
commit 012be3cec3
10 changed files with 509 additions and 91 deletions

View file

@ -349,6 +349,7 @@ sparc-stub.c
sparc-tdep.c
sparcl-stub.c
sparcl-tdep.c
sparclet-rom.c
srec.h
stabsread.c
stabsread.h

View file

@ -1,3 +1,25 @@
Fri Jun 28 06:34:19 1996 Dawn Perchik <dawn@cygnus.com>
* configure,configure.in: Add target sparclet.
* monitor.h,monitor.c:
Added monitor flags MO_NO_ECHO_ON_SETMEM (don't expect echo on
setmem command), MO_RUN_FIRST_TIME (if command to start process
running on target is different from one to continue execution),
MO_HEX_PREFIX (if addresses from monitor have a "0x" prefix).
* monitor.c,parse.c,sparc-tdep.c:
Don't require strings in the registers array. This is to allow
NULLs to be place holders in the tm-*.h file so that only minor
changes are needed when a new processor is introduced (eg, one
without floating point).
* sparc-tdep.c: Conditionally remove dependancies on floating point.
* sparclet-rom.c,config/sparc/sparclet.mt,config/sparc/tm-sparclet.h:
New files for target sparclet.
* symfile.c: Add option for 2nd parameter on load command : a load
offset added to the vma of each section.
Fri Jun 28 05:39:19 1996 Dawn Perchik <dawn@cygnus.com>
* main.c (main): Add option "l" for setting remote_timeout.

3
gdb/configure vendored
View file

@ -3535,8 +3535,7 @@ sparc-*-sunos4*) gdb_target=sun4os4 ;;
sparc-*-sunos5*) gdb_target=sun4sol2 ;;
sparc-*-vxworks*) gdb_target=vxsparc ;;
sparc-*-*) gdb_target=sun4os4 ;;
# Use sparc-em for sparclet for now.
sparclet-*-*) gdb_target=sparc-em ;;
sparclet-*-*) gdb_target=sparclet ;;
sparclite*-*-*) gdb_target=sparclite ;;
# It's not clear what the right solution for "v8plus" systems is yet.
# For now, stick with sparc-sun-solaris2 since that's what config.guess

View file

@ -644,8 +644,7 @@ sparc-*-sunos4*) gdb_target=sun4os4 ;;
sparc-*-sunos5*) gdb_target=sun4sol2 ;;
sparc-*-vxworks*) gdb_target=vxsparc ;;
sparc-*-*) gdb_target=sun4os4 ;;
# Use sparc-em for sparclet for now.
sparclet-*-*) gdb_target=sparc-em ;;
sparclet-*-*) gdb_target=sparclet;;
sparclite*-*-*) gdb_target=sparclite ;;
# It's not clear what the right solution for "v8plus" systems is yet.
# For now, stick with sparc-sun-solaris2 since that's what config.guess

View file

@ -123,6 +123,8 @@ static int dump_reg_flag; /* Non-zero means do a dump_registers cmd when
monitor_wait wakes up. */
static DCACHE *remote_dcache;
static int first_time=0; /* is this the first time we're executing after
gaving created the child proccess? */
/* monitor_debug is like fputs_unfiltered, except it prints special
characters in printable fashion. */
@ -139,7 +141,7 @@ monitor_debug (prefix, string, suffix)
static int new_line=1;
static char *prev_prefix = "";
static char *prev_suffix = "";
/* if the prefix is changing, print the previous suffix, a new line,
and the new prefix */
if (strcmp(prev_prefix, prefix) != 0 && !new_line)
@ -693,6 +695,15 @@ monitor_resume (pid, step, sig)
int pid, step;
enum target_signal sig;
{
/* Some monitors require a different command when starting a program */
if (current_monitor->flags & MO_RUN_FIRST_TIME && first_time == 1)
{
first_time = 0;
monitor_printf ("run\r");
if (current_monitor->flags & MO_NEED_REGDUMP_AFTER_CONT)
dump_reg_flag = 1;
return;
}
dcache_flush (remote_dcache);
if (step)
monitor_printf (current_monitor->step);
@ -885,6 +896,20 @@ monitor_fetch_register (regno)
if (current_monitor->getreg.resp_delim)
monitor_expect (current_monitor->getreg.resp_delim, NULL, 0);
/* Skip leading spaces and "0x" if MO_HEX_PREFIX flag is set */
if (current_monitor->flags & MO_HEX_PREFIX)
{
int c;
c = readchar (timeout);
while (c == ' ')
c = readchar (timeout);
if ((c == '0') && ((c = readchar (timeout)) == 'x'))
;
else
error ("Bad value returned from monitor while fetching register %x.",
regno);
}
/* Read upto the maximum number of hex digits for this register, skipping
spaces, but stop reading if something else is seen. Some monitors
like to drop leading zeros. */
@ -1078,7 +1103,10 @@ monitor_write_memory (memaddr, myaddr, len)
val = extract_unsigned_integer (myaddr, len);
monitor_printf (cmd, memaddr, val);
if (current_monitor->flags & MO_NO_ECHO_ON_SETMEM)
monitor_printf_noecho (cmd, memaddr, val);
else
monitor_printf (cmd, memaddr, val);
monitor_expect_prompt (NULL, 0);
@ -1135,6 +1163,19 @@ monitor_read_memory_single (memaddr, myaddr, len)
/* Now, read the appropriate number of hex digits for this loc, skipping
spaces. */
/* Skip leading spaces and "0x" if MO_HEX_PREFIX flag is set */
if (current_monitor->flags & MO_HEX_PREFIX)
{
int c;
c = readchar (timeout);
while (c == ' ')
c = readchar (timeout);
if ((c == '0') && ((c = readchar (timeout)) == 'x'))
;
else
error ("monitor_read_memory_single (0x%x): bad response from monitor: %.*s%c.",
memaddr, i, membuf, c);
}
for (i = 0; i < len * 2; i++)
{
int c;
@ -1331,6 +1372,7 @@ monitor_create_inferior (exec_file, args, env)
if (args && (*args != '\000'))
error ("Args are not supported by the monitor.");
first_time = 1;
clear_proceed_status ();
proceed (bfd_get_start_address (exec_bfd), TARGET_SIGNAL_0, 0);
}
@ -1432,6 +1474,7 @@ monitor_load (file, from_tty)
if (current_monitor->loadresp)
monitor_expect (current_monitor->loadresp, NULL, 0);
/* FIXME Should add arg here for load_offset (already done for generic_load) */
load_srec (monitor_desc, file, 32, SREC_ALL, hashmark,
current_monitor->flags & MO_SREC_ACK ?
monitor_wait_srec_ack : NULL);

View file

@ -152,6 +152,18 @@ struct monitor_ops
#define MO_SREC_ACK 0x100
/* Allow 0x prefix on addresses retured from monitor */
#define MO_HEX_PREFIX 0x200
/* Some monitors require a different command when starting a program */
#define MO_RUN_FIRST_TIME 0x400
/* Don't expect echos when getting memory */
#define MO_NO_ECHO_ON_SETMEM 0x800
#define SREC_SIZE 160
extern void monitor_open PARAMS ((char *args, struct monitor_ops *ops,

View file

@ -459,13 +459,13 @@ write_dollar_variable (str)
/* Handle tokens that refer to machine registers:
$ followed by a register name. */
for (i = 0; i < NUM_REGS; i++)
if (str.length - 1 == strlen (reg_names[i])
if (reg_names[i] && str.length - 1 == strlen (reg_names[i])
&& STREQN (str.ptr + 1, reg_names[i], str.length - 1))
{
goto handle_register;
}
for (i = 0; i < num_std_regs; i++)
if (str.length - 1 == strlen (std_regs[i].name)
if (std_regs[i].name && str.length - 1 == strlen (std_regs[i].name)
&& STREQN (str.ptr + 1, std_regs[i].name, str.length - 1))
{
i = std_regs[i].regnum;

View file

@ -1,5 +1,5 @@
/* Target-dependent code for the SPARC for GDB, the GNU debugger.
Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995
Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996
Free Software Foundation, Inc.
This file is part of GDB.
@ -34,9 +34,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "gdbcore.h"
#ifdef GDB_TARGET_IS_SPARC64
#define NUM_SPARC_FPREGS 64
#define FP_REGISTER_BYTES (64 * 4)
#else
#define NUM_SPARC_FPREGS 32
#define FP_REGISTER_BYTES (32 * 4)
#endif
/* If not defined, assume 32 bit sparc. */
#ifndef FP_MAX_REGNUM
#define FP_MAX_REGNUM (FP0_REGNUM + 32)
#endif
#define SPARC_INTREG_SIZE (REGISTER_RAW_SIZE (G0_REGNUM))
@ -607,6 +612,22 @@ get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
*optimized = 0;
addr = 0;
/* FIXME This code extracted from infcmd.c; should put elsewhere! */
if (frame == NULL)
{
/* error ("No selected frame."); */
if (!target_has_registers)
error ("The program has no registers now.");
if (selected_frame == NULL)
error ("No selected frame.");
/* Try to use selected frame */
frame = get_prev_frame (selected_frame);
if (frame == 0)
error ("Cmd not meaningful in the outermost frame.");
}
frame1 = frame->next;
while (frame1 != NULL)
{
@ -614,20 +635,36 @@ get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
read_register (SP_REGNUM))
&& frame1->pc <= FRAME_FP (frame1))
{
/* Dummy frame. All but the window regs are in there somewhere. */
/* FIXME: The offsets are wrong for sparc64 (eg: 0xa0). */
/* Dummy frame. All but the window regs are in there somewhere.
The window registers are saved on the stack, just like in a
normal frame. */
if (regnum >= G1_REGNUM && regnum < G1_REGNUM + 7)
addr = frame1->frame + (regnum - G0_REGNUM) * SPARC_INTREG_SIZE
- (NUM_SPARC_FPREGS * 4 + 8 * SPARC_INTREG_SIZE);
- (FP_REGISTER_BYTES + 8 * SPARC_INTREG_SIZE);
else if (regnum >= I0_REGNUM && regnum < I0_REGNUM + 8)
addr = frame1->frame + (regnum - I0_REGNUM) * SPARC_INTREG_SIZE
- (NUM_SPARC_FPREGS * 4 + 16 * SPARC_INTREG_SIZE);
else if (regnum >= FP0_REGNUM && regnum < FP0_REGNUM + NUM_SPARC_FPREGS)
addr = (frame1->prev->bottom
+ (regnum - I0_REGNUM) * SPARC_INTREG_SIZE
+ FRAME_SAVED_I0);
else if (regnum >= L0_REGNUM && regnum < L0_REGNUM + 8)
addr = (frame1->prev->bottom
+ (regnum - L0_REGNUM) * SPARC_INTREG_SIZE
+ FRAME_SAVED_L0);
else if (regnum >= O0_REGNUM && regnum < O0_REGNUM + 8)
addr = frame1->frame + (regnum - O0_REGNUM) * SPARC_INTREG_SIZE
- (FP_REGISTER_BYTES + 16 * SPARC_INTREG_SIZE);
#ifdef FP0_REGNUM
else if (regnum >= FP0_REGNUM && regnum < FP0_REGNUM + 32)
addr = frame1->frame + (regnum - FP0_REGNUM) * 4
- (NUM_SPARC_FPREGS * 4);
- (FP_REGISTER_BYTES);
#ifdef GDB_TARGET_IS_SPARC64
else if (regnum >= FP0_REGNUM + 32 && regnum < FP_MAX_REGNUM)
addr = frame1->frame + 32 * 4 + (regnum - FP0_REGNUM - 32) * 8
- (FP_REGISTER_BYTES);
#endif
#endif /* FP0_REGNUM */
else if (regnum >= Y_REGNUM && regnum < NUM_REGS)
addr = frame1->frame + (regnum - Y_REGNUM) * SPARC_INTREG_SIZE
- (NUM_SPARC_FPREGS * 4 + 24 * SPARC_INTREG_SIZE);
- (FP_REGISTER_BYTES + 24 * SPARC_INTREG_SIZE);
}
else if (frame1->flat)
{
@ -715,8 +752,13 @@ get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
#endif
/* See tm-sparc.h for how this is calculated. */
#ifdef FP0_REGNUM
#define DUMMY_STACK_REG_BUF_SIZE \
(((8+8+8) * SPARC_INTREG_SIZE) + (32 * REGISTER_RAW_SIZE (FP0_REGNUM)))
#else
#define DUMMY_STACK_REG_BUF_SIZE \
(((8+8+8) * SPARC_INTREG_SIZE) )
#endif /* FP0_REGNUM */
#define DUMMY_STACK_SIZE (DUMMY_STACK_REG_BUF_SIZE + DUMMY_REG_SAVE_OFFSET)
void
@ -743,11 +785,11 @@ sparc_push_dummy_frame ()
&register_temp[16 * SPARC_INTREG_SIZE],
SPARC_INTREG_SIZE * 8);
/* ??? The 32 here should be NUM_SPARC_FPREGS, but until we decide what
REGISTER_RAW_SIZE should be for fp regs, it's left as is. */
#ifdef FP0_REGNUM
read_register_bytes (REGISTER_BYTE (FP0_REGNUM),
&register_temp[24 * SPARC_INTREG_SIZE],
REGISTER_RAW_SIZE (FP0_REGNUM) * 32);
FP_REGISTER_BYTES);
#endif /* FP0_REGNUM */
sp -= DUMMY_STACK_SIZE;
@ -820,19 +862,27 @@ sparc_frame_find_saved_regs (fi, saved_regs_addr)
for (regnum = G1_REGNUM; regnum < G1_REGNUM+7; regnum++)
saved_regs_addr->regs[regnum] =
frame_addr + (regnum - G0_REGNUM) * SPARC_INTREG_SIZE
- (NUM_SPARC_FPREGS * 4 + 8 * SPARC_INTREG_SIZE);
- (FP_REGISTER_BYTES + 8 * SPARC_INTREG_SIZE);
for (regnum = I0_REGNUM; regnum < I0_REGNUM+8; regnum++)
saved_regs_addr->regs[regnum] =
frame_addr + (regnum - I0_REGNUM) * SPARC_INTREG_SIZE
- (NUM_SPARC_FPREGS * 4 + 16 * SPARC_INTREG_SIZE);
- (FP_REGISTER_BYTES + 16 * SPARC_INTREG_SIZE);
#ifdef FP0_REGNUM
for (regnum = FP0_REGNUM; regnum < FP0_REGNUM + 32; regnum++)
saved_regs_addr->regs[regnum] =
frame_addr + (regnum - FP0_REGNUM) * 4
- (NUM_SPARC_FPREGS * 4);
- (FP_REGISTER_BYTES);
#ifdef GDB_TARGET_IS_SPARC64
for (regnum = FP0_REGNUM + 32; regnum < FP_MAX_REGNUM; regnum++)
saved_regs_addr->regs[regnum] =
frame_addr + 32 * 4 + (regnum - FP0_REGNUM - 32) * 8
- (FP_REGISTER_BYTES);
#endif
#endif /* FP0_REGNUM */
for (regnum = Y_REGNUM; regnum < NUM_REGS; regnum++)
saved_regs_addr->regs[regnum] =
frame_addr + (regnum - Y_REGNUM) * SPARC_INTREG_SIZE - 0xe0;
- (NUM_SPARC_FPREGS * 4 + 24 * SPARC_INTREG_SIZE);
- (FP_REGISTER_BYTES + 24 * SPARC_INTREG_SIZE);
frame_addr = fi->bottom ?
fi->bottom : read_register (SP_REGNUM);
}
@ -908,11 +958,12 @@ sparc_pop_frame ()
int regnum;
sparc_frame_find_saved_regs (frame, &fsr);
#ifdef FP0_REGNUM
if (fsr.regs[FP0_REGNUM])
{
read_memory (fsr.regs[FP0_REGNUM], raw_buffer, NUM_SPARC_FPREGS * 4);
read_memory (fsr.regs[FP0_REGNUM], raw_buffer, FP_REGISTER_BYTES);
write_register_bytes (REGISTER_BYTE (FP0_REGNUM),
raw_buffer, NUM_SPARC_FPREGS * 4);
raw_buffer, FP_REGISTER_BYTES);
}
#ifndef GDB_TARGET_IS_SPARC64
if (fsr.regs[FPS_REGNUM])
@ -926,6 +977,7 @@ sparc_pop_frame ()
write_register_bytes (REGISTER_BYTE (CPS_REGNUM), raw_buffer, 4);
}
#endif
#endif /* FP0_REGNUM */
if (fsr.regs[G1_REGNUM])
{
read_memory (fsr.regs[G1_REGNUM], raw_buffer, 7 * SPARC_INTREG_SIZE);
@ -1205,7 +1257,7 @@ prfpregset_t *fpregsetp;
register int regi;
char *from;
for (regi = FP0_REGNUM ; regi < FP0_REGNUM+32 ; regi++)
for (regi = FP0_REGNUM ; regi < FP_MAX_REGNUM ; regi++)
{
from = (char *) &fpregsetp->pr_fr.pr_regs[regi-FP0_REGNUM];
supply_register (regi, from);
@ -1228,9 +1280,7 @@ int regno;
char *to;
char *from;
/* ??? The 32 should probably be NUM_SPARC_FPREGS, but again we're
waiting on what REGISTER_RAW_SIZE should be for fp regs. */
for (regi = FP0_REGNUM ; regi < FP0_REGNUM + 32 ; regi++)
for (regi = FP0_REGNUM ; regi < FP_MAX_REGNUM ; regi++)
{
if ((regno == -1) || (regno == regi))
{
@ -1360,17 +1410,50 @@ sparc_print_register_hook (regno)
{
unsigned LONGEST val;
if (((unsigned) (regno) - FP0_REGNUM < FP_MAX_REGNUM - FP0_REGNUM)
&& ((regno) & 1) == 0)
/* Handle double/quad versions of lower 32 fp regs. */
if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32
&& (regno & 1) == 0)
{
char doublereg[8]; /* two float regs */
if (!read_relative_register_raw_bytes ((regno), doublereg))
char value[16];
if (!read_relative_register_raw_bytes (regno, value)
&& !read_relative_register_raw_bytes (regno + 1, value + 4))
{
printf_unfiltered("\t");
print_floating (doublereg, builtin_type_double, gdb_stdout);
printf_unfiltered ("\t");
print_floating (value, builtin_type_double, gdb_stdout);
}
#if 0 /* FIXME: gdb doesn't handle long doubles */
if ((regno & 3) == 0)
{
if (!read_relative_register_raw_bytes (regno + 2, value + 8)
&& !read_relative_register_raw_bytes (regno + 3, value + 12))
{
printf_unfiltered ("\t");
print_floating (value, builtin_type_long_double, gdb_stdout);
}
}
#endif
return;
}
#if 0 /* FIXME: gdb doesn't handle long doubles */
/* Print upper fp regs as long double if appropriate. */
if (regno >= FP0_REGNUM + 32 && regno < FP_MAX_REGNUM
/* We test for even numbered regs and not a multiple of 4 because
the upper fp regs are recorded as doubles. */
&& (regno & 1) == 0)
{
char value[16];
if (!read_relative_register_raw_bytes (regno, value)
&& !read_relative_register_raw_bytes (regno + 1, value + 8))
{
printf_unfiltered ("\t");
print_floating (value, builtin_type_long_double, gdb_stdout);
}
return;
}
#endif
/* FIXME: Some of these are priviledged registers.
Not sure how they should be handled. */

279
gdb/sparclet-rom.c Normal file
View file

@ -0,0 +1,279 @@
/* Remote target glue for the SPARC Sparclet ROM monitor.
Copyright 1995, 1996 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "gdbcore.h"
#include "target.h"
#include "monitor.h"
#include "serial.h"
#include "srec.h"
#include "symtab.h"
#include "symfile.h" /* for generic_load */
#if !defined (HAVE_TERMIOS) && !defined (HAVE_TERMIO) && !defined (HAVE_SGTTY)
#define HAVE_SGTTY
#endif
#ifdef HAVE_SGTTY
#include <sys/ioctl.h>
#endif
#include <sys/types.h> /* Needed by file.h on Sys V */
#include <sys/file.h>
#include <signal.h>
#include <sys/stat.h>
#define USE_GENERIC_LOAD
#define USE_SW_BREAKS
static struct target_ops sparclet_ops;
static void sparclet_open PARAMS ((char *args, int from_tty));
#ifdef USE_GENERIC_LOAD
static void
sparclet_load_gen (filename, from_tty)
char *filename;
int from_tty;
{
extern int inferior_pid;
generic_load (filename, from_tty);
/* Finally, make the PC point at the start address */
if (exec_bfd)
write_pc (bfd_get_start_address (exec_bfd));
inferior_pid = 0; /* No process now */
}
#else
static void
sparclet_xmodem_load (desc, file, hashmark)
serial_t desc;
char *file;
int hashmark;
{
bfd *abfd;
asection *s;
char *buffer;
int i;
buffer = alloca (XMODEM_PACKETSIZE);
abfd = bfd_openr (file, 0);
if (!abfd)
{
printf_filtered ("Unable to open file %s\n", file);
return;
}
if (bfd_check_format (abfd, bfd_object) == 0)
{
printf_filtered ("File is not an object file\n");
return;
}
for (s = abfd->sections; s; s = s->next)
if (s->flags & SEC_LOAD)
{
bfd_size_type section_size;
printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, s->vma,
s->vma + s->_raw_size);
gdb_flush (gdb_stdout);
monitor_printf (current_monitor->load, s->vma);
if (current_monitor->loadresp)
monitor_expect (current_monitor->loadresp, NULL, 0);
xmodem_init_xfer (desc);
section_size = bfd_section_size (abfd, s);
for (i = 0; i < section_size; i += XMODEM_DATASIZE)
{
int numbytes;
numbytes = min (XMODEM_DATASIZE, section_size - i);
bfd_get_section_contents (abfd, s, buffer + XMODEM_DATAOFFSET, i,
numbytes);
xmodem_send_packet (desc, buffer, numbytes, hashmark);
if (hashmark)
{
putchar_unfiltered ('#');
gdb_flush (gdb_stdout);
}
} /* Per-packet (or S-record) loop */
xmodem_finish_xfer (desc);
monitor_expect_prompt (NULL, 0);
putchar_unfiltered ('\n');
} /* Loadable sections */
if (hashmark)
putchar_unfiltered ('\n');
}
static void
sparclet_load (desc, file, hashmark)
serial_t desc;
char *file;
int hashmark;
{
???
}
#endif /* USE_GENERIC_LOAD */
/* This array of registers need to match the indexes used by GDB.
This exists because the various ROM monitors use different strings
than does GDB, and don't necessarily support all the registers
either. So, typing "info reg sp" becomes a "r30". */
/*PSR 0x00000080 impl ver icc AW LE EE EC EF PIL S PS ET CWP WIM
0x0 0x0 0x0 0 0 0 0 0 0x0 1 0 0 0x00 0x2
0000010
INS LOCALS OUTS GLOBALS
0 0x00000000 0x00000000 0x00000000 0x00000000
1 0x00000000 0x00000000 0x00000000 0x00000000
2 0x00000000 0x00000000 0x00000000 0x00000000
3 0x00000000 0x00000000 0x00000000 0x00000000
4 0x00000000 0x00000000 0x00000000 0x00000000
5 0x00000000 0x00001000 0x00000000 0x00000000
6 0x00000000 0x00000000 0x123f0000 0x00000000
7 0x00000000 0x00000000 0x00000000 0x00000000
pc: 0x12010000 0x00000000 unimp
npc: 0x12010004 0x00001000 unimp 0x1000
tbr: 0x00000000
y: 0x00000000
*/
/* these correspond to the offsets from tm-* files from config directories */
/* is wim part of psr?? */
/* monitor wants lower case */
static char *sparclet_regnames[NUM_REGS] = REGISTER_NAMES;
/* Define the monitor command strings. Since these are passed directly
through to a printf style function, we may include formatting
strings. We also need a CR or LF on the end. */
/* need to pause the monitor for timing reasons, so slow it down */
static char *sparclet_inits[] = {"\n\r\r\n", NULL};
static struct monitor_ops sparclet_cmds =
{
MO_CLR_BREAK_USES_ADDR
| MO_HEX_PREFIX
| MO_HANDLE_NL
| MO_NO_ECHO_ON_OPEN
| MO_NO_ECHO_ON_SETMEM
| MO_RUN_FIRST_TIME
| MO_GETMEM_READ_SINGLE, /* flags */
sparclet_inits, /* Init strings */
"cont\r", /* continue command */
"step\r", /* single step */
"\r", /* break interrupts the program */
"+bp %x\r", /* set a breakpoint */
/* can't use "br" because only 2 hw bps are supported */
"-bp %x\r", /* clear a breakpoint */
"-bp\r", /* clear all breakpoints */
NULL, /* fill (start end val) */
/* can't use "fi" because it takes words, not bytes */
{
/* ex [addr] [-n count] [-b|-s|-l] default: ex cur -n 1 -b */
"ex %x -b\r%x\rq\r", /* setmem.cmdb (addr, value) */
"ex %x -s\r%x\rq\r", /* setmem.cmdw (addr, value) */
"ex %x -l\r%x\rq\r",
NULL, /* setmem.cmdll (addr, value) */
NULL, /*": ", /* setmem.resp_delim */
NULL, /*"? ", /* setmem.term */
NULL, /*"q\r", /* setmem.term_cmd */
},
{
/* since the parsing of multiple bytes is difficult due to
interspersed addresses, we'll only read 1 value at a time,
even tho these can handle a count */
/* we can use -n to set count to read, but may have to parse? */
"ex %x -n 1 -b\r", /* getmem.cmdb (addr, #bytes) */
"ex %x -n 1 -s\r", /* getmem.cmdw (addr, #swords) */
"ex %x -n 1 -l\r", /* getmem.cmdl (addr, #words) */
NULL, /* getmem.cmdll (addr, #dwords) */
": ", /* getmem.resp_delim */
NULL, /* getmem.term */
NULL, /* getmem.term_cmd */
},
{
"reg %s 0x%x\r", /* setreg.cmd (name, value) */
NULL, /* setreg.resp_delim */
NULL, /* setreg.term */
NULL /* setreg.term_cmd */
},
{
"reg %s\r", /* getreg.cmd (name) */
": ", /* getreg.resp_delim */
NULL, /* getreg.term */
NULL, /* getreg.term_cmd */
},
"reg\r", /* dump_registers */
"\\(\\w+\\)=\\([0-9a-fA-F]+\\)", /* register_pattern */
NULL, /* supply_register */
#ifdef USE_GENERIC_LOAD
NULL, /* load_routine (defaults to SRECs) */
NULL, /* download command */
NULL, /* load response */
#else
sparclet_load, /* load_routine (defaults to SRECs) */
/* load [c|a] [s|f|r] [addr count] */
"load a s %x\r", /* download command */
"load: ", /* load response */
#endif
"monitor>", /* monitor command prompt */
/* yikes! gdb core dumps without this delimitor!! */
"\r", /* end-of-command delimitor */
NULL, /* optional command terminator */
&sparclet_ops, /* target operations */
SERIAL_1_STOPBITS, /* number of stop bits */
sparclet_regnames, /* registers names */
MONITOR_OPS_MAGIC /* magic */
};
static void
sparclet_open (args, from_tty)
char *args;
int from_tty;
{
monitor_open (args, &sparclet_cmds, from_tty);
}
void
_initialize_sparclet ()
{
init_monitor_ops (&sparclet_ops);
sparclet_ops.to_shortname = "sparclet"; /* for the target command */
sparclet_ops.to_longname = "SPARC Sparclet monitor";
#ifdef USE_GENERIC_LOAD
sparclet_ops.to_load = sparclet_load_gen; /* FIXME - should go back and try "do" */
#endif
#ifdef USE_SW_BREAKS
/* use SW breaks; target only supports 2 HW breakpoints */
sparclet_ops.to_insert_breakpoint = memory_insert_breakpoint;
sparclet_ops.to_remove_breakpoint = memory_remove_breakpoint;
#endif
sparclet_ops.to_doc =
"Use a board running the Sparclet debug monitor.\n\
Specify the serial device it is connected to (e.g. /dev/ttya).";
sparclet_ops.to_open = sparclet_open;
add_target (&sparclet_ops);
}

View file

@ -657,6 +657,8 @@ symbol_file_add (name, from_tty, addr, mainline, mapped, readnow)
new_symfile_objfile (objfile, mainline, from_tty);
target_new_objfile (objfile);
return (objfile);
}
@ -920,6 +922,16 @@ generic_load (filename, from_tty)
bfd *loadfile_bfd;
time_t start_time, end_time; /* Start and end times of download */
unsigned long data_count = 0; /* Number of bytes transferred to memory */
int n;
unsigned long load_offset = 0; /* offset to add to vma for each section */
char buf[128];
/* enable user to specify address for downloading as 2nd arg to load */
n = sscanf(filename, "%s 0x%x", buf, &load_offset);
if (n > 1 )
filename = buf;
else
load_offset = 0;
loadfile_bfd = bfd_openr (filename, gnutarget);
if (loadfile_bfd == NULL)
@ -959,6 +971,7 @@ generic_load (filename, from_tty)
old_chain = make_cleanup (free, buffer);
vma = bfd_get_section_vma (loadfile_bfd, s);
vma += load_offset;
/* Is this really necessary? I guess it gives the user something
to look at during a long download. */
@ -979,6 +992,8 @@ generic_load (filename, from_tty)
end_time = time (NULL);
printf_filtered ("Start address 0x%lx\n", loadfile_bfd->start_address);
/* We were doing this in remote-mips.c, I suspect it is right
for other targets too. */
write_pc (loadfile_bfd->start_address);
@ -1424,6 +1439,7 @@ clear_symtab_users ()
current_source_symtab = 0;
current_source_line = 0;
clear_pc_function_cache ();
target_new_objfile (NULL);
}
/* clear_symtab_users_once:
@ -1654,35 +1670,42 @@ start_psymtab_common (objfile, section_offsets,
return (psymtab);
}
/* Debugging versions of functions that are usually inline macros
(see symfile.h). */
#if !INLINE_ADD_PSYMBOL
/* Add a symbol with a long value to a psymtab.
Since one arg is a struct, we pass in a ptr and deref it (sigh). */
void
add_psymbol_to_list (name, namelength, namespace, class, list, val, language,
objfile)
add_psymbol_to_list (name, namelength, namespace, class, list, val, coreaddr,
language, objfile)
char *name;
int namelength;
namespace_enum namespace;
enum address_class class;
struct psymbol_allocation_list *list;
long val;
long val; /* Value as a long */
CORE_ADDR coreaddr; /* Value as a CORE_ADDR */
enum language language;
struct objfile *objfile;
{
register struct partial_symbol *psym;
char *buf = alloca (namelength + 1);
struct partial_symbol psymbol;
/* psymbol is static so that there will be no uninitialized gaps in the
structure which might contain random data, causing cache misses in
bcache. */
static struct partial_symbol psymbol;
/* Create local copy of the partial symbol */
memcpy (buf, name, namelength);
buf[namelength] = '\0';
SYMBOL_NAME (&psymbol) = bcache (buf, namelength + 1, &objfile->psymbol_cache);
SYMBOL_VALUE (&psymbol) = val;
/* val and coreaddr are mutually exclusive, one of them *will* be zero */
if (val != 0)
{
SYMBOL_VALUE (&psymbol) = val;
}
else
{
SYMBOL_VALUE_ADDRESS (&psymbol) = coreaddr;
}
SYMBOL_SECTION (&psymbol) = 0;
SYMBOL_LANGUAGE (&psymbol) = language;
PSYMBOL_NAMESPACE (&psymbol) = namespace;
@ -1701,49 +1724,6 @@ add_psymbol_to_list (name, namelength, namespace, class, list, val, language,
OBJSTAT (objfile, n_psyms++);
}
/* Add a symbol with a CORE_ADDR value to a psymtab. */
void
add_psymbol_addr_to_list (name, namelength, namespace, class, list, val,
language, objfile)
char *name;
int namelength;
namespace_enum namespace;
enum address_class class;
struct psymbol_allocation_list *list;
CORE_ADDR val;
enum language language;
struct objfile *objfile;
{
register struct partial_symbol *psym;
char *buf = alloca (namelength + 1);
struct partial_symbol psymbol;
/* Create local copy of the partial symbol */
memcpy (buf, name, namelength);
buf[namelength] = '\0';
SYMBOL_NAME (&psymbol) = bcache (buf, namelength + 1, &objfile->psymbol_cache);
SYMBOL_VALUE_ADDRESS (&psymbol) = val;
SYMBOL_SECTION (&psymbol) = 0;
SYMBOL_LANGUAGE (&psymbol) = language;
PSYMBOL_NAMESPACE (&psymbol) = namespace;
PSYMBOL_CLASS (&psymbol) = class;
SYMBOL_INIT_LANGUAGE_SPECIFIC (&psymbol, language);
/* Stash the partial symbol away in the cache */
psym = bcache (&psymbol, sizeof (struct partial_symbol), &objfile->psymbol_cache);
/* Save pointer to partial symbol in psymtab, growing symtab if needed. */
if (list->next >= list->list + list->size)
{
extend_psymbol_list (list, objfile);
}
*list->next++ = psym;
OBJSTAT (objfile, n_psyms++);
}
#endif /* !INLINE_ADD_PSYMBOL */
/* Initialize storage for partial symbols. */
void