From patchwork Sat Apr 14 19:09:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pedro Alves X-Patchwork-Id: 26719 Received: (qmail 125710 invoked by alias); 14 Apr 2018 19:10:22 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 125594 invoked by uid 89); 14 Apr 2018 19:10:21 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.5 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT autolearn=ham version=3.3.2 spammy=18818, STEP X-HELO: mx1.redhat.com Received: from mx3-rdu2.redhat.com (HELO mx1.redhat.com) (66.187.233.73) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 14 Apr 2018 19:10:18 +0000 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BA19A406E8A4 for ; Sat, 14 Apr 2018 19:10:15 +0000 (UTC) Received: from localhost.localdomain (ovpn04.gateway.prod.ext.ams2.redhat.com [10.39.146.4]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6A822215CDC8 for ; Sat, 14 Apr 2018 19:10:15 +0000 (UTC) From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH 32/40] target_ops/C++: Generic i386/AMD64 BSD targets Date: Sat, 14 Apr 2018 20:09:45 +0100 Message-Id: <20180414190953.24481-33-palves@redhat.com> In-Reply-To: <20180414190953.24481-1-palves@redhat.com> References: <20180414190953.24481-1-palves@redhat.com> The $architecture x NetBSD/OpenBSD/FreeBSD support matrix complicates things a bit. There's common BSD target code, and there's common architecture-specific code shared between the different BSDs. Current, all that is stiched together to form a final target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target functions etc. Introduces generic i386/AMD64 BSD targets, to be used as template mixin to build a final target. --- gdb/amd64-bsd-nat.c | 24 ++++-------------------- gdb/amd64-bsd-nat.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ gdb/amd64-fbsd-nat.c | 26 +++++++++++++++----------- gdb/amd64-nat.h | 5 ----- gdb/i386-bsd-nat.c | 24 ++++-------------------- gdb/i386-bsd-nat.h | 22 ++++++++++++++++++---- gdb/i386-fbsd-nat.c | 37 ++++++++++++++++++++----------------- gdb/x86-bsd-nat.c | 27 ++------------------------- gdb/x86-bsd-nat.h | 21 +++++++++++++++++---- 9 files changed, 124 insertions(+), 106 deletions(-) create mode 100644 gdb/amd64-bsd-nat.h diff --git a/gdb/amd64-bsd-nat.c b/gdb/amd64-bsd-nat.c index d3a516f875..74a1842de9 100644 --- a/gdb/amd64-bsd-nat.c +++ b/gdb/amd64-bsd-nat.c @@ -38,9 +38,8 @@ /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this for all registers (including the floating-point registers). */ -static void -amd64bsd_fetch_inferior_registers (struct target_ops *ops, - struct regcache *regcache, int regnum) +void +amd64bsd_fetch_inferior_registers (struct regcache *regcache, int regnum) { struct gdbarch *gdbarch = regcache->arch (); pid_t pid = get_ptrace_pid (regcache_get_ptid (regcache)); @@ -112,9 +111,8 @@ amd64bsd_fetch_inferior_registers (struct target_ops *ops, /* Store register REGNUM back into the inferior. If REGNUM is -1, do this for all registers (including the floating-point registers). */ -static void -amd64bsd_store_inferior_registers (struct target_ops *ops, - struct regcache *regcache, int regnum) +void +amd64bsd_store_inferior_registers (struct regcache *regcache, int regnum) { struct gdbarch *gdbarch = regcache->arch (); pid_t pid = get_ptrace_pid (regcache_get_ptid (regcache)); @@ -193,17 +191,3 @@ amd64bsd_store_inferior_registers (struct target_ops *ops, perror_with_name (_("Couldn't write floating point status")); } } - -/* Create a prototype *BSD/amd64 target. The client can override it - with local methods. */ - -struct target_ops * -amd64bsd_target (void) -{ - struct target_ops *t; - - t = x86bsd_target (); - t->to_fetch_registers = amd64bsd_fetch_inferior_registers; - t->to_store_registers = amd64bsd_store_inferior_registers; - return t; -} diff --git a/gdb/amd64-bsd-nat.h b/gdb/amd64-bsd-nat.h new file mode 100644 index 0000000000..84528ca625 --- /dev/null +++ b/gdb/amd64-bsd-nat.h @@ -0,0 +1,44 @@ +/* Native-dependent code for modern AMD64 BSD's. + + Copyright (C) 2018 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef AMD64_BSD_NAT_H +#define AMD64_BSD_NAT_H + +#include "x86-bsd-nat.h" + +/* Helper functions. See definitions. */ +extern void amd64bsd_fetch_inferior_registers (struct regcache *regcache, + int regnum); +extern void amd64bsd_store_inferior_registers (struct regcache *regcache, + int regnum); + +/* A prototype *BSD/AMD64 target. */ + +template +class amd64_bsd_nat_target : public x86bsd_nat_target +{ +public: + void fetch_registers (struct regcache *regcache, int regnum) override + { amd64bsd_fetch_inferior_registers (regcache, regnum); } + + void store_registers (struct regcache *regcache, int regnum) override + { amd64bsd_store_inferior_registers (regcache, regnum); } +}; + +#endif /* i386-bsd-nat.h */ diff --git a/gdb/amd64-fbsd-nat.c b/gdb/amd64-fbsd-nat.c index 07963f508d..d1c62d79e8 100644 --- a/gdb/amd64-fbsd-nat.c +++ b/gdb/amd64-fbsd-nat.c @@ -32,11 +32,21 @@ #include "fbsd-nat.h" #include "amd64-tdep.h" #include "amd64-nat.h" -#include "x86-bsd-nat.h" +#include "amd64-bsd-nat.h" #include "x86-nat.h" #include "x86-xstate.h" +class amd64_fbsd_nat_target final + : public amd64_bsd_nat_target +{ +public: + /* Add some extra features to the common *BSD/i386 target. */ + const struct target_desc *read_description () override; +}; + +static amd64_fbsd_nat_target the_amd64_fbsd_nat_target; + /* Offset in `struct reg' where MEMBER is stored. */ #define REG_OFFSET(member) offsetof (struct reg, member) @@ -141,10 +151,10 @@ amd64fbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) } -/* Implement the to_read_description method. */ +/* Implement the read_description method. */ -static const struct target_desc * -amd64fbsd_read_description (struct target_ops *ops) +const struct target_desc * +amd64_fbsd_nat_target::read_description (struct target_ops *ops) { #ifdef PT_GETXSTATE_INFO static int xsave_probed; @@ -188,18 +198,12 @@ amd64fbsd_read_description (struct target_ops *ops) void _initialize_amd64fbsd_nat (void) { - struct target_ops *t; + struct target_ops *t = &the_amd64_fbsd_nat_target; int offset; amd64_native_gregset32_reg_offset = amd64fbsd32_r_reg_offset; amd64_native_gregset64_reg_offset = amd64fbsd64_r_reg_offset; - /* Add some extra features to the common *BSD/i386 target. */ - t = amd64bsd_target (); - t->to_read_description = amd64fbsd_read_description; - - fbsd_nat_add_target (t); - /* Support debugging kernel virtual memory images. */ bsd_kvm_add_target (amd64fbsd_supply_pcb); diff --git a/gdb/amd64-nat.h b/gdb/amd64-nat.h index c1a4a87cd4..11bddf5c9e 100644 --- a/gdb/amd64-nat.h +++ b/gdb/amd64-nat.h @@ -49,9 +49,4 @@ extern void amd64_supply_native_gregset (struct regcache *regcache, extern void amd64_collect_native_gregset (const struct regcache *regcache, void *gregs, int regnum); -/* Create a prototype *BSD/amd64 target. The client can override it - with local methods. */ - -extern struct target_ops *amd64bsd_target (void); - #endif /* amd64-nat.h */ diff --git a/gdb/i386-bsd-nat.c b/gdb/i386-bsd-nat.c index ef2b534129..f7f27ceba0 100644 --- a/gdb/i386-bsd-nat.c +++ b/gdb/i386-bsd-nat.c @@ -127,9 +127,8 @@ i386bsd_collect_gregset (const struct regcache *regcache, /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this for all registers (including the floating point registers). */ -static void -i386bsd_fetch_inferior_registers (struct target_ops *ops, - struct regcache *regcache, int regnum) +void +i386bsd_fetch_inferior_registers (struct regcache *regcache, int regnum) { pid_t pid = get_ptrace_pid (regcache_get_ptid (regcache)); @@ -191,9 +190,8 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops, /* Store register REGNUM back into the inferior. If REGNUM is -1, do this for all registers (including the floating point registers). */ -static void -i386bsd_store_inferior_registers (struct target_ops *ops, - struct regcache *regcache, int regnum) +void +i386bsd_store_inferior_registers (struct regcache *regcache, int regnum) { pid_t pid = get_ptrace_pid (regcache_get_ptid (regcache)); @@ -267,20 +265,6 @@ i386bsd_store_inferior_registers (struct target_ops *ops, } } -/* Create a prototype *BSD/i386 target. The client can override it - with local methods. */ - -struct target_ops * -i386bsd_target (void) -{ - struct target_ops *t; - - t = x86bsd_target (); - t->to_fetch_registers = i386bsd_fetch_inferior_registers; - t->to_store_registers = i386bsd_store_inferior_registers; - return t; -} - void _initialize_i386bsd_nat (void) { diff --git a/gdb/i386-bsd-nat.h b/gdb/i386-bsd-nat.h index 72eec39274..b5acc70482 100644 --- a/gdb/i386-bsd-nat.h +++ b/gdb/i386-bsd-nat.h @@ -20,9 +20,23 @@ #ifndef I386_BSD_NAT_H #define I386_BSD_NAT_H -/* Create a prototype *BSD/i386 target. The client can override it - with local methods. */ - -extern struct target_ops *i386bsd_target (void); +/* Helper functions. See definitions. */ +extern void i386bsd_fetch_inferior_registers (struct regcache *regcache, + int regnum); +extern void i386bsd_store_inferior_registers (struct regcache *regcache, + int regnum); + +/* A prototype *BSD/i386 target. */ + +template +class i386_bsd_nat_target : public x86bsd_nat_target +{ +public: + void fetch_registers (struct regcache *regcache, int regnum) override + { i386bsd_fetch_inferior_registers (regcache, regnum); } + + void store_registers (struct regcache *, int) override + { i386bsd_store_inferior_registers (regcache, regnum); } +}; #endif /* i386-bsd-nat.h */ diff --git a/gdb/i386-fbsd-nat.c b/gdb/i386-fbsd-nat.c index c7b8f9a1f9..f2bb82c4c0 100644 --- a/gdb/i386-fbsd-nat.c +++ b/gdb/i386-fbsd-nat.c @@ -34,12 +34,25 @@ #include "x86-bsd-nat.h" #include "i386-bsd-nat.h" +class i386_fbsd_nat_target final + : public i386_bsd_nat_target +{ +public: + /* Add some extra features to the common *BSD/i386 target. */ +#ifdef PT_GETXSTATE_INFO + const struct target_desc *read_description () override; +#endif + + void resume (ptid_t, int, enum gdb_signal) override; +}; + +static i386_fbsd_nat_target the_i386_fbsd_nat_target; + /* Resume execution of the inferior process. If STEP is nonzero, single-step it. If SIGNAL is nonzero, give it that signal. */ -static void -i386fbsd_resume (struct target_ops *ops, - ptid_t ptid, int step, enum gdb_signal signal) +void +i386_fbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signal) { pid_t pid = ptid_get_pid (ptid); int request = PT_STEP; @@ -119,10 +132,10 @@ i386fbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb) #ifdef PT_GETXSTATE_INFO -/* Implement the to_read_description method. */ +/* Implement the read_description method. */ -static const struct target_desc * -i386fbsd_read_description (struct target_ops *ops) +const struct target_desc * +i386_fbsd_nat_traget::read_description () { static int xsave_probed; static uint64_t xcr0; @@ -150,17 +163,7 @@ i386fbsd_read_description (struct target_ops *ops) void _initialize_i386fbsd_nat (void) { - struct target_ops *t; - - /* Add some extra features to the common *BSD/i386 target. */ - t = i386bsd_target (); - -#ifdef PT_GETXSTATE_INFO - t->to_read_description = i386fbsd_read_description; -#endif - - t->to_resume = i386fbsd_resume; - fbsd_nat_add_target (t); + add_target (&the_i386_fbsd_nat_target); /* Support debugging kernel virtual memory images. */ bsd_kvm_add_target (i386fbsd_supply_pcb); diff --git a/gdb/x86-bsd-nat.c b/gdb/x86-bsd-nat.c index dff2a004a5..542bcd0603 100644 --- a/gdb/x86-bsd-nat.c +++ b/gdb/x86-bsd-nat.c @@ -40,16 +40,6 @@ size_t x86bsd_xsave_len; /* Support for debug registers. */ #ifdef HAVE_PT_GETDBREGS -static void (*super_mourn_inferior) (struct target_ops *ops); - -/* Implement the "to_mourn_inferior" target_ops method. */ - -static void -x86bsd_mourn_inferior (struct target_ops *ops) -{ - x86_cleanup_dregs (); - super_mourn_inferior (ops); -} /* Helper macro to access debug register X. FreeBSD/amd64 and modern versions of FreeBSD/i386 provide this macro in system headers. Define @@ -134,28 +124,15 @@ x86bsd_dr_get_control (void) #endif /* PT_GETDBREGS */ -/* Create a prototype *BSD/x86 target. The client can override it - with local methods. */ - -struct target_ops * -x86bsd_target (void) +void +_initialize_x86_bsd_nat () { - struct target_ops *t; - - t = inf_ptrace_target (); - #ifdef HAVE_PT_GETDBREGS - x86_use_watchpoints (t); - x86_dr_low.set_control = x86bsd_dr_set_control; x86_dr_low.set_addr = x86bsd_dr_set_addr; x86_dr_low.get_addr = x86bsd_dr_get_addr; x86_dr_low.get_status = x86bsd_dr_get_status; x86_dr_low.get_control = x86bsd_dr_get_control; x86_set_debug_register_length (sizeof (void *)); - super_mourn_inferior = t->to_mourn_inferior; - t->to_mourn_inferior = x86bsd_mourn_inferior; #endif /* HAVE_PT_GETDBREGS */ - - return t; } diff --git a/gdb/x86-bsd-nat.h b/gdb/x86-bsd-nat.h index ced33ac6aa..1aee5fbc46 100644 --- a/gdb/x86-bsd-nat.h +++ b/gdb/x86-bsd-nat.h @@ -20,12 +20,25 @@ #ifndef X86_BSD_NAT_H #define X86_BSD_NAT_H +#include "x86-nat.h" + /* Low level x86 XSAVE info. */ extern size_t x86bsd_xsave_len; -/* Create a prototype *BSD/x86 target. The client can override it - with local methods. */ - -extern struct target_ops *x86bsd_target (void); +/* A prototype *BSD/x86 target. */ + +template +class x86bsd_nat_target : public x86_nat_target +{ + using base_class = x86_nat_target; +public: +#ifdef HAVE_PT_GETDBREGS + void mourn_inferior () override + { + x86_cleanup_dregs (); + base_class::mourn_inferior (); + } +#endif /* HAVE_PT_GETDBREGS */ +}; #endif /* x86-bsd-nat.h */