Remove locally duplicated code for calling functions in the inferior. The
authorFred Fish <fnf@specifix.com>
Fri, 25 Oct 1991 06:29:23 +0000 (06:29 +0000)
committerFred Fish <fnf@specifix.com>
Fri, 25 Oct 1991 06:29:23 +0000 (06:29 +0000)
only differences were in the specific trap vectors used and whether or not
an fpu was present.  These are now handled by appropriate definitions of
BPT_VECTOR and HAVE_68881 respectively.  Other minor obvious cleanups.
Minor spelling correction in valops.c.

13 files changed:
gdb/ChangeLog
gdb/tm-3b1.h
gdb/tm-68k.h
gdb/tm-altos.h
gdb/tm-amix.h
gdb/tm-hp300bsd.h
gdb/tm-hp300hpux.h
gdb/tm-isi.h
gdb/tm-news.h
gdb/tm-pn.h
gdb/tm-sun2.h
gdb/tm-sun3.h
gdb/valops.c

index ad4fdf7..99bf7a9 100644 (file)
@@ -1,5 +1,15 @@
 Thu Oct 24 23:06:40 1991  Fred Fish  (fnf at cygnus.com)
 
+       * tm-3b1.h, tm-68k.h, tm-altos.h, tm-amix.h, tm-hp300bsd.h,
+       tm-hp300hpux.h, tm-isi.h, tm-news.h, tm-pn.h, tm-sun2.h,
+       tm-sun3.h:  Remove locally duplicated code for calling functions
+       in the inferior.  The only differences were in the specific trap
+       vectors used and whether or not an fpu was present.  These are
+       now handled by appropriate definitions of BPT_VECTOR and
+       HAVE_68881 respectively.  Other minor obvious cleanups.
+
+       * valops.c:  Correct a minor misspelling.
+
        * utils.c:  Remove local BSD/USG hacks that are now in libiberty.
 
        * dwarfread.c:  Remove prototype for dwarfwarn.  Does not work
index 00436c0..5b49b07 100644 (file)
@@ -17,7 +17,11 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
-#define BREAKPOINT { 0x4e, 0x41 }
+/* Define BPT_VECTOR if it is different than the default.
+   This is the vector number used by traps to indicate a breakpoint. */
+
+#define BPT_VECTOR 0x1
+
 /* Define this if the C compiler puts an underscore at the front
    of external names before giving them to the linker.  */
 
@@ -32,77 +36,4 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #define STACK_END_ADDR 0x300000
 
-\f
-/* Things needed for making the inferior call functions.  */
-
-/* Push an empty stack frame, to record the current PC, etc.  */
-
-#define PUSH_DUMMY_FRAME \
-{ register CORE_ADDR sp = read_register (SP_REGNUM);\
-  register int regnum;                             \
-  sp = push_word (sp, read_register (PC_REGNUM));   \
-  sp = push_word (sp, read_register (FP_REGNUM));   \
-  write_register (FP_REGNUM, sp);                  \
-  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)  \
-    sp = push_word (sp, read_register (regnum));    \
-  sp = push_word (sp, read_register (PS_REGNUM));   \
-  write_register (SP_REGNUM, sp);  }
-
-/* Discard from the stack the innermost frame, restoring all registers.  */
-
-#define POP_FRAME  \
-{ register FRAME frame = get_current_frame ();                  \
-  register CORE_ADDR fp;                                        \
-  register int regnum;                                          \
-  struct frame_saved_regs fsr;                                  \
-  struct frame_info *fi;                                                \
-  fi = get_frame_info (frame);                                  \
-  fp = fi->frame;                                               \
-  get_frame_saved_regs (fi, &fsr);                              \
-  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)           \
-    if (fsr.regs[regnum])                                       \
-      write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
-  if (fsr.regs[PS_REGNUM])                                      \
-    write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
-  write_register (FP_REGNUM, read_memory_integer (fp, 4));      \
-  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));   \
-  write_register (SP_REGNUM, fp + 8);                           \
-  flush_cached_frames ();                                       \
-  set_current_frame ( create_new_frame (read_register (FP_REGNUM),\
-                                       read_pc ())); }
-
-/* This sequence of words is the instructions
-     moveml 0xfffc,-(sp)
-     clrw -(sp)
-     movew ccr,-(sp)
-     /..* The arguments are pushed at this point by GDB;
-       no code is needed in the dummy for this.
-       The CALL_DUMMY_START_OFFSET gives the position of 
-       the following jsr instruction.  *../
-     jsr @#32323232
-     addl #69696969,sp
-     bpt
-     nop
-Note this is 24 bytes.
-We actually start executing at the jsr, since the pushing of the
-registers is done by PUSH_DUMMY_FRAME.  If this were real code,
-the arguments for the function called by the jsr would be pushed
-between the moveml and the jsr, and we could allow it to execute through.
-But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
-and we cannot allow the moveml to push the registers again lest they be
-taken for the arguments.  */
-
-#define CALL_DUMMY {0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4f4e71}
-
-#define CALL_DUMMY_LENGTH 24
-
-#define CALL_DUMMY_START_OFFSET 8
-
-/* Insert the specified number of args and function address
-   into a call sequence of the above form stored at DUMMYNAME.  */
-
-#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, type)     \
-{ *(int *)((char *) dummyname + 16) = nargs * 4;  \
-  *(int *)((char *) dummyname + 10) = fun; }
-\f
 #include "tm-68k.h"
index 2a5893c..d89f23d 100644 (file)
@@ -17,7 +17,7 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
-/* Generic 68000 stuff, to be included by other m-*.h files.
+/* Generic 68000 stuff, to be included by other tm-*.h files.
    Define HAVE_68881 if that is the case.  */
 
 #if defined (HAVE_68881)
@@ -65,11 +65,15 @@ read_memory_integer (read_register (SP_REGNUM), 4)
 
 /* Sequence of bytes for breakpoint instruction.
    This is a TRAP instruction.  The last 4 bits (0xf below) is the
-   vector.  Systems which don't use 0xf should define BREAKPOINT
+   vector.  Systems which don't use 0xf should define BPT_VECTOR
    themselves before including this file.  */
 
+#if !defined BPT_VECTOR
+#define BPT_VECTOR 0xf
+#endif
+
 #if !defined (BREAKPOINT)
-#define BREAKPOINT {0x4e, 0x4f}
+#define BREAKPOINT {0x4e, (0x40 | BPT_VECTOR)}
 #endif
 
 /* If your kernel resets the pc after the trap happens you may need to
@@ -310,9 +314,24 @@ extern struct ext_format ext_format_68881;
    read_memory_integer ((thisframe)->frame, 4) :\
    0)
 
+#if defined (FRAME_CHAIN_VALID_ALTERNATE)
+
+/* Use the alternate method of avoiding running up off the end of
+   the frame chain or following frames back into the startup code.
+   See the comments in blockframe.c */
+   
+#define FRAME_CHAIN_VALID(chain, thisframe)    \
+  (chain != 0                                  \
+   && !(inside_main_scope ((thisframe)->pc))   \
+   && !(inside_entry_scope ((thisframe)->pc)))
+
+#else
+
 #define FRAME_CHAIN_VALID(chain, thisframe) \
   (chain != 0 && outside_startup_file (FRAME_SAVED_PC (thisframe)))
 
+#endif /* FRAME_CHAIN_VALID_ALTERNATE */
+
 #define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
 
 /* Define other aspects of the stack frame.  */
@@ -476,40 +495,53 @@ extern struct ext_format ext_format_68881;
    for most configurations.  The m68k family should be able to do this as
    well.  These macros can still be overridden when necessary.  */
 
-/* The CALL_DUMMY macro is the sequence of instructions
-     fmovem 0xff,-(sp)
-     moveml 0xfffc,-(sp)
-     clrw -(sp)
-     movew ccr,-(sp)
-     /..* The arguments are pushed at this point by GDB;
+/* The CALL_DUMMY macro is the sequence of instructions, as disassembled
+   by gdb itself:
+
+       fmovemx fp0-fp7,sp@-                    0xf227 0xe0ff
+       moveml d0-a5,sp@-                       0x48e7 0xfffc
+       clrw sp@-                               0x4267
+       movew ccr,sp@-                          0x42e7
+
+       /..* The arguments are pushed at this point by GDB;
        no code is needed in the dummy for this.
        The CALL_DUMMY_START_OFFSET gives the position of 
        the following jsr instruction.  *../
-     jsr @#32323232
-     addl #69696969,sp
-     bpt
-     nop
-Note this is 28 bytes.
-We actually start executing at the jsr, since the pushing of the
-registers is done by PUSH_DUMMY_FRAME.  If this were real code,
-the arguments for the function called by the jsr would be pushed
-between the moveml and the jsr, and we could allow it to execute through.
-But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
-and we cannot allow the moveml to push the registers again lest they be
-taken for the arguments.  */
 
-#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e414e71}
+       jsr @#0x32323232                        0x4eb9 0x3232 0x3232
+       addal #0x69696969,sp                    0xdffc 0x6969 0x6969
+       trap #<your BPT_VECTOR number here>     0x4e4?
+       nop                                     0x4e71
+
+   Note this is CALL_DUMMY_LENGTH bytes (28 for the above example).
+   We actually start executing at the jsr, since the pushing of the
+   registers is done by PUSH_DUMMY_FRAME.  If this were real code,
+   the arguments for the function called by the jsr would be pushed
+   between the moveml and the jsr, and we could allow it to execute through.
+   But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is
+   done, and we cannot allow the moveml to push the registers again lest
+   they be taken for the arguments.  */
+
+#if defined (HAVE_68881)
+
+#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, (0x4e404e71 | (BPT_VECTOR << 16))}
+#define CALL_DUMMY_LENGTH 28           /* Size of CALL_DUMMY */
+#define CALL_DUMMY_START_OFFSET 12     /* Offset to jsr instruction*/
+
+#else
 
-#define CALL_DUMMY_LENGTH 28
+#define CALL_DUMMY {0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, (0x4e404e71 | (BPT_VECTOR << 16))}
+#define CALL_DUMMY_LENGTH 24           /* Size of CALL_DUMMY */
+#define CALL_DUMMY_START_OFFSET 8      /* Offset to jsr instruction*/
 
-#define CALL_DUMMY_START_OFFSET 12
+#endif /* HAVE_68881 */
 
 /* Insert the specified number of args and function address
    into a call sequence of the above form stored at DUMMYNAME.  */
 
 #define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)     \
-{ *(int *)((char *) dummyname + 20) = nargs * 4;  \
-  *(int *)((char *) dummyname + 14) = fun; }
+{ *(int *)((char *) dummyname + CALL_DUMMY_START_OFFSET + 2) = fun;  \
+  *(int *)((char *) dummyname + CALL_DUMMY_START_OFFSET + 8) = nargs * 4; }
 
 /* Push an empty stack frame, to record the current PC, etc.  */
 
@@ -517,9 +549,5 @@ taken for the arguments.  */
 
 /* Discard from the stack the innermost frame, restoring all registers.  */
 
-#define POP_FRAME { m68k_pop_frame (); }
+#define POP_FRAME              { m68k_pop_frame (); }
 
-/* Note that stuff for calling inferior functions is not in this file
-   because the call dummy is different for different breakpoint
-   instructions, which are different on different systems.  Perhaps
-   they could be merged, but I haven't bothered.  */
index 3112fe1..bc0d2f9 100644 (file)
@@ -17,9 +17,10 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
-/* Sequence of bytes for breakpoint instruction.  */
+/* Define BPT_VECTOR if it is different than the default.
+   This is the vector number used by traps to indicate a breakpoint. */
 
-#define BREAKPOINT {0x4e, 0x4e}
+#define BPT_VECTOR 0xe
 
 /* Define this if the C compiler puts an underscore at the front
    of external names before giving them to the linker.  */
@@ -92,39 +93,5 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
   set_current_frame (create_new_frame (read_register (FP_REGNUM),      \
                                        read_pc ())); }
 
-/* This sequence of words is the instructions
-     fmovem 0xff,-(sp)
-     moveml 0xfffc,-(sp)
-     clrw -(sp)
-     movew ccr,-(sp)
-     /..* The arguments are pushed at this point by GDB;
-       no code is needed in the dummy for this.
-       The CALL_DUMMY_START_OFFSET gives the position of 
-       the following jsr instruction.  *../
-     jsr @#32323232
-     addl #69696969,sp
-     bpt
-     nop
-Note this is 28 bytes.
-We actually start executing at the jsr, since the pushing of the
-registers is done by PUSH_DUMMY_FRAME.  If this were real code,
-the arguments for the function called by the jsr would be pushed
-between the moveml and the jsr, and we could allow it to execute through.
-But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
-and we cannot allow the moveml to push the registers again lest they be
-taken for the arguments.  */
-
-#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4e4e71}
-
-#define CALL_DUMMY_LENGTH 28
-
-#define CALL_DUMMY_START_OFFSET 12
-
-/* Insert the specified number of args and function address
-   into a call sequence of the above form stored at DUMMYNAME.  */
-
-#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)     \
-{ *(int *)((char *) dummyname + 20) = nargs * 4;  \
-  *(int *)((char *) dummyname + 14) = fun; }
 \f
 #include "tm-68k.h"
index 056bd82..635d3b3 100644 (file)
@@ -21,36 +21,27 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 /* All Amiga's (so far) running UNIX have come standard with the floating
    point coprocessor. */
 
-#define HAVE_68881     /* Amiga has floating point coprocessor */
+#define HAVE_68881
 
-/* Sequence of bytes for breakpoint instruction.
-   This is a TRAP instruction.  The last 4 bits (0x1 below) is the
-   vector. */
+/* Define BPT_VECTOR if it is different than the default.
+   This is the vector number used by traps to indicate a breakpoint. */
 
-#define BREAKPOINT {0x4e, 0x41 }       /* Trap using vector 0x1 */
+#define BPT_VECTOR 0x1
 
 /* How much to decrement the PC after a trap.  Depends on kernel. */
 
 #define DECR_PC_AFTER_BREAK 0          /* No decrement required */
 
-
-#include "tm-68k.h"
-#include "tm-svr4.h"
-
-/* Address of end of stack space. (actually one byte past it).
+/* Address of end of stack space.  Actually one byte past it.
    This value is typically very OS dependent.
    FIXME:  Check to see if SVR4 offers some machine independent way
    of discovering this value and use it if so, and if we need it. */
 
 /* #define STACK_END_ADDR 0xc0800000 */
 
-/* Use the alternate method of avoiding running up off the end of
-   the frame chain or following frames back into the startup code.
-   See the comments in blockframe.c */
-   
-#undef FRAME_CHAIN_VALID
-#define FRAME_CHAIN_VALID(chain, thisframe)    \
-  (chain != 0                                  \
-   && !(inside_main_scope ((thisframe)->pc))   \
-   && !(inside_entry_scope ((thisframe)->pc)))
+/* Use the alternate method of determining valid frame chains. */
 
+#define FRAME_CHAIN_VALID_ALTERNATE
+
+#include "tm-svr4.h"
+#include "tm-68k.h"
index dccbc7d..9a6da61 100644 (file)
@@ -23,6 +23,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  * Problems to hpbsd-bugs@cs.utah.edu
  */
 
+#define HAVE_68881
+
+/* Define BPT_VECTOR if it is different than the default.
+   This is the vector number used by traps to indicate a breakpoint. */
+
+#define BPT_VECTOR 0x2
+
 /* Define this if the C compiler puts an underscore at the front
    of external names before giving them to the linker.  */
 
@@ -49,94 +56,4 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #define STACK_END_ADDR 0xfff00000
 
-/* Sequence of bytes for breakpoint instruction.  */
-
-#define BREAKPOINT {0x4e, 0x42}
-
-\f
-/* Things needed for making the inferior call functions.  */
-
-/* Push an empty stack frame, to record the current PC, etc.  */
-
-#define PUSH_DUMMY_FRAME \
-{ register CORE_ADDR sp = read_register (SP_REGNUM);                   \
-  register int regnum;                                                 \
-  char raw_buffer[12];                                                 \
-  sp = push_word (sp, read_register (PC_REGNUM));                      \
-  sp = push_word (sp, read_register (FP_REGNUM));                      \
-  write_register (FP_REGNUM, sp);                                      \
-  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)                \
-    { read_register_gen (regnum, raw_buffer);                          \
-      sp = push_bytes (sp, raw_buffer, 12); }                          \
-  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)                  \
-    sp = push_word (sp, read_register (regnum));                       \
-  sp = push_word (sp, read_register (PS_REGNUM));                      \
-  write_register (SP_REGNUM, sp);  }
-
-/* Discard from the stack the innermost frame, 
-   restoring all saved registers.  */
-
-#define POP_FRAME  \
-{ register FRAME frame = get_current_frame ();                  \
-  register CORE_ADDR fp;                                        \
-  register int regnum;                                          \
-  struct frame_saved_regs fsr;                                  \
-  struct frame_info *fi;                                        \
-  char raw_buffer[12];                                          \
-  fi = get_frame_info (frame);                                  \
-  fp = fi->frame;                                               \
-  get_frame_saved_regs (fi, &fsr);                              \
-  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)         \
-    if (fsr.regs[regnum])                                       \
-      { read_memory (fsr.regs[regnum], raw_buffer, 12);                 \
-        write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); }\
-  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)           \
-    if (fsr.regs[regnum])                                       \
-      write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
-  if (fsr.regs[PS_REGNUM])                                      \
-    write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
-  write_register (FP_REGNUM, read_memory_integer (fp, 4));      \
-  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));   \
-  write_register (SP_REGNUM, fp + 8);                           \
-  flush_cached_frames ();                                       \
-  set_current_frame (create_new_frame (read_register (FP_REGNUM),\
-                                       read_pc ())); }
-
-/* This sequence of words is the instructions
-     fmovem 0xff,-(sp)
-     moveml 0xfffc,-(sp)
-     clrw -(sp)
-     movew ccr,-(sp)
-     /..* The arguments are pushed at this point by GDB;
-       no code is needed in the dummy for this.
-       The CALL_DUMMY_START_OFFSET gives the position of 
-       the following jsr instruction.  *../
-     jsr @#32323232
-     addl #69696969,sp
-     trap #2
-     nop
-Note this is 28 bytes.
-We actually start executing at the jsr, since the pushing of the
-registers is done by PUSH_DUMMY_FRAME.  If this were real code,
-the arguments for the function called by the jsr would be pushed
-between the moveml and the jsr, and we could allow it to execute through.
-But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
-and we cannot allow the moveml to push the registers again lest they be
-taken for the arguments.  */
-
-#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e424e71}
-
-#define CALL_DUMMY_LENGTH 28
-
-#define CALL_DUMMY_START_OFFSET 12
-
-/* Insert the specified number of args and function address
-   into a call sequence of the above form stored at DUMMYNAME.  */
-
-#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)     \
-{ *(int *)((char *) dummyname + 20) = nargs * 4;  \
-  *(int *)((char *) dummyname + 14) = fun; }
-\f
-#define HAVE_68881
-
 #include "tm-68k.h"
index 42c1849..742149b 100644 (file)
@@ -17,9 +17,12 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
-/* Sequence of bytes for breakpoint instruction.  */
+#include HAVE_68881
+
+/* Define BPT_VECTOR if it is different than the default.
+   This is the vector number used by traps to indicate a breakpoint. */
 
-#define BREAKPOINT {0x4e, 0x41}
+#define BPT_VECTOR 0x1
 
 /* Define this if the C compiler puts an underscore at the front
    of external names before giving them to the linker.  */
@@ -33,90 +36,5 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 /* Address of end of stack space.  */
 
 #define STACK_END_ADDR 0xFFF00000
-\f
-/* Things needed for making the inferior call functions.  */
-
-/* Push an empty stack frame, to record the current PC, etc.  */
-
-#define PUSH_DUMMY_FRAME \
-{ register CORE_ADDR sp = read_register (SP_REGNUM);                   \
-  register int regnum;                                                 \
-  char raw_buffer[12];                                                 \
-  sp = push_word (sp, read_register (PC_REGNUM));                      \
-  sp = push_word (sp, read_register (FP_REGNUM));                      \
-  write_register (FP_REGNUM, sp);                                      \
-  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)                \
-    { read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);    \
-      sp = push_bytes (sp, raw_buffer, 12); }                          \
-  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)                  \
-    sp = push_word (sp, read_register (regnum));                       \
-  sp = push_word (sp, read_register (PS_REGNUM));                      \
-  write_register (SP_REGNUM, sp);  }
-
-/* Discard from the stack the innermost frame, 
-   restoring all saved registers.  */
-
-#define POP_FRAME  \
-{ register FRAME frame = get_current_frame ();                  \
-  register CORE_ADDR fp;                                        \
-  register int regnum;                                          \
-  struct frame_saved_regs fsr;                                  \
-  struct frame_info *fi;                                        \
-  char raw_buffer[12];                                          \
-  fi = get_frame_info (frame);                                  \
-  fp = fi->frame;                                               \
-  get_frame_saved_regs (fi, &fsr);                              \
-  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)         \
-    if (fsr.regs[regnum])                                       \
-      { read_memory (fsr.regs[regnum], raw_buffer, 12);                 \
-        write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); }\
-  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)           \
-    if (fsr.regs[regnum])                                       \
-      write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
-  if (fsr.regs[PS_REGNUM])                                      \
-    write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
-  write_register (FP_REGNUM, read_memory_integer (fp, 4));      \
-  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));   \
-  write_register (SP_REGNUM, fp + 8);                           \
-  flush_cached_frames ();                                       \
-  set_current_frame (create_new_frame (read_register (FP_REGNUM),\
-                                      read_pc ()));}
-
-/* This sequence of words is the instructions
-     fmovem 0xff,-(sp)
-     moveml 0xfffc,-(sp)
-     clrw -(sp)
-     movew ccr,-(sp)
-     /..* The arguments are pushed at this point by GDB;
-       no code is needed in the dummy for this.
-       The CALL_DUMMY_START_OFFSET gives the position of 
-       the following jsr instruction.  *../
-     jsr @#32323232
-     addl #69696969,sp
-     bpt
-     nop
-Note this is 28 bytes.
-We actually start executing at the jsr, since the pushing of the
-registers is done by PUSH_DUMMY_FRAME.  If this were real code,
-the arguments for the function called by the jsr would be pushed
-between the moveml and the jsr, and we could allow it to execute through.
-But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
-and we cannot allow the moveml to push the registers again lest they be
-taken for the arguments.  */
-
-#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e414e71}
-
-#define CALL_DUMMY_LENGTH 28
-
-#define CALL_DUMMY_START_OFFSET 12
-
-/* Insert the specified number of args and function address
-   into a call sequence of the above form stored at DUMMYNAME.  */
-
-#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)     \
-{ *(int *)((char *) dummyname + 20) = nargs * 4;  \
-  *(int *)((char *) dummyname + 14) = fun; }
-\f
-#include HAVE_68881
 
 #include "tm-68k.h"
index d9e8539..f214317 100644 (file)
@@ -20,6 +20,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 /* This has not been tested on ISI's running BSD 4.2, but it will probably
    work.  */
 
+#define HAVE_68881
+
 /* Define this if the C compiler puts an underscore at the front
    of external names before giving them to the linker.  */
 
@@ -29,7 +31,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #define READ_DBX_FORMAT
 
-/*#define STACK_END_ADDR 0x10000000*/
+/* Address of end of stack space.  */
+
 #define STACK_END_ADDR 0xfffe000
 
 /* Data segment starts at etext rounded up to DATAROUND in {N,Z}MAGIC files */
@@ -139,89 +142,5 @@ retry:                                                                     \
   (frame_saved_regs).regs[FP_REGNUM] = (frame_info)->frame;            \
   (frame_saved_regs).regs[PC_REGNUM] = (frame_info)->frame + 4;                \
 }
-\f
-/* Things needed for making the inferior call functions.  */
-
-/* Push an empty stack frame, to record the current PC, etc.  */
-
-#define PUSH_DUMMY_FRAME \
-{ register CORE_ADDR sp = read_register (SP_REGNUM);                   \
-  register int regnum;                                                 \
-  char raw_buffer[12];                                                 \
-  sp = push_word (sp, read_register (PC_REGNUM));                      \
-  sp = push_word (sp, read_register (FP_REGNUM));                      \
-  write_register (FP_REGNUM, sp);                                      \
-  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)                \
-    { read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);    \
-      sp = push_bytes (sp, raw_buffer, 12); }                          \
-  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)                  \
-    sp = push_word (sp, read_register (regnum));                       \
-  sp = push_word (sp, read_register (PS_REGNUM));                      \
-  write_register (SP_REGNUM, sp);  }
-
-/* Discard from the stack the innermost frame, restoring all registers.  */
-
-#define POP_FRAME  \
-{ register FRAME frame = get_current_frame ();                         \
-  register CORE_ADDR fp;                                               \
-  register int regnum;                                                 \
-  struct frame_saved_regs fsr;                                         \
-  struct frame_info *fi;                                               \
-  char raw_buffer[12];                                                 \
-  fi = get_frame_info (frame);                                         \
-  fp = fi->frame;                                                      \
-  get_frame_saved_regs (fi, &fsr);                                     \
-  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)                \
-    if (fsr.regs[regnum])                                              \
-      { read_memory (fsr.regs[regnum], raw_buffer, 12);                        \
-        write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); }\
-  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)                  \
-    if (fsr.regs[regnum])                                              \
-      write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
-  if (fsr.regs[PS_REGNUM])                                             \
-    write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
-  write_register (FP_REGNUM, read_memory_integer (fp, 4));             \
-  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));         \
-  write_register (SP_REGNUM, fp + 8);                                  \
-  flush_cached_frames ();                                              \
-  set_current_frame ( create_new_frame (read_register (FP_REGNUM),     \
-                                       read_pc ())); }
-
-/* This sequence of words is the instructions
-     fmovem #<f0-f7>,-(sp)
-     moveml 0xfffc,-(sp)
-     clrw -(sp)
-     movew ccr,-(sp)
-     /..* The arguments are pushed at this point by GDB;
-       no code is needed in the dummy for this.
-       The CALL_DUMMY_START_OFFSET gives the position of
-       the following jsr instruction.  *../
-     jsr @#32323232
-     addl #69696969,sp
-     bpt
-     nop
-Note this is 24 bytes.
-We actually start executing at the jsr, since the pushing of the
-registers is done by PUSH_DUMMY_FRAME.  If this were real code,
-the arguments for the function called by the jsr would be pushed
-between the moveml and the jsr, and we could allow it to execute through.
-But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
-and we cannot allow the moveml to push the registers again lest they be
-taken for the arguments.  */
-
-#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4f4e71}
-
-#define CALL_DUMMY_LENGTH 28
-
-#define CALL_DUMMY_START_OFFSET 12
-
-/* Insert the specified number of args and function address
-   into a call sequence of the above form stored at DUMMYNAME.  */
-
-#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)     \
-{ *(int *)((char *) dummyname + 20) = nargs * 4;  \
-  *(int *)((char *) dummyname + 14) = fun; }
-\f
-#define HAVE_68881 1
 
 #include "tm-68k.h"
index 4cc1c78..bf70b74 100644 (file)
@@ -27,6 +27,8 @@ Here is an m-news.h file for gdb.  It supports the 68881 registers.
 * After NEWS OS version 3.2, some of ptrace's bug is fixed.
   But we cannot change the floating register(see adb(1) in OS 3.2) yet.  */
 
+#define HAVE_68881
+
 /* Define this if the C compiler puts an underscore at the front
    of external names before giving them to the linker.  */
 
@@ -88,85 +90,4 @@ Here is an m-news.h file for gdb.  It supports the 68881 registers.
     val = read_memory_integer (pc + 2, 4);                     \
   val >>= 2; }
 
-/* Things needed for making the inferior call functions.  */
-#define PUSH_DUMMY_FRAME \
-{ register CORE_ADDR sp = read_register (SP_REGNUM);                   \
-  register int regnum;                                                 \
-  char raw_buffer[12];                                                 \
-  sp = push_word (sp, read_register (PC_REGNUM));                      \
-  sp = push_word (sp, read_register (FP_REGNUM));                      \
-  write_register (FP_REGNUM, sp);                                      \
-  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)                \
-    { read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);    \
-      sp = push_bytes (sp, raw_buffer, 12); }                          \
-  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)                  \
-    sp = push_word (sp, read_register (regnum));                       \
-  sp = push_word (sp, read_register (PS_REGNUM));                      \
-  write_register (SP_REGNUM, sp);  }
-
-/* Discard from the stack the innermost frame, restoring all registers.  */
-
-#define POP_FRAME  \
-{ register FRAME frame = get_current_frame ();                         \
-  register CORE_ADDR fp;                                               \
-  register int regnum;                                                 \
-  struct frame_saved_regs fsr;                                         \
-  struct frame_info *fi;                                               \
-  char raw_buffer[12];                                                 \
-  fi = get_frame_info (frame);                                         \
-  fp = fi->frame;                                                      \
-  get_frame_saved_regs (fi, &fsr);                                     \
-  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)                \
-    if (fsr.regs[regnum])                                              \
-      { read_memory (fsr.regs[regnum], raw_buffer, 12);                        \
-        write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); }\
-  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)                  \
-    if (fsr.regs[regnum])                                              \
-      write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
-  if (fsr.regs[PS_REGNUM])                                             \
-    write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
-  write_register (FP_REGNUM, read_memory_integer (fp, 4));             \
-  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));         \
-  write_register (SP_REGNUM, fp + 8);                                  \
-  flush_cached_frames ();                                              \
-  set_current_frame (create_new_frame (read_register (FP_REGNUM),      \
-                                      read_pc ())); }
-
-/* This sequence of words is the instructions
-     fmove.m #<f0-f7>,-(sp)
-     movem.l 0xfffc,-(sp)     ;; no save a6(fp) and a7(sp)
-     clr.w -(sp)
-     move.w ccr,-(sp)
-     /..* The arguments are pushed at this point by GDB;
-       no code is needed in the dummy for this.
-       The CALL_DUMMY_START_OFFSET gives the position of 
-       the following jsr instruction.  *../
-     jbsr (#32323232)
-     add.l #69696969,sp
-     bpt
-     nop
-Note this is 24 bytes.
-We actually start executing at the jsr, since the pushing of the
-registers is done by PUSH_DUMMY_FRAME.  If this were real code,
-the arguments for the function called by the jsr would be pushed
-between the moveml and the jsr, and we could allow it to execute through.
-But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
-and we cannot allow the moveml to push the registers again lest they be
-taken for the arguments.  */
-
-#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4f4e71}
-
-#define CALL_DUMMY_LENGTH 28
-
-#define CALL_DUMMY_START_OFFSET 12
-
-/* Insert the specified number of args and function address
-   into a call sequence of the above form stored at DUMMYNAME.  */
-
-#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)     \
-{ *(int *)((char *) dummyname + 20) = nargs * 4;  \
-  *(int *)((char *) dummyname + 14) = fun; }
-\f
-#define HAVE_68881
-
 #include "tm-68k.h"
index 1c2e77a..36565df 100644 (file)
@@ -419,6 +419,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
    Setup our stack frame, load argumemts, call and then restore registers.
 */
 
+/* FIXME:  The below defines an m68k CALL_DUMMY, which looks nothing like what
+   is documented above. */
+
 #define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4f4e71}
 
 #define CALL_DUMMY_LENGTH 28
index 20fc4a1..21fd588 100644 (file)
@@ -17,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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
-#include "m-68k.h"
-
 /* Define this if the C compiler puts an underscore at the front
    of external names before giving them to the linker.  */
 
@@ -30,78 +28,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 /* Address of the end of stack space.  We get this from the system
    include files. */
+
 #include <sys/types.h>
 #include <machine/vmparam.h>
 #define STACK_END_ADDR USRSTACK
-\f
-/* Things needed for making the inferior call functions.  */
-
-/* Push an empty stack frame, to record the current PC, etc.  */
-
-#define PUSH_DUMMY_FRAME \
-{ register CORE_ADDR sp = read_register (SP_REGNUM);\
-  register int regnum;                             \
-  sp = push_word (sp, read_register (PC_REGNUM));   \
-  sp = push_word (sp, read_register (FP_REGNUM));   \
-  write_register (FP_REGNUM, sp);                  \
-  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)  \
-    sp = push_word (sp, read_register (regnum));    \
-  sp = push_word (sp, read_register (PS_REGNUM));   \
-  write_register (SP_REGNUM, sp);  }
-
-/* Discard from the stack the innermost frame, restoring all registers.  */
-
-#define POP_FRAME  \
-{ register FRAME frame = get_current_frame ();                  \
-  register CORE_ADDR fp;                                        \
-  register int regnum;                                          \
-  struct frame_saved_regs fsr;                                  \
-  struct frame_info *fi;                                                \
-  fi = get_frame_info (frame);                                  \
-  fp = fi->frame;                                               \
-  get_frame_saved_regs (fi, &fsr);                              \
-  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)           \
-    if (fsr.regs[regnum])                                       \
-      write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
-  if (fsr.regs[PS_REGNUM])                                      \
-    write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
-  write_register (FP_REGNUM, read_memory_integer (fp, 4));      \
-  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));   \
-  write_register (SP_REGNUM, fp + 8);                           \
-  flush_cached_frames ();                                       \
-  set_current_frame ( create_new_frame (read_register (FP_REGNUM),\
-                                       read_pc ())); }
-
-/* This sequence of words is the instructions
-     moveml 0xfffc,-(sp)
-     clrw -(sp)
-     movew ccr,-(sp)
-     /..* The arguments are pushed at this point by GDB;
-       no code is needed in the dummy for this.
-       The CALL_DUMMY_START_OFFSET gives the position of
-       the following jsr instruction.  *../
-     jsr @#32323232
-     addl #69696969,sp
-     bpt
-     nop
-Note this is 24 bytes.
-We actually start executing at the jsr, since the pushing of the
-registers is done by PUSH_DUMMY_FRAME.  If this were real code,
-the arguments for the function called by the jsr would be pushed
-between the moveml and the jsr, and we could allow it to execute through.
-But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
-and we cannot allow the moveml to push the registers again lest they be
-taken for the arguments.  */
-
-#define CALL_DUMMY {0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4f4e71}
-
-#define CALL_DUMMY_LENGTH 24
-
-#define CALL_DUMMY_START_OFFSET 8
-
-/* Insert the specified number of args and function address
-   into a call sequence of the above form stored at DUMMYNAME.  */
 
-#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)     \
-{ *(int *)((char *) dummyname + 16) = nargs * 4;  \
-  *(int *)((char *) dummyname + 10) = fun; }
+#include "tm-68k.h"
index b3da81b..5b6aa91 100644 (file)
@@ -23,8 +23,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
    ../include/target.h (included by ../include/a.out.gnu.h).  */
 #define GDB_TARGET_IS_SUN3 1
 
-#include "tm-68k.h"
-
 /* Define this if the C compiler puts an underscore at the front
    of external names before giving them to the linker.  */
 
@@ -36,92 +34,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 /* Address of the end of stack space.  We get this from the system
    include files. */
+
 #include <sys/types.h>
 #include <machine/vmparam.h>
 #define STACK_END_ADDR USRSTACK
-\f
-/* Things needed for making the inferior call functions.  */
-
-/* Push an empty stack frame, to record the current PC, etc.  */
-
-#define PUSH_DUMMY_FRAME \
-{ register CORE_ADDR sp = read_register (SP_REGNUM);                   \
-  register int regnum;                                                 \
-  char raw_buffer[12];                                                 \
-  sp = push_word (sp, read_register (PC_REGNUM));                      \
-  sp = push_word (sp, read_register (FP_REGNUM));                      \
-  write_register (FP_REGNUM, sp);                                      \
-  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)                \
-    { read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12);    \
-      sp = push_bytes (sp, raw_buffer, 12); }                          \
-  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)                  \
-    sp = push_word (sp, read_register (regnum));                       \
-  sp = push_word (sp, read_register (PS_REGNUM));                      \
-  write_register (SP_REGNUM, sp);  }
-
-/* Discard from the stack the innermost frame, 
-   restoring all saved registers.  */
-
-#define POP_FRAME  \
-{ register FRAME frame = get_current_frame ();                         \
-  register CORE_ADDR fp;                                               \
-  register int regnum;                                                 \
-  struct frame_saved_regs fsr;                                         \
-  struct frame_info *fi;                                               \
-  char raw_buffer[12];                                                 \
-  fi = get_frame_info (frame);                                         \
-  fp = fi->frame;                                                      \
-  get_frame_saved_regs (fi, &fsr);                                     \
-  for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--)                \
-    if (fsr.regs[regnum])                                              \
-      { read_memory (fsr.regs[regnum], raw_buffer, 12);                        \
-        write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); }\
-  for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--)                  \
-    if (fsr.regs[regnum])                                              \
-      write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
-  if (fsr.regs[PS_REGNUM])                                             \
-    write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
-  write_register (FP_REGNUM, read_memory_integer (fp, 4));             \
-  write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));         \
-  write_register (SP_REGNUM, fp + 8);                                  \
-  flush_cached_frames ();                                              \
-  set_current_frame (create_new_frame (read_register (FP_REGNUM),      \
-                                       read_pc ())); }
 
-/* This sequence of words is the instructions
-     fmovem 0xff,-(sp)
-     moveml 0xfffc,-(sp)
-     clrw -(sp)
-     movew ccr,-(sp)
-     /..* The arguments are pushed at this point by GDB;
-       no code is needed in the dummy for this.
-       The CALL_DUMMY_START_OFFSET gives the position of 
-       the following jsr instruction.  *../
-     jsr @#32323232
-     addl #69696969,sp
-     trap #15
-     nop
-Note this is 28 bytes.
-We actually start executing at the jsr, since the pushing of the
-registers is done by PUSH_DUMMY_FRAME.  If this were real code,
-the arguments for the function called by the jsr would be pushed
-between the moveml and the jsr, and we could allow it to execute through.
-But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
-and we cannot allow the moveml to push the registers again lest they be
-taken for the arguments.  */
-
-#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4f4e71}
-
-#define CALL_DUMMY_LENGTH 28
-
-#define CALL_DUMMY_START_OFFSET 12
-
-/* Insert the specified number of args and function address
-   into a call sequence of the above form stored at DUMMYNAME.  */
-
-#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p)     \
-{ int temp;                                             \
-  temp = nargs * 4;                                     \
+#include "tm-68k.h"
   SWAP_TARGET_AND_HOST (temp, 4);                       \
   bcopy ((char *)&temp, (char *)(dummyname) + 20, 4);   \
   temp = fun;                                           \
index b4101b5..614317f 100644 (file)
@@ -659,7 +659,7 @@ call_function_by_hand (function, nargs, args)
   register int i;
   CORE_ADDR start_sp;
   /* CALL_DUMMY is an array of words (REGISTER_TYPE), but each word
-     in in host byte order.  It is switched to target byte order before calling
+     is in host byte order.  It is switched to target byte order before calling
      FIX_CALL_DUMMY.  */
   static REGISTER_TYPE dummy[] = CALL_DUMMY;
   REGISTER_TYPE dummy1[sizeof dummy / sizeof (REGISTER_TYPE)];
@@ -720,6 +720,7 @@ call_function_by_hand (function, nargs, args)
   /* Convex Unix prohibits executing in the stack segment. */
   /* Hope there is empty room at the top of the text segment. */
   {
+    extern CORE_ADDR text_end;
     static checked = 0;
     if (!checked)
       for (start_sp = text_end - sizeof dummy; start_sp < text_end; ++start_sp)
@@ -732,6 +733,7 @@ call_function_by_hand (function, nargs, args)
   }
 #else /* After text_end.  */
   {
+    extern CORE_ADDR text_end;
     int errcode;
     sp = old_sp;
     start_sp = text_end;
@@ -891,7 +893,7 @@ value_string (ptr, len)
   register int c;
 
   /* Copy the string into COPY, processing escapes.
-     We could not conveniently process them in expread
+     We could not conveniently process them in the parser
      because the string there wants to be a substring of the input.  */
 
   while (i - ibeg < len)