* 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:
parent
265c044ac1
commit
012be3cec3
@ -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
|
||||
|
@ -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
3
gdb/configure
vendored
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
143
gdb/sparc-tdep.c
143
gdb/sparc-tdep.c
@ -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 ()
|
||||
®ister_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),
|
||||
®ister_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
279
gdb/sparclet-rom.c
Normal 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);
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user