* sparc-tdep.c (sparc_extract_struct_value_address): Make it

work correctly on little-endian hosts.
	(sparc_push_arguments): New function.
	(gdb_print_insn_sparc): New function.
	(_initialize_sparc_tdep): Make gdb_print_insn_sparc the default
	disassembler, so that SPARClite-specific instructions will
	be recognized.
	* sparcl-tdep.c (readchar): Print debugging information.
	(debug_serial_write): New function, a replacement for SERIAL_WRITE
	that prints debugging information.
	* config/sparc/tm-sparc.h (PUSH_ARGUMENTS): Define.
	(sparc_push_arguments): Declare.
This commit is contained in:
Mark Alexander 1998-04-15 00:25:58 +00:00
parent 93f967158f
commit e50f526e68
4 changed files with 194 additions and 31 deletions

View File

@ -1,3 +1,18 @@
Tue Apr 14 16:52:59 1998 Mark Alexander <marka@cygnus.com>
* sparc-tdep.c (sparc_extract_struct_value_address): Make it
work correctly on little-endian hosts.
(sparc_push_arguments): New function.
(gdb_print_insn_sparc): New function.
(_initialize_sparc_tdep): Make gdb_print_insn_sparc the default
disassembler, so that SPARClite-specific instructions will
be recognized.
* sparcl-tdep.c (readchar): Print debugging information.
(debug_serial_write): New function, a replacement for SERIAL_WRITE
that prints debugging information.
* config/sparc/tm-sparc.h (PUSH_ARGUMENTS): Define.
(sparc_push_arguments): Declare.
Tue Apr 14 15:43:49 1998 John Metzler <jmetzler@cygnus.com>
* gdbcfgxref (xref_menu): Call new regex and wild card searches
@ -95,7 +110,6 @@ Wed Apr 8 16:47:33 1998 Jason Molenda (crash@bugshack.cygnus.com)
* breakpoint.c (breakpoint_re_set_one): Remove Ulrich Drepper's
patch of March 23 1998.
>>>>>>> 1.4385
Sat Apr 4 10:05:00 1998 Dawn Perchik <dawn@cygnus.com>
* mdebugread.c (parse_partial_symbols): If this is an .mdebug

View File

@ -245,7 +245,7 @@ extern CORE_ADDR sparc_pc_adjust PARAMS ((CORE_ADDR));
#define CANNOT_STORE_REGISTER(regno) ((regno) == G0_REGNUM)
/* Store the address of the place in which to copy the structure the
subroutine will return. This is called from call_function. */
subroutine will return. This is called from call_function_by_hand. */
#define STORE_STRUCT_RETURN(ADDR, SP) \
{ char val[4]; \
@ -648,3 +648,15 @@ extern int deferred_stores;
/* Select the sparc disassembler */
#define TM_PRINT_INSN_MACH bfd_mach_sparc
/* Arguments smaller than an int must promoted to ints when synthesizing
function calls. */
#ifdef __STDC__
struct value;
#endif
#define PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr) \
sp = sparc_push_arguments((nargs), (args), (sp), (struct_return), (struct_addr))
extern CORE_ADDR
sparc_push_arguments PARAMS ((int, struct value **, CORE_ADDR, int, CORE_ADDR));

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, 1996
Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997
Free Software Foundation, Inc.
This file is part of GDB.
@ -27,6 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "target.h"
#include "value.h"
#include "bfd.h"
#include "gdb_string.h"
#ifdef USE_PROC_FS
#include <sys/procfs.h>
@ -75,14 +76,12 @@ int deferred_stores = 0; /* Cumulates stores we want to do eventually. */
/* Sign extension macros. */
#define X_SIMM13(i) ((X_IMM13 (i) ^ 0x1000) - 0x1000)
#define X_DISP22(i) ((X_IMM22 (i) ^ 0x200000) - 0x200000)
#ifdef GDB_TARGET_IS_SPARC64
#define X_CC(i) (((i) >> 20) & 3)
#define X_P(i) (((i) >> 19) & 1)
#define X_DISP19(i) ((((i) & 0x7ffff) ^ 0x40000) - 0x40000)
#define X_RCOND(i) (((i) >> 25) & 7)
#define X_DISP16(i) ((((((i) >> 6) && 0xc000) | ((i) & 0x3fff)) ^ 0x8000) - 0x8000)
#define X_FCN(i) (((i) >> 25) & 31)
#endif
typedef enum
{
@ -109,6 +108,8 @@ static binsn_quantum break_mem[3];
int one_stepped;
static branch_type isbranch PARAMS ((long, CORE_ADDR, CORE_ADDR *));
/* single_step() is called just before we want to resume the inferior,
if we want to single-step it but there is no hardware or kernel single-step
support (as on all SPARCs). We find all the possible targets of the
@ -119,9 +120,9 @@ int one_stepped;
void
single_step (ignore)
int ignore; /* pid, but we don't need it */
enum target_signal ignore; /* pid, but we don't need it */
{
branch_type br, isbranch();
branch_type br;
CORE_ADDR pc;
long pc_instruction;
@ -206,14 +207,24 @@ sparc_init_extra_frame_info (fromleaf, fi)
if (fi->next)
{
char buf[MAX_REGISTER_RAW_SIZE];
int err;
/* Compute ->frame as if not flat. If it is flat, we'll change
it later. */
/* FIXME: If error reading memory, should just stop backtracing, rather
than error(). */
get_saved_register (buf, 0, 0, fi, FP_REGNUM, 0);
fi->frame = extract_address (buf, REGISTER_RAW_SIZE (FP_REGNUM));
if (fi->next->next != NULL
&& (fi->next->next->signal_handler_caller
|| frame_in_dummy (fi->next->next))
&& frameless_look_for_prologue (fi->next))
{
/* A frameless function interrupted by a signal did not change
the frame pointer, fix up frame pointer accordingly. */
fi->frame = FRAME_FP (fi->next);
fi->bottom = fi->next->bottom;
}
else
{
get_saved_register (buf, 0, 0, fi, FP_REGNUM, 0);
fi->frame = extract_address (buf, REGISTER_RAW_SIZE (FP_REGNUM));
}
}
/* Decide whether this is a function with a ``flat register window''
@ -289,7 +300,9 @@ sparc_extract_struct_value_address (regbuf)
return extract_address (regbuf + REGISTER_BYTE (O0_REGNUM),
REGISTER_RAW_SIZE (O0_REGNUM));
#else
return read_memory_integer (((int *)(regbuf)) [SP_REGNUM] + (16 * SPARC_INTREG_SIZE),
CORE_ADDR sp = extract_address (&regbuf [REGISTER_BYTE (SP_REGNUM)],
REGISTER_RAW_SIZE (SP_REGNUM));
return read_memory_integer (sp + (16 * SPARC_INTREG_SIZE),
TARGET_PTR_BIT / TARGET_CHAR_BIT);
#endif
}
@ -335,6 +348,17 @@ sparc_frame_saved_pc (frame)
scbuf, sizeof (scbuf));
return extract_address (scbuf, sizeof (scbuf));
}
else if (frame->next != NULL
&& (frame->next->signal_handler_caller
|| frame_in_dummy (frame->next))
&& frameless_look_for_prologue (frame))
{
/* A frameless function interrupted by a signal did not save
the PC, it is still in %o7. */
get_saved_register (buf, (int *)NULL, (CORE_ADDR *)NULL,
frame, O7_REGNUM, (enum lval_type *)NULL);
return PC_ADJUST (extract_address (buf, SPARC_INTREG_SIZE));
}
if (frame->flat)
addr = frame->pc_addr;
else
@ -517,24 +541,23 @@ skip_prologue (start_pc, frameless_p)
This isn't static as it's used by remote-sa.sparc.c. */
branch_type
static branch_type
isbranch (instruction, addr, target)
long instruction;
CORE_ADDR addr, *target;
{
branch_type val = not_branch;
long int offset; /* Must be signed for sign-extend. */
long int offset = 0; /* Must be signed for sign-extend. */
*target = 0;
if (X_OP (instruction) == 0
&& (X_OP2 (instruction) == 2
|| X_OP2 (instruction) == 6
#ifdef GDB_TARGET_IS_SPARC64
|| X_OP2 (instruction) == 1
|| X_OP2 (instruction) == 3
|| X_OP2 (instruction) == 5
#else
#ifndef GDB_TARGET_IS_SPARC64
|| X_OP2 (instruction) == 7
#endif
))
@ -552,7 +575,6 @@ isbranch (instruction, addr, target)
#endif
offset = 4 * X_DISP22 (instruction);
break;
#ifdef GDB_TARGET_IS_SPARC64
case 1:
case 5:
offset = 4 * X_DISP19 (instruction);
@ -560,7 +582,6 @@ isbranch (instruction, addr, target)
case 3:
offset = 4 * X_DISP16 (instruction);
break;
#endif
}
*target = addr + offset;
}
@ -630,6 +651,22 @@ get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
frame1 = frame->next;
/* Get saved PC from the frame info if not in innermost frame. */
if (regnum == PC_REGNUM && frame1 != NULL)
{
if (lval != NULL)
*lval = not_lval;
if (raw_buffer != NULL)
{
/* Put it back in target format. */
store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), frame->pc);
}
if (addrp != NULL)
*addrp = 0;
return;
}
while (frame1 != NULL)
{
if (frame1->pc >= (frame1->bottom ? frame1->bottom :
@ -863,27 +900,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
- (FP_REGISTER_BYTES + 8 * SPARC_INTREG_SIZE);
- DUMMY_STACK_REG_BUF_SIZE + 16 * 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
- (FP_REGISTER_BYTES + 16 * SPARC_INTREG_SIZE);
- DUMMY_STACK_REG_BUF_SIZE + 8 * 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
- (FP_REGISTER_BYTES);
- DUMMY_STACK_REG_BUF_SIZE + 24 * SPARC_INTREG_SIZE;
#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);
- DUMMY_STACK_REG_BUF_SIZE + 24 * SPARC_INTREG_SIZE;
#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;
- (FP_REGISTER_BYTES + 24 * SPARC_INTREG_SIZE);
frame_addr + (regnum - Y_REGNUM) * SPARC_INTREG_SIZE
- DUMMY_STACK_REG_BUF_SIZE;
frame_addr = fi->bottom ?
fi->bottom : read_register (SP_REGNUM);
}
@ -1094,7 +1131,7 @@ sparc_pc_adjust(pc)
char buf[4];
int err;
err = target_read_memory (pc + 8, buf, sizeof(long));
err = target_read_memory (pc + 8, buf, 4);
insn = extract_unsigned_integer (buf, 4);
if ((err == 0) && (insn & 0xffc00000) == 0)
return pc+12;
@ -1409,7 +1446,7 @@ void
sparc_print_register_hook (regno)
int regno;
{
unsigned LONGEST val;
ULONGEST val;
/* Handle double/quad versions of lower 32 fp regs. */
if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32
@ -1546,9 +1583,82 @@ sparc_print_register_hook (regno)
#endif
int
gdb_print_insn_sparc (memaddr, info)
bfd_vma memaddr;
disassemble_info *info;
{
/* It's necessary to override mach again because print_insn messes it up. */
info->mach = TM_PRINT_INSN_MACH;
return print_insn_sparc (memaddr, info);
}
/* The SPARC passes the arguments on the stack; arguments smaller
than an int are promoted to an int. */
CORE_ADDR
sparc_push_arguments (nargs, args, sp, struct_return, struct_addr)
int nargs;
value_ptr *args;
CORE_ADDR sp;
int struct_return;
CORE_ADDR struct_addr;
{
int i;
int accumulate_size = 0;
struct sparc_arg
{
char *contents;
int len;
int offset;
};
struct sparc_arg *sparc_args =
(struct sparc_arg*)alloca (nargs * sizeof (struct sparc_arg));
struct sparc_arg *m_arg;
/* Promote arguments if necessary, and calculate their stack offsets
and sizes. */
for (i = 0, m_arg = sparc_args; i < nargs; i++, m_arg++)
{
value_ptr arg = args[i];
struct type *arg_type = check_typedef (VALUE_TYPE (arg));
/* Cast argument to long if necessary as the compiler does it too. */
switch (TYPE_CODE (arg_type))
{
case TYPE_CODE_INT:
case TYPE_CODE_BOOL:
case TYPE_CODE_CHAR:
case TYPE_CODE_RANGE:
case TYPE_CODE_ENUM:
if (TYPE_LENGTH (arg_type) < TYPE_LENGTH (builtin_type_long))
{
arg_type = builtin_type_long;
arg = value_cast (arg_type, arg);
}
break;
default:
break;
}
m_arg->len = TYPE_LENGTH (arg_type);
m_arg->offset = accumulate_size;
accumulate_size = (accumulate_size + m_arg->len + 3) & ~3;
m_arg->contents = VALUE_CONTENTS(arg);
}
/* Make room for the arguments on the stack. */
accumulate_size += CALL_DUMMY_STACK_ADJUST;
sp = ((sp - accumulate_size) & ~7) + CALL_DUMMY_STACK_ADJUST;
/* `Push' arguments on the stack. */
for (i = nargs; m_arg--, --i >= 0; )
write_memory(sp + m_arg->offset, m_arg->contents, m_arg->len);
return sp;
}
void
_initialize_sparc_tdep ()
{
tm_print_insn = print_insn_sparc;
tm_print_insn = gdb_print_insn_sparc;
tm_print_insn_info.mach = TM_PRINT_INSN_MACH; /* Selects sparc/sparclite */
}

View File

@ -302,6 +302,7 @@ readchar (desc, timeout)
int timeout;
{
int ch;
char s[10];
ch = SERIAL_READCHAR (desc, timeout);
@ -314,16 +315,42 @@ readchar (desc, timeout)
case SERIAL_TIMEOUT:
error ("SPARClite remote timeout");
default:
if (remote_debug > 0)
{
sprintf (s, "[%02x]", ch & 0xff);
puts_debug ("read -->", s, "<--");
}
return ch;
}
}
static void
debug_serial_write (desc, buf, len)
serial_t desc;
char *buf;
int len;
{
char s[10];
SERIAL_WRITE (desc, buf, len);
if (remote_debug > 0)
{
while (len-- > 0)
{
sprintf (s, "[%02x]", *buf & 0xff);
puts_debug ("Sent -->", s, "<--");
buf++;
}
}
}
static int
send_resp (desc, c)
serial_t desc;
char c;
{
SERIAL_WRITE (desc, &c, 1);
debug_serial_write (desc, &c, 1);
return readchar (desc, 2);
}
@ -659,7 +686,7 @@ sparclite_serial_start (entry)
buffer[0] = 0x03;
store_unsigned_integer (buffer + 1, 4, entry);
SERIAL_WRITE (remote_desc, buffer, 1 + 4);
debug_serial_write (remote_desc, buffer, 1 + 4);
i = readchar (remote_desc, 2);
if (i != 0x55)
error ("Can't start SparcLite. Error code %d\n", i);
@ -691,7 +718,7 @@ sparclite_serial_write (from_bfd, from_sec, from_addr, to_addr, len)
if (i != 0x5a)
error ("Bad response from load command (0x%x)", i);
SERIAL_WRITE (remote_desc, buffer, 4 + 4 + len);
debug_serial_write (remote_desc, buffer, 4 + 4 + len);
i = readchar (remote_desc, 2);
if (i != checksum)