* buildsym.c (finish_block): Treat LOC_BASEREG_ARG and
authorStu Grossman <grossman@cygnus>
Tue, 15 Oct 1996 23:44:13 +0000 (23:44 +0000)
committerStu Grossman <grossman@cygnus>
Tue, 15 Oct 1996 23:44:13 +0000 (23:44 +0000)
LOC_LOCAL_ARG as arguments so that GDB will know about function
args declared this way.  Mostly affects dwarf.
* dwarfread.c (decode_die_type):  Change default type from int to
void.  This allows GDB to recognize void functions.
* (new_symbol):  If AT_PROTOTYPED is present, set a flag in the
type structure.
* findvar.c (extract_floating store_floating):  Clean up comments
to reflect reality.
* gdbtypes.h:  Add TYPE_FLAG_PROTOTYPED so that we can tell if a
function has a prototype.  Currently, only dwarf supports this.
* utils.c (floatformat_from_doublest):  Fix logic error with
converting from double to float.  (It wasn't shifting mant_long if
it had a hidden bit.)

* v850-tdep.c:  Add support for function calling.  Fix some
problems with debugging code w/o debug symbols.
* config/v850/tm-v850.h:  Ditto.

gdb/ChangeLog
gdb/buildsym.c
gdb/config/v850/tm-v850.h
gdb/dwarfread.c
gdb/gdbtypes.h
gdb/v850-tdep.c

index c1f5a87..1199419 100644 (file)
@@ -1,3 +1,25 @@
+Tue Oct 15 16:30:07 1996  Stu Grossman  (grossman@critters.cygnus.com)
+
+       * buildsym.c (finish_block):  Treat LOC_BASEREG_ARG and
+       LOC_LOCAL_ARG as arguments so that GDB will know about function
+       args declared this way.  Mostly affects dwarf.
+       * dwarfread.c (decode_die_type):  Change default type from int to
+       void.  This allows GDB to recognize void functions.
+       * (new_symbol):  If AT_PROTOTYPED is present, set a flag in the
+       type structure.
+       * findvar.c (extract_floating store_floating):  Clean up comments
+       to reflect reality.
+       * gdbtypes.h:  Add TYPE_FLAG_PROTOTYPED so that we can tell if a
+       function has a prototype.  Currently, only dwarf supports this.
+       * utils.c (floatformat_from_doublest):  Fix logic error with
+       converting from double to float.  (It wasn't shifting mant_long if
+       it had a hidden bit.)
+
+start-sanitize-v850
+       * v850-tdep.c:  Add support for function calling.  Fix some
+       problems with debugging code w/o debug symbols.
+       * config/v850/tm-v850.h:  Ditto.
+end-sanitize-v850
 Tue Oct 15 18:19:42 1996  Ian Lance Taylor  <ian@cygnus.com>
 
        * utils.c: Always ensure that size_t is defined.  Check
@@ -16,8 +38,8 @@ Sun Oct 13 11:38:25 1996  Peter Schauer  (pes@regent.e-technik.tu-muenchen.de)
 
 Fri Oct 11 15:43:54 1996  Stu Grossman  (grossman@critters.cygnus.com)
 
-       * frame.h:  Move definition of struct frame_saved_args to before
-       struct frame to make it possible to use frame_saved_args in
+       * frame.h:  Move definition of struct frame_saved_regs to before
+       struct frame to make it possible to use frame_saved_regs in
        EXTRA_FRAME_INFO macro.
 
 start-sanitize-v850
index e28c727..02d7dfc 100644 (file)
@@ -268,6 +268,8 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile)
                case LOC_REF_ARG:
                case LOC_REGPARM:
                case LOC_REGPARM_ADDR:
+               case LOC_BASEREG_ARG:
+               case LOC_LOCAL_ARG:
                  nparams++;
                  break;
                case LOC_UNDEF:
@@ -279,9 +281,7 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile)
                case LOC_LABEL:
                case LOC_BLOCK:
                case LOC_CONST_BYTES:
-               case LOC_LOCAL_ARG:
                case LOC_BASEREG:
-               case LOC_BASEREG_ARG:
                case LOC_UNRESOLVED:
                case LOC_OPTIMIZED_OUT:
                default:
@@ -303,6 +303,8 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile)
                    case LOC_REF_ARG:
                    case LOC_REGPARM:
                    case LOC_REGPARM_ADDR:
+                   case LOC_BASEREG_ARG:
+                   case LOC_LOCAL_ARG:
                      TYPE_FIELD_TYPE (ftype, iparams) = SYMBOL_TYPE (sym);
                      iparams++;
                      break;
@@ -315,9 +317,7 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile)
                    case LOC_LABEL:
                    case LOC_BLOCK:
                    case LOC_CONST_BYTES:
-                   case LOC_LOCAL_ARG:
                    case LOC_BASEREG:
-                   case LOC_BASEREG_ARG:
                    case LOC_UNRESOLVED:
                    case LOC_OPTIMIZED_OUT:
                    default:
index 5aa11b5..9bd1b48 100644 (file)
@@ -68,6 +68,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 struct frame_info;
 struct frame_saved_regs;
 struct type;
+struct value;
 #endif
 
 #define EXTRA_FRAME_INFO struct frame_saved_regs fsr;
@@ -106,3 +107,35 @@ extern CORE_ADDR v850_skip_prologue PARAMS ((CORE_ADDR pc));
 
 extern struct frame_info *v850_pop_frame PARAMS ((struct frame_info *frame));
 #define POP_FRAME v850_pop_frame (get_current_frame ())
+
+#define CALL_DUMMY { 0 }
+
+#define CALL_DUMMY_START_OFFSET (0)
+
+#define CALL_DUMMY_BREAKPOINT_OFFSET (0)
+
+extern void v850_push_dummy_frame PARAMS ((void));
+#define PUSH_DUMMY_FRAME v850_push_dummy_frame ()
+
+#define FIX_CALL_DUMMY(DUMMY1, START_SP, FUNADDR, NARGS, ARGS, VALUE_TYPE, USING_GCC)
+
+#define CALL_DUMMY_LOCATION AT_ENTRY_POINT
+
+#define STACK_ALIGN(x) ((x + 3) & ~3)
+
+extern CORE_ADDR
+v850_push_arguments PARAMS ((int nargs, struct value **args, CORE_ADDR sp,
+                            unsigned char struct_return,
+                            CORE_ADDR struct_addr));
+#define PUSH_ARGUMENTS(NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR) \
+  (SP) = v850_push_arguments (NARGS, ARGS, SP, STRUCT_RETURN, STRUCT_ADDR)
+
+#define STORE_STRUCT_RETURN(STRUCT_ADDR, SP)
+
+#define CALL_DUMMY_ADDRESS() (entry_point_address ())
+
+extern int v850_pc_in_call_dummy PARAMS ((CORE_ADDR pc));
+#define PC_IN_CALL_DUMMY(PC, SP, FP) v850_pc_in_call_dummy (PC)
+
+#define USE_STRUCT_CONVENTION(GCC_P, TYPE) \
+       (TYPE_NFIELDS (TYPE) > 1 || TYPE_LENGTH (TYPE) > 4)
index 98ceb49..529f01b 100644 (file)
@@ -964,7 +964,7 @@ decode_die_type (dip)
     }
   else
     {
-      type = dwarf_fundamental_type (current_objfile, FT_INTEGER);
+      type = dwarf_fundamental_type (current_objfile, FT_VOID);
     }
   return (type);
 }
@@ -2957,6 +2957,8 @@ new_symbol (dip, objfile)
        case TAG_subroutine:
          SYMBOL_VALUE_ADDRESS (sym) = dip -> at_low_pc;
          SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym));
+         if (dip -> at_prototyped)
+           TYPE_FLAGS (SYMBOL_TYPE (sym)) |= TYPE_FLAG_PROTOTYPED;
          SYMBOL_CLASS (sym) = LOC_BLOCK;
          if (dip -> die_tag == TAG_global_subroutine)
            {
index 3a40f1c..a7d8c39 100644 (file)
@@ -154,6 +154,12 @@ enum type_code
 
 #define TYPE_FLAG_TARGET_STUB (1 << 3)
 
+/* This is a function type which appears to have a prototype.  We need this
+   for function calls in order to tell us if it's necessary to coerce the args,
+   or to just do the standard conversions.  */
+
+#define TYPE_FLAG_PROTOTYPED (1 << 4)
+
 struct type
 {
 
index 7363fc2..7e6b431 100644 (file)
@@ -1,6 +1,5 @@
 /* Target-dependent code for the NEC V850 for GDB, the GNU debugger.
-   Copyright 1986, 1996
-   Free Software Foundation, Inc.
+   Copyright 1996, Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -18,8 +17,6 @@ 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.  */
 
-/* ??? Support for calling functions from gdb in sparc64 is unfinished.  */
-
 #include "defs.h"
 #include "frame.h"
 #include "inferior.h"
@@ -28,9 +25,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "value.h"
 #include "bfd.h"
 #include "gdb_string.h"
-
 #include "gdbcore.h"
 
+struct dummy_frame
+{
+  struct dummy_frame *next;
+
+  CORE_ADDR fp;
+  CORE_ADDR sp;
+  CORE_ADDR rp;
+  CORE_ADDR pc;
+};
+
+static struct dummy_frame *dummy_frame_stack = NULL;
 \f
 /* This function actually figures out the frame address for a given pc and
    sp.  This is tricky on the v850 because we only use an explicit frame
@@ -49,7 +56,7 @@ v850_init_extra_frame_info (fi)
   int framereg;
 
   if (fi->next)
-    fi->pc = v850_find_callers_reg (fi->next, RP_REGNUM);
+    fi->pc = FRAME_SAVED_PC (fi->next);
 
   /* First, figure out the bounds of the prologue so that we can limit the
      search to something reasonable.  */
@@ -58,7 +65,10 @@ v850_init_extra_frame_info (fi)
     {
       sal = find_pc_line (func_addr, 0);
 
-      prologue_end = sal.end;
+      if (sal.line == 0)
+       prologue_end = fi->pc;
+      else
+       prologue_end = sal.end;
     }
   else
     prologue_end = func_addr + 100; /* We're in the boondocks */
@@ -108,21 +118,10 @@ v850_init_extra_frame_info (fi)
        }
     }
 
-#if 0
-  if (!fi->next)
-    fi->frame = read_register (framereg);
-  else
-    if (framereg == SP_REGNUM)
-      fi->frame = fi->next->frame;
-    else
-      fi->frame = v850_find_callers_reg (fi, framereg);
-
-  if (framereg == SP_REGNUM)
-    fi->frame -= frameoffset;
-#else
-  if (!fi->next && framereg == SP_REGNUM)
+  if (PC_IN_CALL_DUMMY (fi->pc, NULL, NULL))
+    fi->frame = dummy_frame_stack->sp;
+  else if (!fi->next && framereg == SP_REGNUM)
     fi->frame = read_register (framereg) - frameoffset;
-#endif
 
   for (reg = 0; reg < NUM_REGS; reg++)
     if (fi->fsr.regs[reg] != 0)
@@ -137,6 +136,24 @@ v850_find_callers_reg (fi, regnum)
      struct frame_info *fi;
      int regnum;
 {
+  /* XXX - Won't work if multiple dummy frames are active */
+  if (PC_IN_CALL_DUMMY (fi->pc, NULL, NULL))
+    switch (regnum)
+      {
+      case SP_REGNUM:
+       return dummy_frame_stack->sp;
+       break;
+      case FP_REGNUM:
+       return dummy_frame_stack->fp;
+       break;
+      case RP_REGNUM:
+       return dummy_frame_stack->pc;
+       break;
+      case PC_REGNUM:
+       return dummy_frame_stack->pc;
+       break;
+      }
+
   for (; fi; fi = fi->next)
     if (fi->fsr.regs[regnum] != 0)
       return read_memory_integer (fi->fsr.regs[regnum], 4);
@@ -149,13 +166,15 @@ v850_frame_chain (fi)
      struct frame_info *fi;
 {
   CORE_ADDR callers_pc, callers_sp;
-  struct frame_info temp_fi;
   CORE_ADDR func_addr, prologue_end, current_pc;
   int frameoffset;
 
   /* First, find out who called us */
 
-  callers_pc = v850_find_callers_reg (fi, RP_REGNUM);
+  callers_pc = FRAME_SAVED_PC (fi);
+
+  if (PC_IN_CALL_DUMMY (callers_pc, NULL, NULL))
+    return dummy_frame_stack->sp; /* XXX Won't work if multiple dummy frames on stack! */
 
   /* Next, figure out where his prologue is.  */
 
@@ -163,9 +182,16 @@ v850_frame_chain (fi)
     {
       struct symtab_and_line sal;
 
+      /* Stop when the caller is the entry point function */
+      if (func_addr == entry_point_address ())
+       return 0;
+
       sal = find_pc_line (func_addr, 0);
 
-      prologue_end = sal.end;
+      if (sal.line == 0)
+       prologue_end = callers_pc;
+      else
+       prologue_end = sal.end;
     }
   else
     prologue_end = func_addr + 100; /* We're in the boondocks */
@@ -217,11 +243,12 @@ v850_skip_prologue (pc)
 
       sal = find_pc_line (func_addr, 0);
 
-      if (sal.end < func_end)
+      if (sal.line != 0 && sal.end < func_end)
        return sal.end;
       else
-       /* The line after the prologue is after the end of the function.  In
-          this case, there probably isn't a prologue.  */
+       /* Either there's no line info, or the line after the prologue is after
+          the end of the function.  In this case, there probably isn't a
+          prologue.  */
        return pc;
     }
 
@@ -229,12 +256,60 @@ v850_skip_prologue (pc)
   return pc;
 }
 
+/* All we do here is record SP and FP on the call dummy stack */
+
+void
+v850_push_dummy_frame ()
+{
+  struct dummy_frame *dummy_frame;
+
+  dummy_frame = xmalloc (sizeof (struct dummy_frame));
+
+  dummy_frame->fp = read_register (FP_REGNUM);
+  dummy_frame->sp = read_register (SP_REGNUM);
+  dummy_frame->rp = read_register (RP_REGNUM);
+  dummy_frame->pc = read_register (PC_REGNUM);
+  dummy_frame->next = dummy_frame_stack;
+  dummy_frame_stack = dummy_frame;
+}
+
+int
+v850_pc_in_call_dummy (pc)
+     CORE_ADDR pc;
+{
+  return dummy_frame_stack
+        && pc >= CALL_DUMMY_ADDRESS ()
+        && pc <= CALL_DUMMY_ADDRESS () + DECR_PC_AFTER_BREAK;
+}
+
 struct frame_info *
 v850_pop_frame (frame)
      struct frame_info *frame;
 {
   int regnum;
 
+  if (PC_IN_CALL_DUMMY (frame->pc, NULL, NULL))
+    {
+      struct dummy_frame *dummy_frame;
+      
+      dummy_frame = dummy_frame_stack;
+      if (!dummy_frame)
+       error ("Can't pop dummy frame!");
+
+      dummy_frame_stack = dummy_frame->next;
+
+      write_register (FP_REGNUM, dummy_frame->fp);
+      write_register (SP_REGNUM, dummy_frame->sp);
+      write_register (RP_REGNUM, dummy_frame->rp);
+      write_register (PC_REGNUM, dummy_frame->pc);
+
+      free (dummy_frame);
+
+      flush_cached_frames ();
+
+      return NULL;
+    }
+
   write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
 
   for (regnum = 0; regnum < NUM_REGS; regnum++)
@@ -246,6 +321,81 @@ v850_pop_frame (frame)
 
   return NULL;
 }
+
+/* Put arguments in the right places, and setup return address register (RP) to
+   point at a convenient place to put a breakpoint.  First four args go in
+   R6->R9, subsequent args go into sp + 16 -> sp + ...  Structs are passed by
+   reference.  64 bit quantities (doubles and long longs) may be split between
+   the regs and the stack.  When calling a function that returns a struct, a
+   pointer to the struct is passed in as a secret first argument (always in R6).
+
+   By the time we get here, stack space has been allocated for the args, but
+   not for the struct return pointer.  */
+
+CORE_ADDR
+v850_push_arguments (nargs, args, sp, struct_return, struct_addr)
+     int nargs;
+     value_ptr *args;
+     CORE_ADDR sp;
+     unsigned char struct_return;
+     CORE_ADDR struct_addr;
+{
+  int argreg;
+  int argnum;
+
+  argreg = 6;
+
+  if (struct_return)
+    {
+      write_register (argreg++, struct_addr);
+      sp -= 4;
+    }
+
+  for (argnum = 0; argnum < nargs; argnum++)
+    {
+      int len;
+      char *val;
+      char valbuf[4];
+
+      if (TYPE_CODE (VALUE_TYPE (*args)) == TYPE_CODE_STRUCT
+         && TYPE_LENGTH (VALUE_TYPE (*args)) > 8)
+       {
+         store_address (valbuf, 4, VALUE_ADDRESS (*args));
+         len = 4;
+         val = valbuf;
+       }
+      else
+       {
+         len = TYPE_LENGTH (VALUE_TYPE (*args));
+         val = (char *)VALUE_CONTENTS (*args);
+       }
+
+      while (len > 0)
+       if  (argreg <= 9)
+         {
+           CORE_ADDR regval;
+
+           regval = extract_address (val, REGISTER_RAW_SIZE (argreg));
+           write_register (argreg, regval);
+
+           len -= REGISTER_RAW_SIZE (argreg);
+           val += REGISTER_RAW_SIZE (argreg);
+           argreg++;
+         }
+       else
+         {
+           write_memory (sp + argnum * 4, val, 4);
+
+           len -= 4;
+           val += 4;
+         }
+      args++;
+    }
+
+  write_register (RP_REGNUM, entry_point_address ());
+
+  return sp;
+}
 \f
 void
 _initialize_sparc_tdep ()