aboutsummaryrefslogtreecommitdiff
path: root/gdb/hppah-tdep.c
diff options
context:
space:
mode:
authorStu Grossman <grossman@cygnus>1993-04-23 18:01:02 +0000
committerStu Grossman <grossman@cygnus>1993-04-23 18:01:02 +0000
commitb5728692b43217ea2babbe08a94552cb4b2ffeff (patch)
treec8d9bdff58794e4ef37a05faa4111665f7626829 /gdb/hppah-tdep.c
parentc156f3c1c9395bcb721678e07a5cf10b7c0d7b18 (diff)
downloadfsf-binutils-gdb-b5728692b43217ea2babbe08a94552cb4b2ffeff.zip
fsf-binutils-gdb-b5728692b43217ea2babbe08a94552cb4b2ffeff.tar.gz
fsf-binutils-gdb-b5728692b43217ea2babbe08a94552cb4b2ffeff.tar.bz2
* Fix two bugs found by deja-gnu. One is the incorrect reporting
of the PC being in a stack dummy when looking at a core file without symbols. The other is the incorrect passing of char arguments during expression evaluation (ie: p foo('a','b') would mess up the passing of it's args because it wasn't coercing the char's to ints). * hppah-tdep.c: Rename global functions to have consistent hppa_ prefix. Make more functions static. Drop hp_ prefix from static functions. (hppa_push_arguments): Call value_arg_coerce to cast char to int args if necessary. (hppa_fix_call_dummy): Create this routine from FIX_CALL_DUMMY macro in tm-hppa.h. * inferior.h (PC_IN_CALL_DUMMY): Check for frame_address being valid (ie: != 0) before doing comparison against PC. * valops.c (call_function_by_hand): Adjust call to FIX_CALL_DUMMY to reflect new arguments. * config/pa/tm-hppa.h (POP_FRAME, PUSH_ARGUMENTS): Use new hppa_ prefix for func name. (FIX_CALL_DUMMY): Move code into hppah-tdep.c. * testsuite/gdb.t16/gdbme.c, testsuite/gdb.t17/gdbme.c: Add calls to malloc() so that we can test GDB eval of dynamically created arrays (like char strings in `print "foo"').
Diffstat (limited to 'gdb/hppah-tdep.c')
-rw-r--r--gdb/hppah-tdep.c71
1 files changed, 61 insertions, 10 deletions
diff --git a/gdb/hppah-tdep.c b/gdb/hppah-tdep.c
index 5a1227a..cd0d157 100644
--- a/gdb/hppah-tdep.c
+++ b/gdb/hppah-tdep.c
@@ -59,6 +59,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "symfile.h"
#include "objfiles.h"
+static int restore_pc_queue PARAMS ((struct frame_saved_regs *fsr));
+static int hppa_alignof PARAMS ((struct type *arg));
+
/* Routines to extract various sized constants out of hppa
instructions. */
@@ -534,7 +537,7 @@ find_dummy_frame_regs (frame, frame_saved_regs)
}
int
-hp_pop_frame ()
+hppa_pop_frame ()
{
register FRAME frame = get_current_frame ();
register CORE_ADDR fp;
@@ -548,7 +551,7 @@ hp_pop_frame ()
get_frame_saved_regs (fi, &fsr);
if (fsr.regs[IPSW_REGNUM]) /* Restoring a call dummy frame */
- hp_restore_pc_queue (&fsr);
+ restore_pc_queue (&fsr);
for (regnum = 31; regnum > 0; regnum--)
if (fsr.regs[regnum])
@@ -589,8 +592,8 @@ hp_pop_frame ()
* After returning to a dummy on the stack, restore the instruction
* queue space registers. */
-int
-hp_restore_pc_queue (fsr)
+static int
+restore_pc_queue (fsr)
struct frame_saved_regs *fsr;
{
CORE_ADDR pc = read_pc ();
@@ -638,7 +641,7 @@ hp_restore_pc_queue (fsr)
}
CORE_ADDR
-hp_push_arguments (nargs, args, sp, struct_return, struct_addr)
+hppa_push_arguments (nargs, args, sp, struct_return, struct_addr)
int nargs;
value *args;
CORE_ADDR sp;
@@ -652,11 +655,14 @@ hp_push_arguments (nargs, args, sp, struct_return, struct_addr)
for (i = 0; i < nargs; i++)
{
+ /* Coerce chars to int & float to double if necessary */
+ args[i] = value_arg_coerce (args[i]);
+
cum += TYPE_LENGTH (VALUE_TYPE (args[i]));
/* value must go at proper alignment. Assume alignment is a
power of two.*/
- alignment = hp_alignof (VALUE_TYPE (args[i]));
+ alignment = hppa_alignof (VALUE_TYPE (args[i]));
if (cum % alignment)
cum = (cum + alignment) & -alignment;
offset[i] = -cum;
@@ -672,11 +678,56 @@ hp_push_arguments (nargs, args, sp, struct_return, struct_addr)
return sp + 32;
}
+/*
+ * Insert the specified number of args and function address
+ * into a call sequence of the above form stored at DUMMYNAME.
+ *
+ * On the hppa we need to call the stack dummy through $$dyncall.
+ * Therefore our version of FIX_CALL_DUMMY takes an extra argument,
+ * real_pc, which is the location where gdb should start up the
+ * inferior to do the function call.
+ */
+
+CORE_ADDR
+hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
+ REGISTER_TYPE *dummy;
+ CORE_ADDR pc;
+ CORE_ADDR fun;
+ int nargs;
+ value *args;
+ struct type *type;
+ int gcc_p;
+{
+ CORE_ADDR dyncall_addr, sr4export_addr;
+ struct minimal_symbol *msymbol;
+
+ msymbol = lookup_minimal_symbol ("$$dyncall", (struct objfile *) NULL);
+ if (msymbol == NULL)
+ error ("Can't find an address for $$dyncall trampoline");
+
+ dyncall_addr = SYMBOL_VALUE_ADDRESS (msymbol);
+
+ msymbol = lookup_minimal_symbol ("_sr4export", (struct objfile *) NULL);
+ if (msymbol == NULL)
+ error ("Can't find an address for _sr4export trampoline");
+
+ sr4export_addr = SYMBOL_VALUE_ADDRESS (msymbol);
+
+ dummy[9] = deposit_21 (fun >> 11, dummy[9]);
+ dummy[10] = deposit_14 (fun & MASK_11, dummy[10]);
+ dummy[12] = deposit_21 (sr4export_addr >> 11, dummy[12]);
+ dummy[13] = deposit_14 (sr4export_addr & MASK_11, dummy[13]);
+
+ write_register (22, pc);
+
+ return dyncall_addr;
+}
+
/* return the alignment of a type in bytes. Structures have the maximum
alignment required by their fields. */
-int
-hp_alignof (arg)
+static int
+hppa_alignof (arg)
struct type *arg;
{
int max_align, align, i;
@@ -687,7 +738,7 @@ hp_alignof (arg)
case TYPE_CODE_FLT:
return TYPE_LENGTH (arg);
case TYPE_CODE_ARRAY:
- return hp_alignof (TYPE_FIELD_TYPE (arg, 0));
+ return hppa_alignof (TYPE_FIELD_TYPE (arg, 0));
case TYPE_CODE_STRUCT:
case TYPE_CODE_UNION:
max_align = 2;
@@ -696,7 +747,7 @@ hp_alignof (arg)
/* Bit fields have no real alignment. */
if (!TYPE_FIELD_BITPOS (arg, i))
{
- align = hp_alignof (TYPE_FIELD_TYPE (arg, i));
+ align = hppa_alignof (TYPE_FIELD_TYPE (arg, i));
max_align = max (max_align, align);
}
}