From patchwork Tue Feb 11 09:01:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Aktemur, Tankut Baris" X-Patchwork-Id: 37892 Received: (qmail 105622 invoked by alias); 11 Feb 2020 09:03:07 -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 105050 invoked by uid 89); 11 Feb 2020 09:03:07 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-22.3 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3 autolearn=ham version=3.3.1 spammy=thr, Tankut, tankutbarisaktemurintelcom, U*tankut.baris.aktemur X-HELO: mga11.intel.com Received: from mga11.intel.com (HELO mga11.intel.com) (192.55.52.93) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 11 Feb 2020 09:03:05 +0000 Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 Feb 2020 01:03:03 -0800 Received: from irvmail001.ir.intel.com ([163.33.26.43]) by orsmga003.jf.intel.com with ESMTP; 11 Feb 2020 01:03:02 -0800 Received: from ulvlx001.iul.intel.com (ulvlx001.iul.intel.com [172.28.207.17]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id 01B931Fj002047; Tue, 11 Feb 2020 09:03:02 GMT Received: from ulvlx001.iul.intel.com (localhost [127.0.0.1]) by ulvlx001.iul.intel.com with ESMTP id 01B931AJ010349; Tue, 11 Feb 2020 10:03:01 +0100 Received: (from taktemur@localhost) by ulvlx001.iul.intel.com with LOCAL id 01B931dE010345; Tue, 11 Feb 2020 10:03:01 +0100 From: Tankut Baris Aktemur To: gdb-patches@sourceware.org Subject: [PATCH 01/58] gdbserver: start turning the target ops vector into a class Date: Tue, 11 Feb 2020 10:01:13 +0100 Message-Id: <460b763f23ba70d06276b0233858126fb79db909.1581410932.git.tankut.baris.aktemur@intel.com> In-Reply-To: References: In-Reply-To: References: X-IsSubscribed: yes This is the beginning of a series of patches where the goal is to turn the target ops vector into a class and all the target op function pointers into methods of this class. This is done by first introducing a helper class, called 'process_target', that is initially empty. An instance of this class is added to the end of the current target ops vector. This new field is called 'pt'. We will gradually carry target ops to the new class, one by one, whereas the invocation of the target op will be converted to a method call on 'pt'. For instance, target op 'attach' is currently invoked as (*the_target->attach) (args) After moving 'attach' as a method to 'process_target', it will be invoked as the_target->pt->attach (args) In this process, the concrete target vector definitions (e.g. linux-low, win32-low, nto-low, etc.) are turned into derived classes of 'process_target', so that they can either inherit the default behavior of the target ops or can override the method. We prefer to make this transition gradually rather than in a single giant patch, to yield bite-size patches. The goal is that after each patch gdbserver will still be buildable and testable. The general rule of thumb when converting a target op to a method is this: (1) If the function call is protected with a NULL-check with an obvious default behavior, simply implement that default behavior in the base class (e.g.: supports_non_stop). (2) If there is no NULL-check guard, the method becomes pure virtual, and the derived targets are required to implement the method (e.g.: attach). (3) If there is a NULL-check but no apparent default behavior, or if the NULL-check is utilized to populate a feature support packet, introduce a 'supports_XYZ' method (e.g.: pid_to_exec_file). The overall strategy is to preserve the existing behavior as much as possible. When we're done moving all the target ops into 'process_target', the target op vector will contain nothing but the field 'pt'. At that point, the auxiliary class 'process_target' will simply meld into 'process_stratum_target' and the method calls of the form 'the_target->pt->xyz' will be turned into 'the_target->xyz'. gdbserver/ChangeLog: 2020-02-10 Tankut Baris Aktemur * target.h (class process_target): Define. (struct process_stratum_target): Add a new 'pt' field, which is a pointer to a 'process_target'. * linux-low.h (class linux_process_target): Define as a derived class of 'process_target'. * linux-low.c (linux_target_ops): Add a linux_process_target* as the 'pt' field. * lynx-low.h (class lynx_process_target): Define as a derived class of 'process_target'. * lynx-low.c (lynx_target_ops): Add a lynx_process_target* as the 'pt' field. * nto-low.h (class nto_process_target): Define as a derived class of 'process_target'. * nto-low.c (nto_target_ops): Add an nto_process_target* as the 'pt' field. * win32-low.h (class win32_process_target): Define as a derived class of 'process_target'. * win32-low.c (win32_target_ops): Add a win32_process_target* as the 'pt' field. --- gdbserver/linux-low.c | 5 +++++ gdbserver/linux-low.h | 7 +++++++ gdbserver/lynx-low.c | 39 +++++++++++++++++++++++++++++++++++++++ gdbserver/lynx-low.h | 7 +++++++ gdbserver/nto-low.c | 10 ++++++++++ gdbserver/nto-low.h | 7 +++++++ gdbserver/target.h | 11 +++++++++++ gdbserver/win32-low.c | 11 +++++++++++ gdbserver/win32-low.h | 7 +++++++ 9 files changed, 104 insertions(+) diff --git a/gdbserver/linux-low.c b/gdbserver/linux-low.c index 676dea26c63..17f360639a4 100644 --- a/gdbserver/linux-low.c +++ b/gdbserver/linux-low.c @@ -7354,6 +7354,10 @@ linux_get_hwcap2 (int wordsize) return hwcap2; } +/* The linux target ops object. */ + +static linux_process_target the_linux_target; + static process_stratum_target linux_target_ops = { linux_create_inferior, linux_post_create_inferior, @@ -7457,6 +7461,7 @@ static process_stratum_target linux_target_ops = { #else NULL, #endif + &the_linux_target, }; #ifdef HAVE_LINUX_REGSETS diff --git a/gdbserver/linux-low.h b/gdbserver/linux-low.h index e25ddd024dd..f17ac95fae8 100644 --- a/gdbserver/linux-low.h +++ b/gdbserver/linux-low.h @@ -264,6 +264,13 @@ struct linux_target_ops extern struct linux_target_ops the_low_target; +/* Target ops definitions for a Linux target. */ + +class linux_process_target : public process_target { +public: + +}; + #define get_thread_lwp(thr) ((struct lwp_info *) (thread_target_data (thr))) #define get_lwp_thread(lwp) ((lwp)->thread) diff --git a/gdbserver/lynx-low.c b/gdbserver/lynx-low.c index a5b019396fa..f1177920921 100644 --- a/gdbserver/lynx-low.c +++ b/gdbserver/lynx-low.c @@ -719,6 +719,10 @@ lynx_request_interrupt (void) kill (lynx_ptid_get_pid (inferior_ptid), SIGINT); } +/* The LynxOS target ops object. */ + +static lynx_process_target the_lynx_target; + /* The LynxOS target_ops vector. */ static process_stratum_target lynx_target_ops = { @@ -765,6 +769,41 @@ static process_stratum_target lynx_target_ops = { NULL, /* supports_exec_events */ NULL, /* handle_new_gdb_connection */ NULL, /* handle_monitor_command */ + NULL, /* core_of_thread */ + NULL, /* read_loadmap */ + NULL, /* process_qsupported */ + NULL, /* supports_tracepoints */ + NULL, /* read_pc */ + NULL, /* write_pc */ + NULL, /* thread_stopped */ + NULL, /* get_tib_address */ + NULL, /* pause_all */ + NULL, /* unpause_all */ + NULL, /* stabilize_threads */ + NULL, /* install_fast_tracepoint_jump_pad */ + NULL, /* emit_ops */ + NULL, /* supports_disable_randomization */ + NULL, /* get_min_fast_tracepoint_insn_len */ + NULL, /* qxfer_libraries_svr4 */ + NULL, /* support_agent */ + NULL, /* enable_btrace */ + NULL, /* disable_btrace */ + NULL, /* read_btrace */ + NULL, /* read_btrace_conf */ + NULL, /* supports_range_stepping */ + NULL, /* pid_to_exec_file */ + NULL, /* multifs_open */ + NULL, /* multifs_unlink */ + NULL, /* multifs_readlink */ + NULL, /* breakpoint_kind_from_pc */ + NULL, /* sw_breakpoint_from_kind */ + NULL, /* thread_name */ + NULL, /* breakpoint_kind_from_current_state */ + NULL, /* supports_software_single_step */ + NULL, /* supports_catch_syscall */ + NULL, /* get_ipa_tdesc_idx */ + NULL, /* thread_handle */ + &the_lynx_target, }; void diff --git a/gdbserver/lynx-low.h b/gdbserver/lynx-low.h index b122298fb88..ca9601b221b 100644 --- a/gdbserver/lynx-low.h +++ b/gdbserver/lynx-low.h @@ -52,6 +52,13 @@ struct lynx_target_ops extern struct lynx_target_ops the_low_target; +/* Target ops definitions for a LynxOS target. */ + +class lynx_process_target : public process_target { +public: + +}; + /* The inferior's target description. This is a global because the LynxOS ports support neither bi-arch nor multi-process. */ extern const struct target_desc *lynx_tdesc; diff --git a/gdbserver/nto-low.c b/gdbserver/nto-low.c index b4dea479b9c..6f12a735c12 100644 --- a/gdbserver/nto-low.c +++ b/gdbserver/nto-low.c @@ -930,6 +930,9 @@ nto_sw_breakpoint_from_kind (int kind, int *size) return the_low_target.breakpoint; } +/* The QNX Neutrino target ops object. */ + +static nto_process_target the_nto_target; static process_stratum_target nto_target_ops = { nto_create_inferior, @@ -1003,6 +1006,13 @@ static process_stratum_target nto_target_ops = { NULL, /* multifs_readlink */ NULL, /* breakpoint_kind_from_pc */ nto_sw_breakpoint_from_kind, + NULL, /* thread_name */ + NULL, /* breakpoint_kind_from_current_state */ + NULL, /* supports_software_single_step */ + NULL, /* supports_catch_syscall */ + NULL, /* get_ipa_tdesc_idx */ + NULL, /* thread_handle */ + &the_nto_target, }; diff --git a/gdbserver/nto-low.h b/gdbserver/nto-low.h index 393b8a98695..398382113b6 100644 --- a/gdbserver/nto-low.h +++ b/gdbserver/nto-low.h @@ -42,6 +42,13 @@ struct nto_target_ops extern struct nto_target_ops the_low_target; +/* Target ops definitions for a QNX Neutrino target. */ + +class nto_process_target : public process_target { +public: + +}; + /* The inferior's target description. This is a global because the LynxOS ports support neither bi-arch nor multi-process. */ extern const struct target_desc *nto_tdesc; diff --git a/gdbserver/target.h b/gdbserver/target.h index 1b0810ba049..af3995425a3 100644 --- a/gdbserver/target.h +++ b/gdbserver/target.h @@ -63,6 +63,8 @@ struct thread_resume CORE_ADDR step_range_end; /* Exclusive */ }; +class process_target; + /* GDBserver doesn't have a concept of strata like GDB, but we call its target vector "process_stratum" anyway for the benefit of shared code. */ @@ -477,6 +479,15 @@ struct process_stratum_target false for failure. Return pointer to thread handle via HANDLE and the handle's length via HANDLE_LEN. */ bool (*thread_handle) (ptid_t ptid, gdb_byte **handle, int *handle_len); + + /* The object that will gradually replace this struct. */ + process_target *pt; +}; + +class process_target { +public: + + virtual ~process_target () = default; }; extern process_stratum_target *the_target; diff --git a/gdbserver/win32-low.c b/gdbserver/win32-low.c index 9d0343788f1..b0b54a10669 100644 --- a/gdbserver/win32-low.c +++ b/gdbserver/win32-low.c @@ -1823,6 +1823,10 @@ win32_sw_breakpoint_from_kind (int kind, int *size) return the_low_target.breakpoint; } +/* The win32 target ops object. */ + +static win32_process_target the_win32_target; + static process_stratum_target win32_target_ops = { win32_create_inferior, NULL, /* post_create_inferior */ @@ -1899,6 +1903,13 @@ static process_stratum_target win32_target_ops = { NULL, /* multifs_readlink */ NULL, /* breakpoint_kind_from_pc */ win32_sw_breakpoint_from_kind, + NULL, /* thread_name */ + NULL, /* breakpoint_kind_from_current_state */ + NULL, /* supports_software_single_step */ + NULL, /* supports_catch_syscall */ + NULL, /* get_ipa_tdesc_idx */ + NULL, /* thread_handle */ + &the_win32_target, }; /* Initialize the Win32 backend. */ diff --git a/gdbserver/win32-low.h b/gdbserver/win32-low.h index 7a3eeda6e24..f8cc0b27c7f 100644 --- a/gdbserver/win32-low.h +++ b/gdbserver/win32-low.h @@ -101,6 +101,13 @@ struct win32_target_ops extern struct win32_target_ops the_low_target; +/* Target ops definitions for a Win32 target. */ + +class win32_process_target : public process_target { +public: + +}; + /* Retrieve the context for this thread, if not already retrieved. */ extern void win32_require_context (win32_thread_info *th);