* gdbarch.sh (GET_LONGJMP_TARGET): Add rule.
authorRichard Earnshaw <richard.earnshaw@arm.com>
Mon, 18 Feb 2002 13:35:31 +0000 (13:35 +0000)
committerRichard Earnshaw <richard.earnshaw@arm.com>
Mon, 18 Feb 2002 13:35:31 +0000 (13:35 +0000)
* gdbarch.c gdbarch.h: Regenerate.
* breakpoint.c (create_longjmp_breakpoint): Always compile this
function.
(breakpoint_reset): Test GET_LONGJMP_TARGET_P().
* infrun.c (GET_LONGJMP_TARGET): Delete default definition.
(handle_inferior_event): Test GET_LONGJMP_TARGET_P().

* arm-tdep.h (struct gdbarch_tdep): Add jb_pc and jb_elt_size fields.
* arm-tdep.c (arm_get_longjmp_target): New function.
(arm_gdbarch_init): Initialize jb_pc to -1.  If ABI handler changes
this to a positive value register arm_get_longjmp_target as the
longjmp handler.
* arm-linux-tdep.c (arm_get_longjmp_target): Delete.
(arm_linux_init_abi): Set up longjmp description in tdep.
* armnbsd-nat.c (get_longjmp_target): Delete.
* armnbsd-tdep.c (arm_netbsd_init_abi_common): Set up longjmp
description in tdep.
* config/arm/tm-nbsd.h (JB_ELEMENT_SIZE, JB_PC): Delete.
(get_longjmp_target): Delete declaration.
(GET_LONGJMP_TARGET): Delete.
* config/arm/tm-linux.h (arm_get_longjmp_target): Delete declaration.
(GET_LONGJMP_TARGET): Delete.

13 files changed:
gdb/ChangeLog
gdb/arm-linux-tdep.c
gdb/arm-tdep.c
gdb/arm-tdep.h
gdb/armnbsd-nat.c
gdb/armnbsd-tdep.c
gdb/breakpoint.c
gdb/config/arm/tm-linux.h
gdb/config/arm/tm-nbsd.h
gdb/gdbarch.c
gdb/gdbarch.h
gdb/gdbarch.sh
gdb/infrun.c

index b0007fc1b7005e22210e97cbc9d24e8cb6608a27..a415c6bb70175001e8082e04335ec39581b6a19f 100644 (file)
@@ -1,3 +1,29 @@
+2002-02-18  Richard Earnshaw  <rearnsha@arm.com>
+
+       * gdbarch.sh (GET_LONGJMP_TARGET): Add rule.
+       * gdbarch.c gdbarch.h: Regenerate.
+       * breakpoint.c (create_longjmp_breakpoint): Always compile this
+       function.
+       (breakpoint_reset): Test GET_LONGJMP_TARGET_P().
+       * infrun.c (GET_LONGJMP_TARGET): Delete default definition.
+       (handle_inferior_event): Test GET_LONGJMP_TARGET_P().
+
+       * arm-tdep.h (struct gdbarch_tdep): Add jb_pc and jb_elt_size fields.
+       * arm-tdep.c (arm_get_longjmp_target): New function.
+       (arm_gdbarch_init): Initialize jb_pc to -1.  If ABI handler changes
+       this to a positive value register arm_get_longjmp_target as the
+       longjmp handler.
+       * arm-linux-tdep.c (arm_get_longjmp_target): Delete.
+       (arm_linux_init_abi): Set up longjmp description in tdep.
+       * armnbsd-nat.c (get_longjmp_target): Delete.
+       * armnbsd-tdep.c (arm_netbsd_init_abi_common): Set up longjmp
+       description in tdep.
+       * config/arm/tm-nbsd.h (JB_ELEMENT_SIZE, JB_PC): Delete.
+       (get_longjmp_target): Delete declaration.
+       (GET_LONGJMP_TARGET): Delete.
+       * config/arm/tm-linux.h (arm_get_longjmp_target): Delete declaration.
+       (GET_LONGJMP_TARGET): Delete.
+
 2002-02-17  Kevin Buettner  <kevinb@redhat.com>
 
        From Peter Schauer  <pes@regent.e-technik.tu-muenchen.de>:
index 6049cf53a8e6b516adc8b2c35d8a21c21de1620e..6faa4a277c3d94abf366907f77ff01dd2894bd71 100644 (file)
@@ -58,40 +58,10 @@ LONGEST arm_linux_call_dummy_words[] =
   0xe1a0e00f, 0xe1a0f004, 0xef9f001
 };
 
-#ifdef GET_LONGJMP_TARGET
-
-/* Figure out where the longjmp will land.  We expect that we have
-   just entered longjmp and haven't yet altered r0, r1, so the
-   arguments are still in the registers.  (ARM_A1_REGNUM) points at
-   the jmp_buf structure from which we extract the pc (JB_PC) that we
-   will land at.  The pc is copied into ADDR.  This routine returns
-   true on success. */
-
-#define LONGJMP_TARGET_SIZE    sizeof(int)
-#define JB_ELEMENT_SIZE                sizeof(int)
-#define JB_SL                  18
-#define JB_FP                  19
-#define JB_SP                  20
+/* Description of the longjmp buffer.  */
+#define JB_ELEMENT_SIZE                INT_REGISTER_RAW_SIZE
 #define JB_PC                  21
 
-int
-arm_get_longjmp_target (CORE_ADDR * pc)
-{
-  CORE_ADDR jb_addr;
-  char buf[LONGJMP_TARGET_SIZE];
-
-  jb_addr = read_register (ARM_A1_REGNUM);
-
-  if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
-                         LONGJMP_TARGET_SIZE))
-    return 0;
-
-  *pc = extract_address (buf, LONGJMP_TARGET_SIZE);
-  return 1;
-}
-
-#endif /* GET_LONGJMP_TARGET */
-
 /* Extract from an array REGBUF containing the (raw) register state
    a function return value of type TYPE, and copy that, in virtual format,
    into VALBUF.  */
@@ -548,6 +518,9 @@ arm_linux_init_abi (struct gdbarch_info info,
   tdep->lowest_pc = 0x8000;
   tdep->arm_breakpoint = arm_linux_arm_le_breakpoint;
   tdep->arm_breakpoint_size = sizeof (arm_linux_arm_le_breakpoint);
+
+  tdep->jb_pc = JB_PC;
+  tdep->jb_elt_size = JB_ELEMENT_SIZE;
 }
 
 void
index a60f4978f048b1f2bfb7145928f5e2896140abd2..7f2026708d5bc10215144896dc29b7d09aff4f08 100644 (file)
@@ -2272,6 +2272,23 @@ arm_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
   write_register (ARM_A1_REGNUM, addr);
 }
 
+static int
+arm_get_longjmp_target (CORE_ADDR *pc)
+{
+  CORE_ADDR jb_addr;
+  char buf[INT_REGISTER_RAW_SIZE];
+  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  
+  jb_addr = read_register (ARM_A1_REGNUM);
+
+  if (target_read_memory (jb_addr + tdep->jb_pc * tdep->jb_elt_size, buf,
+                         INT_REGISTER_RAW_SIZE))
+    return 0;
+
+  *pc = extract_address (buf, INT_REGISTER_RAW_SIZE);
+  return 1;
+}
+
 /* Return non-zero if the PC is inside a thumb call thunk.  */
 
 int
@@ -2775,7 +2792,9 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
                      "arm_gdbarch_init: bad byte order for float format");
     }
 
+  /* This should be low enough for everything.  */
   tdep->lowest_pc = 0x20;
+  tdep->jb_pc = -1; /* Longjump support not enabled by default.  */
 
   set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
 
@@ -2904,6 +2923,9 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Now we have tuned the configuration, set a few final things,
      based on what the OS ABI has told us.  */
 
+  if (tdep->jb_pc >= 0)
+    set_gdbarch_get_longjmp_target (gdbarch, arm_get_longjmp_target);
+
   /* We can't use SIZEOF_FRAME_SAVED_REGS here, since that still
      references the old architecture vector, not the one we are
      building here.  */
index 85d9e4fb0cec5c75203ca66e362cbcd30781f706..29c8bc97dbc983a5842bf08eb3d0367cb0775050 100644 (file)
@@ -123,10 +123,16 @@ struct gdbarch_tdep
   const char *abi_name;                /* Name of the above.  */
   CORE_ADDR lowest_pc;         /* Lowest address at which instructions 
                                   will appear.  */
-  const char *arm_breakpoint;
-  int arm_breakpoint_size;
-  const char *thumb_breakpoint;
-  int thumb_breakpoint_size;
+
+  const char *arm_breakpoint;  /* Breakpoint pattern for an ARM insn.  */
+  int arm_breakpoint_size;     /* And its size.  */
+  const char *thumb_breakpoint;        /* Breakpoint pattern for an ARM insn.  */
+  int thumb_breakpoint_size;   /* And its size.  */
+
+  int jb_pc;                   /* Offset to PC value in jump buffer. 
+                                  If this is negative, longjmp support
+                                  will be disabled.  */
+  size_t jb_elt_size;          /* And the size of each entry in the buf.  */
 };
 
 #ifndef LOWEST_PC
index a270772b059001fc4e78d8be98d36ce2ac49a4f0..2d09bd3f62dd6aedf872d031b5b133123e6e769e 100644 (file)
@@ -97,9 +97,3 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, ignore)
 #else
 #error Not FETCH_INFERIOR_REGISTERS 
 #endif /* !FETCH_INFERIOR_REGISTERS */
-
-int 
-get_longjmp_target (CORE_ADDR *addr)
-{
-  return 0;
-}
index 25c2f164247fa1a13078dc859df26c2dca64116e..291273b1fb8b74dc7376047fa007b8c723860aa8 100644 (file)
 
 #include "arm-tdep.h"
 
+/* Description of the longjmp buffer.  */
+#define JB_PC 24
+#define JB_ELEMENT_SIZE INT_REGISTER_RAW_SIZE
+
 /* For compatibility with previous implemenations of GDB on arm/NetBSD,
    override the default little-endian breakpoint.  */
 static const char arm_nbsd_arm_le_breakpoint[] = {0x11, 0x00, 0x00, 0xe6};
@@ -35,6 +39,9 @@ arm_netbsd_init_abi_common (struct gdbarch_info info,
   tdep->lowest_pc = 0x8000;
   tdep->arm_breakpoint = arm_nbsd_arm_le_breakpoint;
   tdep->arm_breakpoint_size = sizeof (arm_nbsd_arm_le_breakpoint);
+
+  tdep->jb_pc = JB_PC;
+  tdep->jb_elt_size = JB_ELEMENT_SIZE;
 }
   
 static void
index b22a2069b570f49918d98c47dfdd30f4cf8c8582..640505eab5898986fd3ceeeddc68a049e43bec59 100644 (file)
@@ -143,9 +143,7 @@ static int cover_target_enable_exception_callback (PTR);
 
 static void maintenance_info_breakpoints (char *, int);
 
-#ifdef GET_LONGJMP_TARGET
 static void create_longjmp_breakpoint (char *);
-#endif
 
 static void create_overlay_event_breakpoint (char *);
 
@@ -3758,7 +3756,6 @@ create_internal_breakpoint (CORE_ADDR address, enum bptype type)
   return b;
 }
 
-#ifdef GET_LONGJMP_TARGET
 
 static void
 create_longjmp_breakpoint (char *func_name)
@@ -3782,8 +3779,6 @@ create_longjmp_breakpoint (char *func_name)
     b->addr_string = xstrdup (func_name);
 }
 
-#endif /* #ifdef GET_LONGJMP_TARGET */
-
 /* Call this routine when stepping and nexting to enable a breakpoint
    if we do a longjmp().  When we hit that breakpoint, call
    set_longjmp_resume_breakpoint() to figure out where we are going. */
@@ -6967,13 +6962,14 @@ breakpoint_re_set (void)
   set_language (save_language);
   input_radix = save_input_radix;
 
-#ifdef GET_LONGJMP_TARGET
-  create_longjmp_breakpoint ("longjmp");
-  create_longjmp_breakpoint ("_longjmp");
-  create_longjmp_breakpoint ("siglongjmp");
-  create_longjmp_breakpoint ("_siglongjmp");
-  create_longjmp_breakpoint (NULL);
-#endif
+  if (GET_LONGJMP_TARGET_P ())
+    {
+      create_longjmp_breakpoint ("longjmp");
+      create_longjmp_breakpoint ("_longjmp");
+      create_longjmp_breakpoint ("siglongjmp");
+      create_longjmp_breakpoint ("_siglongjmp");
+      create_longjmp_breakpoint (NULL);
+    }
   
   create_overlay_event_breakpoint ("_ovly_debug_event");
 }
index aa3fa52cee83620b05850144106618b01e709dc2..11de4fac7c7bcc8ddc3d341bc81fe77c65296fc7 100644 (file)
@@ -76,14 +76,6 @@ extern CORE_ADDR arm_linux_push_arguments (int, struct value **, CORE_ADDR,
 /* Offset to saved PC in sigcontext structure, from <asm/sigcontext.h> */
 #define SIGCONTEXT_PC_OFFSET   (sizeof(unsigned long) * 18)
 
-/* Figure out where the longjmp will land.  The code expects that longjmp
-   has just been entered and the code had not altered the registers, so
-   the arguments are are still in r0-r1.  r0 points at the jmp_buf structure
-   from which the target pc (JB_PC) is extracted.  This pc value is copied
-   into ADDR.  This routine returns true on success */
-extern int arm_get_longjmp_target (CORE_ADDR *);
-#define GET_LONGJMP_TARGET(addr)       arm_get_longjmp_target (addr)
-
 /* On ARM Linux, each call to a library routine goes through a small piece
    of trampoline code in the ".plt" section.  The  wait_for_inferior() 
    routine uses this macro to detect when we have stepped into one of 
index 4dfc32916eede229d9cf2b946906091d800f6c27..5119879fe475a1a60a55eff91fbce643d1f32447 100644 (file)
 #include "arm/tm-arm.h"
 #include "tm-nbsd.h"
 
-#define JB_ELEMENT_SIZE sizeof(long)   /* jmp_buf[_JBLEN] is array of ints */
-#define JB_PC  24              /* Setjmp()'s return PC saved here */
-
 /* Return non-zero if inside a shared-library entry stub.  */
 #undef IN_SOLIB_CALL_TRAMPOLINE
 #define IN_SOLIB_CALL_TRAMPOLINE(pc, name) \
   STREQ ((name), "_PROCEDURE_LINKAGE_TABLE_")
 
-/* Figure out where the longjmp will land.  Slurp the args out of the stack.
-   We expect the first arg to be a pointer to the jmp_buf structure from which
-   we extract the pc (JB_PC) that we will land at.  The pc is copied into ADDR.
-   This routine returns true on success */
-
-extern int
-get_longjmp_target (CORE_ADDR *);
-
-#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
-
 /* By convention, NetBSD uses the "other" register names. */
 #define DEFAULT_REGISTER_NAMES additional_register_names
 
index f4000b52f2bb45314ecb3bfae42701bd746e430b..8467d414237e96c42e55dd9a94211f54b7efc414 100644 (file)
@@ -182,6 +182,7 @@ struct gdbarch
   gdbarch_register_bytes_ok_ftype *register_bytes_ok;
   gdbarch_cannot_fetch_register_ftype *cannot_fetch_register;
   gdbarch_cannot_store_register_ftype *cannot_store_register;
+  gdbarch_get_longjmp_target_ftype *get_longjmp_target;
   int use_generic_dummy_frames;
   int call_dummy_location;
   gdbarch_call_dummy_address_ftype *call_dummy_address;
@@ -346,6 +347,7 @@ struct gdbarch startup_gdbarch =
   0,
   0,
   0,
+  0,
   generic_get_saved_register,
   0,
   0,
@@ -638,6 +640,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of register_bytes_ok, has predicate */
   /* Skip verify of cannot_fetch_register, invalid_p == 0 */
   /* Skip verify of cannot_store_register, invalid_p == 0 */
+  /* Skip verify of get_longjmp_target, has predicate */
   if ((GDB_MULTI_ARCH >= GDB_MULTI_ARCH_PARTIAL)
       && (gdbarch->use_generic_dummy_frames == -1))
     fprintf_unfiltered (log, "\n\tuse_generic_dummy_frames");
@@ -1282,6 +1285,17 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
                       "gdbarch_dump: FUNCTION_START_OFFSET = %ld\n",
                       (long) FUNCTION_START_OFFSET);
 #endif
+#ifdef GET_LONGJMP_TARGET
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: %s # %s\n",
+                      "GET_LONGJMP_TARGET(pc)",
+                      XSTRING (GET_LONGJMP_TARGET (pc)));
+  if (GDB_MULTI_ARCH)
+    fprintf_unfiltered (file,
+                        "gdbarch_dump: GET_LONGJMP_TARGET = 0x%08lx\n",
+                        (long) current_gdbarch->get_longjmp_target
+                        /*GET_LONGJMP_TARGET ()*/);
+#endif
 #ifdef GET_SAVED_REGISTER
 #if GDB_MULTI_ARCH
   /* Macro might contain `[{}]' when not multi-arch */
@@ -3029,6 +3043,30 @@ set_gdbarch_cannot_store_register (struct gdbarch *gdbarch,
   gdbarch->cannot_store_register = cannot_store_register;
 }
 
+int
+gdbarch_get_longjmp_target_p (struct gdbarch *gdbarch)
+{
+  return gdbarch->get_longjmp_target != 0;
+}
+
+int
+gdbarch_get_longjmp_target (struct gdbarch *gdbarch, CORE_ADDR *pc)
+{
+  if (gdbarch->get_longjmp_target == 0)
+    internal_error (__FILE__, __LINE__,
+                    "gdbarch: gdbarch_get_longjmp_target invalid");
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_get_longjmp_target called\n");
+  return gdbarch->get_longjmp_target (pc);
+}
+
+void
+set_gdbarch_get_longjmp_target (struct gdbarch *gdbarch,
+                                gdbarch_get_longjmp_target_ftype get_longjmp_target)
+{
+  gdbarch->get_longjmp_target = get_longjmp_target;
+}
+
 int
 gdbarch_use_generic_dummy_frames (struct gdbarch *gdbarch)
 {
index da5156cbf41874a28a0dcda6f1bd4497a9e2d10e..2dba00f3ee1e1f24cc5768b5e4a8cadebbff27f6 100644 (file)
@@ -883,6 +883,45 @@ extern void set_gdbarch_cannot_store_register (struct gdbarch *gdbarch, gdbarch_
 #endif
 #endif
 
+/* setjmp/longjmp support. */
+
+#if defined (GET_LONGJMP_TARGET)
+/* Legacy for systems yet to multi-arch GET_LONGJMP_TARGET */
+#if !defined (GET_LONGJMP_TARGET_P)
+#define GET_LONGJMP_TARGET_P() (1)
+#endif
+#endif
+
+/* Default predicate for non- multi-arch targets. */
+#if (!GDB_MULTI_ARCH) && !defined (GET_LONGJMP_TARGET_P)
+#define GET_LONGJMP_TARGET_P() (0)
+#endif
+
+extern int gdbarch_get_longjmp_target_p (struct gdbarch *gdbarch);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (GET_LONGJMP_TARGET_P)
+#error "Non multi-arch definition of GET_LONGJMP_TARGET"
+#endif
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (GET_LONGJMP_TARGET_P)
+#define GET_LONGJMP_TARGET_P() (gdbarch_get_longjmp_target_p (current_gdbarch))
+#endif
+
+/* Default (function) for non- multi-arch platforms. */
+#if (!GDB_MULTI_ARCH) && !defined (GET_LONGJMP_TARGET)
+#define GET_LONGJMP_TARGET(pc) (internal_error (__FILE__, __LINE__, "GET_LONGJMP_TARGET"), 0)
+#endif
+
+typedef int (gdbarch_get_longjmp_target_ftype) (CORE_ADDR *pc);
+extern int gdbarch_get_longjmp_target (struct gdbarch *gdbarch, CORE_ADDR *pc);
+extern void set_gdbarch_get_longjmp_target (struct gdbarch *gdbarch, gdbarch_get_longjmp_target_ftype *get_longjmp_target);
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) && defined (GET_LONGJMP_TARGET)
+#error "Non multi-arch definition of GET_LONGJMP_TARGET"
+#endif
+#if GDB_MULTI_ARCH
+#if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL) || !defined (GET_LONGJMP_TARGET)
+#define GET_LONGJMP_TARGET(pc) (gdbarch_get_longjmp_target (current_gdbarch, pc))
+#endif
+#endif
+
 /* Non multi-arch DUMMY_FRAMES are a mess (multi-arch ones are not that
    much better but at least they are vaguely consistent).  The headers
    and body contain convoluted #if/#else sequences for determine how
index 29aca346371c8b178817c049091120856e5d82e8..996b87668d367f6fb5e91102554a3a7a68c9197b 100755 (executable)
@@ -466,6 +466,8 @@ f:2:REGISTER_SIM_REGNO:int:register_sim_regno:int reg_nr:reg_nr:::default_regist
 F:2:REGISTER_BYTES_OK:int:register_bytes_ok:long nr_bytes:nr_bytes::0:0
 f:2:CANNOT_FETCH_REGISTER:int:cannot_fetch_register:int regnum:regnum:::cannot_register_not::0
 f:2:CANNOT_STORE_REGISTER:int:cannot_store_register:int regnum:regnum:::cannot_register_not::0
+# setjmp/longjmp support.
+F:2:GET_LONGJMP_TARGET:int:get_longjmp_target:CORE_ADDR *pc:pc::0:0
 #
 # Non multi-arch DUMMY_FRAMES are a mess (multi-arch ones are not that
 # much better but at least they are vaguely consistent).  The headers
index c935db86a7b978aaacaf53bd486c6f7dd266b46d..1efe87b936782d75cec08d5b15799abb673b358a 100644 (file)
@@ -114,15 +114,6 @@ static ptid_t previous_inferior_ptid;
 
 static int may_follow_exec = MAY_FOLLOW_EXEC;
 
-/* GET_LONGJMP_TARGET returns the PC at which longjmp() will resume the
-   program.  It needs to examine the jmp_buf argument and extract the PC
-   from it.  The return value is non-zero on success, zero otherwise. */
-
-#ifndef GET_LONGJMP_TARGET
-#define GET_LONGJMP_TARGET(PC_ADDR) 0
-#endif
-
-
 /* Dynamic function trampolines are similar to solib trampolines in that they
    are between the caller and the callee.  The difference is that when you
    enter a dynamic trampoline, you can't determine the callee's address.  Some
@@ -2306,7 +2297,8 @@ handle_inferior_event (struct execution_control_state *ecs)
          disable_longjmp_breakpoint ();
          remove_breakpoints ();
          breakpoints_inserted = 0;
-         if (!GET_LONGJMP_TARGET (&jmp_buf_pc))
+         if (!GET_LONGJMP_TARGET_P ()
+             || !GET_LONGJMP_TARGET (&jmp_buf_pc))
            {
              keep_going (ecs);
              return;
This page took 0.036347 seconds and 4 git commands to generate.