Don't compile x86 debug register support on OpenBSD.
authorJohn Baldwin <jhb@FreeBSD.org>
Thu, 29 Jul 2021 20:16:28 +0000 (13:16 -0700)
committerJohn Baldwin <jhb@FreeBSD.org>
Thu, 29 Jul 2021 20:16:28 +0000 (13:16 -0700)
Simon Marchi tried gdb on OpenBSD, and it immediately segfaults when
running a program.  Simon tracked down the problem to x86_dr_low.get_status
being nullptr at this point:

    (lldb) print x86_dr_low.get_status
    (unsigned long (*)()) $0 = 0x0000000000000000
    (lldb) bt
    * thread #1, stop reason = step over
      * frame #0: 0x0000033b64b764aa gdb`x86_dr_stopped_data_address(state=0x0000033d7162a310, addr_p=0x00007f7ffffc5688) at x86-dregs.c:645:12
        frame #1: 0x0000033b64b766de gdb`x86_dr_stopped_by_watchpoint(state=0x0000033d7162a310) at x86-dregs.c:687:10
        frame #2: 0x0000033b64ea5f72 gdb`x86_stopped_by_watchpoint() at x86-nat.c:206:10
        frame #3: 0x0000033b64637fbb gdb`x86_nat_target<obsd_nat_target>::stopped_by_watchpoint(this=0x0000033b65252820) at x86-nat.h:100:12
        frame #4: 0x0000033b64d3ff11 gdb`target_stopped_by_watchpoint() at target.c:468:46
        frame #5: 0x0000033b6469b001 gdb`watchpoints_triggered(ws=0x00007f7ffffc61c8) at breakpoint.c:4790:32
        frame #6: 0x0000033b64a8bb8b gdb`handle_signal_stop(ecs=0x00007f7ffffc61a0) at infrun.c:6072:29
        frame #7: 0x0000033b64a7e3a7 gdb`handle_inferior_event(ecs=0x00007f7ffffc61a0) at infrun.c:5694:7
        frame #8: 0x0000033b64a7c1a0 gdb`fetch_inferior_event() at infrun.c:4090:5
        frame #9: 0x0000033b64a51921 gdb`inferior_event_handler(event_type=INF_REG_EVENT) at inf-loop.c:41:7
        frame #10: 0x0000033b64a827c9 gdb`infrun_async_inferior_event_handler(data=0x0000000000000000) at infrun.c:9384:3
        frame #11: 0x0000033b6465bd4f gdb`check_async_event_handlers() at async-event.c:335:4
        frame #12: 0x0000033b65070917 gdb`gdb_do_one_event() at event-loop.cc:216:10
        frame #13: 0x0000033b64af0db1 gdb`start_event_loop() at main.c:421:13
        frame #14: 0x0000033b64aefe9a gdb`captured_command_loop() at main.c:481:3
        frame #15: 0x0000033b64aed5c2 gdb`captured_main(data=0x00007f7ffffc6470) at main.c:1353:4
        frame #16: 0x0000033b64aed4f2 gdb`gdb_main(args=0x00007f7ffffc6470) at main.c:1368:7
        frame #17: 0x0000033b6459d787 gdb`main(argc=5, argv=0x00007f7ffffc6518) at gdb.c:32:10
        frame #18: 0x0000033b6459d521 gdb`___start + 321

On BSDs, get_status is set in _initialize_x86_bsd_nat, but only if
HAVE_PT_GETDBREGS is defined.  PT_GETDBREGS doesn't exist on OpenBSD, so
get_status (and the other fields of x86_dr_low) are left as nullptr.

OpenBSD doesn't support getting or setting the x86 debug registers, so
fix by omitting debug register support entirely on OpenBSD:

- Change x86bsd_nat_target to only inherit from x86_nat_target if
  PT_GETDBREGS is supported.

- Don't include x86-nat.o and nat/x86-dregs.o for OpenBSD/amd64.  They
  were already omitted for OpenBSD/i386.

gdb/configure.nat
gdb/x86-bsd-nat.h

index e34cccffd98b14ee1ccafe97f7f788a9b2760572..655c75dd1abe4fae253e51ac1df3d109bc543fee 100644 (file)
@@ -451,9 +451,8 @@ case ${gdb_host} in
        case ${gdb_host_cpu} in
            i386)
                # Host: OpenBSD/amd64
-               NATDEPFILES="${NATDEPFILES} obsd-nat.o amd64-nat.o x86-nat.o \
-               x86-bsd-nat.o amd64-bsd-nat.o amd64-obsd-nat.o bsd-kvm.o \
-               nat/x86-dregs.o"
+               NATDEPFILES="${NATDEPFILES} obsd-nat.o amd64-nat.o \
+               x86-bsd-nat.o amd64-bsd-nat.o amd64-obsd-nat.o bsd-kvm.o"
                LOADLIBES='-lkvm'
                ;;
            mips)
index 02d61c20b0b28a950659205b9d291d44193a6069..caf62e38df65ea84815fd730e13e5edd23600eb2 100644 (file)
@@ -27,18 +27,23 @@ extern size_t x86bsd_xsave_len;
 
 /* A prototype *BSD/x86 target.  */
 
+#ifdef HAVE_PT_GETDBREGS
 template<typename BaseTarget>
 class x86bsd_nat_target : public x86_nat_target<BaseTarget>
 {
   using base_class = x86_nat_target<BaseTarget>;
 public:
-#ifdef HAVE_PT_GETDBREGS
   void mourn_inferior () override
   {
     x86_cleanup_dregs ();
     base_class::mourn_inferior ();
   }
-#endif /* HAVE_PT_GETDBREGS */
 };
+#else /* !HAVE_PT_GETDBREGS */
+template<typename BaseTarget>
+class x86bsd_nat_target : public BaseTarget
+{
+};
+#endif /* HAVE_PT_GETDBREGS */
 
 #endif /* x86-bsd-nat.h */