Remove non-address bits for longjmp resume breakpoint
authorAndreas Arnez <arnez@linux.vnet.ibm.com>
Thu, 9 Oct 2014 11:32:22 +0000 (11:32 +0000)
committerUlrich Weigand <ulrich.weigand@de.ibm.com>
Wed, 15 Oct 2014 15:32:38 +0000 (17:32 +0200)
On 32-bit S390 targets the longjmp target address "naturally" has the
most significant bit set.  That bit indicates the addressing mode and
is not part of the address itself.  Thus, in analogy with similar
cases (like when computing the caller PC in
insert_step_resume_breakpoint_at_caller), this change removes
non-address bits from the longjmp target address before using it as a
breakpoint address.

Note that there are two ways for determining the longjmp target
address: via a probe or via a gdbarch method.  This change only
affects the probe method, because it is assumed that the address
returned by the gdbarch method is usable as-is.

This change was tested together with a patch that enables longjmp
probes in glibc for S/390:

  https://sourceware.org/ml/libc-alpha/2014-10/msg00277.html

gdb/ChangeLog:

* gdb/infrun.c (process_event_stop_test): Apply
gdbarch_addr_bits_remove to longjmp resume address.

gdb/ChangeLog
gdb/infrun.c

index 977590a9f116b4875f4954a7675ae3e255d12244..a43e36e05919edad1b364ccd9b4ebaae5b27ff71 100644 (file)
@@ -1,3 +1,8 @@
+2014-10-15  Andreas Arnez  <arnez@linux.vnet.ibm.com>
+
+       * gdb/infrun.c (process_event_stop_test): Apply
+       gdbarch_addr_bits_remove to longjmp resume address.
+
 2014-10-15  Pedro Alves  <palves@redhat.com>
 
        * regformats/microblaze.dat: Delete file.
index 553635032415e7441da01b12d5c35079c7ff806d..613227463a170f50727550e6a42b4c3a7ff9b3de 100644 (file)
@@ -4596,7 +4596,10 @@ process_event_stop_test (struct execution_control_state *ecs)
             is the third argument to the probe.  */
          arg_value = probe_safe_evaluate_at_pc (frame, 2);
          if (arg_value)
-           jmp_buf_pc = value_as_address (arg_value);
+           {
+             jmp_buf_pc = value_as_address (arg_value);
+             jmp_buf_pc = gdbarch_addr_bits_remove (gdbarch, jmp_buf_pc);
+           }
          else if (!gdbarch_get_longjmp_target_p (gdbarch)
                   || !gdbarch_get_longjmp_target (gdbarch,
                                                   frame, &jmp_buf_pc))