aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Manson <manson@cygnus>1998-05-08 05:30:24 +0000
committerBob Manson <manson@cygnus>1998-05-08 05:30:24 +0000
commit1e9c814fb93ece8958aec6810e4e2e3c3859aa1a (patch)
tree3ddeb2374dee651948ea8ae15d59978385842fd7
parentd67094c6214f66773176d9a2dcb44a6971e25385 (diff)
downloadgdb-1e9c814fb93ece8958aec6810e4e2e3c3859aa1a.zip
gdb-1e9c814fb93ece8958aec6810e4e2e3c3859aa1a.tar.gz
gdb-1e9c814fb93ece8958aec6810e4e2e3c3859aa1a.tar.bz2
* config/sparc/tm-sp64.h (CALL_DUMMY): Store and retrieve
%o0-%o5 as 64-bit values; compensate for stack bias. (USE_STRUCT_CONVENTION): We only pass pointers to structs if they're larger than 32 bytes. (REG_STRUCT_HAS_ADDR): Ditto. * sparc-tdep.c (sparc_init_extra_frame_info): Use read_sp() instead of read_register. If the target is a sparc64 and the frame pointer is odd, compensate for the stack bias. (get_saved_register): Use read_sp(). (DUMMY_STACK_REG_BUF_SIZE): Use FP_REGISTER_BYTES. (sparc_push_dummy_frame): Use read_sp()/write_sp(). On sparc64, save the PC, NPC, CCR, FSR, FPRS, Y and ASI registers. (sparc_frame_find_saved_regs): Use read_sp(). Read the PC, NPC, CCR, FSR, FPRS, Y and ASI registers from the frame, if it's a dummy frame. (sparc_pop_frame): Use write_sp(). If the target is a sparc64 and the FP is odd, compensate for stack bias. (sparc_store_return_value): Right-justify the return value before writing it to %o0. (sparc_fix_call_dummy): Don't NOP out part of the call dummy on sparc64. (sparc64_read_sp, sparc64_read_fp, sparc64_write_sp, sparc64_write_fp, sp64_push_arguments, sparc64_extract_return_value): New functions to support the sparc64 ABI. * dwarfread.c (handle_producer): Set processing_gcc_compilation to the right version number. * dwarf2read.c (read_file_scope): Assume we're processing GCC2 output.
-rw-r--r--gdb/config/sparc/tm-sp64.h119
-rw-r--r--gdb/config/sparc/tm-sparc.h5
-rw-r--r--gdb/dwarf2read.c2
-rw-r--r--gdb/dwarfread.c15
4 files changed, 132 insertions, 9 deletions
diff --git a/gdb/config/sparc/tm-sp64.h b/gdb/config/sparc/tm-sp64.h
index c35a458..7f48bdc 100644
--- a/gdb/config/sparc/tm-sp64.h
+++ b/gdb/config/sparc/tm-sp64.h
@@ -1,8 +1,9 @@
/* Target machine sub-parameters for SPARC64, for GDB, the GNU debugger.
This is included by other tm-*.h files to define SPARC64 cpu-related info.
- Copyright 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright 1994, 1995, 1996, 1998 Free Software Foundation, Inc.
This is (obviously) based on the SPARC Vn (n<9) port.
Contributed by Doug Evans (dje@cygnus.com).
+ Further modified by Bob Manson (manson@cygnus.com).
This file is part of GDB.
@@ -22,6 +23,80 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define GDB_TARGET_IS_SPARC64
+#ifdef __STDC__
+struct value;
+#endif
+
+/* Eeeew. Ok, we have to assume (for now) that the processor really is
+ in sparc64 mode. While this is the same instruction sequence as
+ on the Sparc, the stack frames are offset by +2047 (and the arguments
+ are 8 bytes instead of 4). */
+/* Instructions are:
+ std %f10, [ %fp + 0x7a7 ]
+ std %f8, [ %fp + 0x79f ]
+ std %f6, [ %fp + 0x797 ]
+ std %f4, [ %fp + 0x78f ]
+ std %f2, [ %fp + 0x787 ]
+ std %f0, [ %fp + 0x77f ]
+ std %g6, [ %fp + 0x777 ]
+ std %g4, [ %fp + 0x76f ]
+ std %g2, [ %fp + 0x767 ]
+ std %g0, [ %fp + 0x75f ]
+ std %fp, [ %fp + 0x757 ]
+ std %i4, [ %fp + 0x74f ]
+ std %i2, [ %fp + 0x747 ]
+ std %i0, [ %fp + 0x73f ]
+ nop
+ nop
+ nop
+ nop
+ rd %tbr, %o0
+ st %o0, [ %fp + 0x72b ]
+ rd %tpc, %o0
+ st %o0, [ %fp + 0x727 ]
+ rd %psr, %o0
+ st %o0, [ %fp + 0x723 ]
+ rd %y, %o0
+ st %o0, [ %fp + 0x71f ]
+ ldx [ %sp + 0x8a7 ], %o5
+ ldx [ %sp + 0x89f ], %o4
+ ldx [ %sp + 0x897 ], %o3
+ ldx [ %sp + 0x88f ], %o2
+ ldx [ %sp + 0x887 ], %o1
+ call %g0
+ ldx [ %sp + 0x87f ], %o0
+ nop
+ ta 1
+ nop
+ nop
+ */
+
+#define CALL_DUMMY { 0x9de3bec0fd3fa7f7LL, 0xf93fa7eff53fa7e7LL,\
+ 0xf13fa7dfed3fa7d7LL, 0xe93fa7cfe53fa7c7LL,\
+ 0xe13fa7bfdd3fa7b7LL, 0xd93fa7afd53fa7a7LL,\
+ 0xd13fa79fcd3fa797LL, 0xc93fa78fc53fa787LL,\
+ 0xc13fa77fcc3fa777LL, 0xc83fa76fc43fa767LL,\
+ 0xc03fa75ffc3fa757LL, 0xf83fa74ff43fa747LL,\
+ 0xf03fa73f01000000LL, 0x0100000001000000LL,\
+ 0x0100000091580000LL, 0xd027a72b93500000LL,\
+ 0xd027a72791480000LL, 0xd027a72391400000LL,\
+ 0xd027a71fda5ba8a7LL, 0xd85ba89fd65ba897LL,\
+ 0xd45ba88fd25ba887LL, 0x9fc02000d05ba87fLL,\
+ 0x0100000091d02001LL, 0x0100000001000000LL }
+
+
+/* 128 is to reserve space to write the %i/%l registers that will be restored
+ when we resume. */
+#define CALL_DUMMY_STACK_ADJUST 128
+
+#define CALL_DUMMY_LENGTH 192
+
+#define CALL_DUMMY_START_OFFSET 148
+
+#define CALL_DUMMY_CALL_OFFSET (CALL_DUMMY_START_OFFSET + (5 * 4))
+
+#define CALL_DUMMY_BREAKPOINT_OFFSET (CALL_DUMMY_START_OFFSET + (8 * 4))
+
#include "sparc/tm-sparc.h"
/* Stack must be aligned on 128-bit boundaries when synthesizing
@@ -210,6 +285,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#undef TARGET_PTR_BIT
#define TARGET_PTR_BIT 64
+/* Longs are 64 bits. */
+#undef TARGET_LONG_BIT
+#define TARGET_LONG_BIT 64
+
+#undef TARGET_LONG_LONG_BIT
+#define TARGET_LONG_LONG_BIT 64
+
/* Does the specified function use the "struct returning" convention
or the "value returning" convention? The "value returning" convention
almost invariably returns the entire value in registers. The
@@ -219,12 +301,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
Since this sometimes depends on whether it was compiled with GCC,
this is also an argument. This is used in call_function to build a
- stack, and in value_being_returned to print return values.
+ stack, and in value_being_returned to print return values.
+
+ On Sparc64, we only pass pointers to structs if they're larger then
+ 32 bytes. Otherwise they're stored in %o0-%o3 (floating-point
+ values go into %fp0-%fp3). */
- On sparc64, all structs are returned via a pointer. */
#undef USE_STRUCT_CONVENTION
-#define USE_STRUCT_CONVENTION(gcc_p, type) 1
+#define USE_STRUCT_CONVENTION(gcc_p, type) (TYPE_LENGTH (type) > 32)
+
+#undef REG_STRUCT_HAS_ADDR
+#define REG_STRUCT_HAS_ADDR(gcc_p,type) (TYPE_LENGTH (type) > 32)
/* Store the address of the place in which to copy the structure the
subroutine will return. This is called from call_function. */
@@ -281,3 +369,26 @@ extern int
get_longjmp_target PARAMS ((CORE_ADDR *));
#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
+
+extern CORE_ADDR sparc64_read_sp ();
+extern CORE_ADDR sparc64_read_fp ();
+extern void sparc64_write_sp PARAMS ((CORE_ADDR));
+extern void sparc64_write_fp PARAMS ((CORE_ADDR));
+
+#define TARGET_READ_SP() (sparc64_read_sp ())
+#define TARGET_READ_FP() (sparc64_read_fp ())
+#define TARGET_WRITE_SP(X) (sparc64_write_sp (X))
+#define TARGET_WRITE_FP(X) (sparc64_write_fp (X))
+
+#undef TM_PRINT_INSN_MACH
+#define TM_PRINT_INSN_MACH bfd_mach_sparc_v9a
+
+CORE_ADDR sp64_push_arguments PARAMS ((int, struct value **, CORE_ADDR, unsigned char, CORE_ADDR));
+#undef PUSH_ARGUMENTS
+#define PUSH_ARGUMENTS(A,B,C,D,E) (sp = sp64_push_arguments ((A), (B), (C), (D), (E)))
+
+#undef EXTRACT_RETURN_VALUE
+#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
+ sparc64_extract_return_value(TYPE, REGBUF, VALBUF, 0)
+extern void
+sparc64_extract_return_value PARAMS ((struct type *, char [], char *, int));
diff --git a/gdb/config/sparc/tm-sparc.h b/gdb/config/sparc/tm-sparc.h
index 618fce4..aaadc6b 100644
--- a/gdb/config/sparc/tm-sparc.h
+++ b/gdb/config/sparc/tm-sparc.h
@@ -251,7 +251,8 @@ 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_by_hand. */
+ subroutine will return. This is called from call_function_by_hand.
+ The ultimate mystery is, tho, what is the value "16"? */
#define STORE_STRUCT_RETURN(ADDR, SP) \
{ char val[4]; \
@@ -466,6 +467,7 @@ extern CORE_ADDR sparc_frame_saved_pc PARAMS ((struct frame_info *));
void sparc_push_dummy_frame PARAMS ((void)), sparc_pop_frame PARAMS ((void));
+#ifndef CALL_DUMMY
/* This sequence of words is the instructions
0: mov %g1, %fp
@@ -515,6 +517,7 @@ void sparc_push_dummy_frame PARAMS ((void)), sparc_pop_frame PARAMS ((void));
#define CALL_DUMMY_STACK_ADJUST 68
+#endif
/* Insert the specified number of args and function address
into a call sequence of the above form stored at DUMMYNAME. */
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index b01c990..b6162d4 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -1513,6 +1513,8 @@ read_file_scope (die, objfile)
set_cu_language (DW_UNSND (attr));
}
+ /* We assume that we're processing GCC output. */
+ processing_gcc_compilation = 2;
#if 0
/* FIXME:Do something here. */
if (dip->at_producer != NULL)
diff --git a/gdb/dwarfread.c b/gdb/dwarfread.c
index 323ceaf..eb95b1a 100644
--- a/gdb/dwarfread.c
+++ b/gdb/dwarfread.c
@@ -1902,10 +1902,17 @@ handle_producer (producer)
/* If this compilation unit was compiled with g++ or gcc, then set the
processing_gcc_compilation flag. */
- processing_gcc_compilation =
- STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER))
- || STREQN (producer, CHILL_PRODUCER, strlen (CHILL_PRODUCER))
- || STREQN (producer, GCC_PRODUCER, strlen (GCC_PRODUCER));
+ if (STREQN (producer, GCC_PRODUCER, strlen (GCC_PRODUCER)))
+ {
+ char version = producer[strlen (GCC_PRODUCER)];
+ processing_gcc_compilation = (version == '2' ? 2 : 1);
+ }
+ else
+ {
+ processing_gcc_compilation =
+ STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER))
+ || STREQN (producer, CHILL_PRODUCER, strlen (CHILL_PRODUCER));
+ }
/* Select a demangling style if we can identify the producer and if
the current style is auto. We leave the current style alone if it