From patchwork Tue Dec 6 13:57:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 61551 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9C8D6384698E for ; Tue, 6 Dec 2022 13:58:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9C8D6384698E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1670335112; bh=o+nFVdy18KDv55GffZsDtke4GyqDjT5rUb+WosrLGUk=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=LV+TwDAJRlkS/4hMrLh+E4zAhjt66M42s5PyqCZe5ql5rg+/Hmwhm/cVT9xekYFC7 ZCQE4cf1CVUvrTTh6gssXScSu1/4gc3DdEvD8KHkfMQ3e+5Xg0jTTVZT8dExc5J+Bi yENp8eqVsyC/5yQDURvyoRW/x/MDToSERti850YE= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id 102223864A39 for ; Tue, 6 Dec 2022 13:57:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 102223864A39 X-ASG-Debug-ID: 1670335052-0c856e762a1bac0001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id xgh41RbmzuQflF7y (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO); Tue, 06 Dec 2022 08:57:32 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@efficios.com X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from epycamd.internal.efficios.com (192-222-180-24.qc.cable.ebox.net [192.222.180.24]) by smtp.ebox.ca (Postfix) with ESMTP id 05B55441D65; Tue, 6 Dec 2022 08:57:32 -0500 (EST) X-Barracuda-RBL-IP: 192.222.180.24 X-Barracuda-Effective-Source-IP: 192-222-180-24.qc.cable.ebox.net[192.222.180.24] X-Barracuda-Apparent-Source-IP: 192.222.180.24 To: gdb-patches@sourceware.org Cc: Lancelot SIX , Simon Marchi Subject: [PATCH 01/12] gdb: add supports_arch_info callback to gdbarch_register Date: Tue, 6 Dec 2022 08:57:18 -0500 X-ASG-Orig-Subj: [PATCH 01/12] gdb: add supports_arch_info callback to gdbarch_register Message-Id: <20221206135729.3937767-2-simon.marchi@efficios.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221206135729.3937767-1-simon.marchi@efficios.com> References: <20221206135729.3937767-1-simon.marchi@efficios.com> MIME-Version: 1.0 X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1670335052 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 3230 X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=5.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.102644 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Spam-Status: No, score=-3498.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_SOFTFAIL, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" From: Lancelot SIX In the ROCm GDB port, there are some amdgcn architectures known by BFD that we don't actually support in GDB. We don't want gdbarch_printable_names to return these architectures. gdbarch_printable_names is used for a few things: - completion of the "set architecture" command - the gdb.architecture_names function in Python - foreach-arch selftests Add an optional callback to gdbarch_register that is a predicate indicating whether the gdbarch supports the given bfd_arch_info. by default, it is nullptr, meaning that the gdbarch accepts all "mach"s for that architecture known by BFD. Change-Id: I712f94351b0b34ed1f42e5cf7fc7ba051315d860 Co-Authored-By: Simon Marchi --- gdb/arch-utils.c | 9 +++++++-- gdb/gdbarch.h | 4 +++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index 60ffdc5e16a..dbe78647d5e 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -1211,6 +1211,7 @@ struct gdbarch_registration enum bfd_architecture bfd_architecture; gdbarch_init_ftype *init; gdbarch_dump_tdep_ftype *dump_tdep; + gdbarch_supports_arch_info_ftype *supports_arch_info; struct gdbarch_list *arches; struct gdbarch_registration *next; }; @@ -1234,7 +1235,9 @@ gdbarch_printable_names () internal_error (_("gdbarch_architecture_names: multi-arch unknown")); do { - arches.push_back (ap->printable_name); + if (rego->supports_arch_info == nullptr + || rego->supports_arch_info (ap)) + arches.push_back (ap->printable_name); ap = ap->next; } while (ap != NULL); @@ -1247,7 +1250,8 @@ gdbarch_printable_names () void gdbarch_register (enum bfd_architecture bfd_architecture, gdbarch_init_ftype *init, - gdbarch_dump_tdep_ftype *dump_tdep) + gdbarch_dump_tdep_ftype *dump_tdep, + gdbarch_supports_arch_info_ftype *supports_arch_info) { struct gdbarch_registration **curr; const struct bfd_arch_info *bfd_arch_info; @@ -1280,6 +1284,7 @@ gdbarch_register (enum bfd_architecture bfd_architecture, (*curr)->bfd_architecture = bfd_architecture; (*curr)->init = init; (*curr)->dump_tdep = dump_tdep; + (*curr)->supports_arch_info = supports_arch_info; (*curr)->arches = NULL; (*curr)->next = NULL; } diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index f2ba5f97765..aea6c4335d9 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -268,10 +268,12 @@ struct gdbarch_info typedef struct gdbarch *(gdbarch_init_ftype) (struct gdbarch_info info, struct gdbarch_list *arches); typedef void (gdbarch_dump_tdep_ftype) (struct gdbarch *gdbarch, struct ui_file *file); +typedef bool (gdbarch_supports_arch_info_ftype) (const struct bfd_arch_info *); extern void gdbarch_register (enum bfd_architecture architecture, gdbarch_init_ftype *init, - gdbarch_dump_tdep_ftype *dump_tdep = nullptr); + gdbarch_dump_tdep_ftype *dump_tdep = nullptr, + gdbarch_supports_arch_info_ftype *supports_arch_info = nullptr); /* Return a vector of the valid architecture names. Since architectures are From patchwork Tue Dec 6 13:57:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 61550 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E7303384C905 for ; Tue, 6 Dec 2022 13:57:59 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E7303384C905 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1670335079; bh=6N5VpZlw249QIlNyllyhQUf9Z4aRRsS5AR0MeP6jR0Q=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=YoHSZxTqKC7imAbYu0N3WtFwvRcS75M8Dp8vox49qkSSwq2R7e0Fj8p1PzXBp88E1 ebF/u2Oz0vNuKOpND6O5SgEpXESX6B6X7yiYDYKF9NKxBRRVEVrnmZZmtV2sO6OaA/ Ob25cJeqaOutYhXpUoaHA5SK4LeHlEzIPc4ZSH+M= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id 9FBA93864A30 for ; Tue, 6 Dec 2022 13:57:33 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 9FBA93864A30 X-ASG-Debug-ID: 1670335052-0c856e762b1baf0001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id CfZ0J6cD5ZIsQUo8 (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO); Tue, 06 Dec 2022 08:57:32 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@efficios.com X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from epycamd.internal.efficios.com (192-222-180-24.qc.cable.ebox.net [192.222.180.24]) by smtp.ebox.ca (Postfix) with ESMTP id 2190C441D64; Tue, 6 Dec 2022 08:57:32 -0500 (EST) X-Barracuda-RBL-IP: 192.222.180.24 X-Barracuda-Effective-Source-IP: 192-222-180-24.qc.cable.ebox.net[192.222.180.24] X-Barracuda-Apparent-Source-IP: 192.222.180.24 To: gdb-patches@sourceware.org Cc: Pedro Alves , Simon Marchi Subject: [PATCH 02/12] gdb: make install_breakpoint return a non-owning reference Date: Tue, 6 Dec 2022 08:57:19 -0500 X-ASG-Orig-Subj: [PATCH 02/12] gdb: make install_breakpoint return a non-owning reference Message-Id: <20221206135729.3937767-3-simon.marchi@efficios.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221206135729.3937767-1-simon.marchi@efficios.com> References: <20221206135729.3937767-1-simon.marchi@efficios.com> MIME-Version: 1.0 X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1670335052 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 2032 X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=5.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.102644 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Spam-Status: No, score=-3498.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_SOFTFAIL, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" From: Pedro Alves A following patch will want to install a breakpoint and then keep a non-owning reference to it. Make install_breakpoint return a non-owning reference, to make that easy. Co-Authored-By: Simon Marchi Change-Id: I2e8106a784021ff276ce251e24708cbdccc2d479 --- gdb/breakpoint.c | 4 +++- gdb/breakpoint.h | 8 +++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index f0276a963c0..f974808b4b4 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -7954,7 +7954,7 @@ catchpoint::catchpoint (struct gdbarch *gdbarch, bool temp, pspace = current_program_space; } -void +breakpoint * install_breakpoint (int internal, std::unique_ptr &&arg, int update_gll) { breakpoint *b = add_to_breakpoint_chain (std::move (arg)); @@ -7967,6 +7967,8 @@ install_breakpoint (int internal, std::unique_ptr &&arg, int update_ if (update_gll) update_global_location_list (UGLL_MAY_INSERT); + + return b; } static int diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index f7633d29cbf..eafe694f367 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -1479,10 +1479,12 @@ extern void target and breakpoint_created observers of its existence. If INTERNAL is non-zero, the breakpoint number will be allocated from the internal breakpoint count. If UPDATE_GLL is non-zero, - update_global_location_list will be called. */ + update_global_location_list will be called. -extern void install_breakpoint (int internal, std::unique_ptr &&b, - int update_gll); + Takes ownership of B, and returns a non-owning reference to it. */ + +extern breakpoint *install_breakpoint + (int internal, std::unique_ptr &&b, int update_gll); /* Returns the breakpoint ops appropriate for use with with LOCSPEC and according to IS_TRACEPOINT. Use this to ensure, for example, From patchwork Tue Dec 6 13:57:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 61553 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E9685383FD54 for ; Tue, 6 Dec 2022 13:59:02 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E9685383FD54 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1670335142; bh=d1wteO8K83b7lrIf+lumjMcchCNjUbBUYBOeRaQlpXg=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=OvvP3rG+z6OP+jaaIsg5QmG11lkY5e+5tAn4nWPkSd2GCL0OfvmypsOZgLgXdQknr VHGo8D9tspck4p+7195adZZ520ypXF/1BY7gSn1TKoN+8GsukRP/1fWy3hBd+KGLTk WQ8vSKrdmf5ngmkHyhx6A/+Z6wtvNMxh0pmyuEgw= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id 1807A3864A2F for ; Tue, 6 Dec 2022 13:57:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1807A3864A2F X-ASG-Debug-ID: 1670335052-0c856e762a1bad0001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id RMMUA10xZLDmXlVj (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO); Tue, 06 Dec 2022 08:57:32 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@efficios.com X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from epycamd.internal.efficios.com (192-222-180-24.qc.cable.ebox.net [192.222.180.24]) by smtp.ebox.ca (Postfix) with ESMTP id 3F76C441D65; Tue, 6 Dec 2022 08:57:32 -0500 (EST) X-Barracuda-RBL-IP: 192.222.180.24 X-Barracuda-Effective-Source-IP: 192-222-180-24.qc.cable.ebox.net[192.222.180.24] X-Barracuda-Apparent-Source-IP: 192.222.180.24 To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 03/12] gdbsupport: add type definitions for pid, lwp and tid Date: Tue, 6 Dec 2022 08:57:20 -0500 X-ASG-Orig-Subj: [PATCH 03/12] gdbsupport: add type definitions for pid, lwp and tid Message-Id: <20221206135729.3937767-4-simon.marchi@efficios.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221206135729.3937767-1-simon.marchi@efficios.com> References: <20221206135729.3937767-1-simon.marchi@efficios.com> MIME-Version: 1.0 X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1670335052 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 2481 X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=5.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.102644 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Spam-Status: No, score=-3498.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_SOFTFAIL, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" A following patch will want to declare variables of the same time as some ptid_t components. To make that easy (and avoid harcoding those types everywhere), define some type definitions in the ptid_t struct for each of them. Use them throughout ptid.h. I initially used pid_t, lwp_t and tid_t, but there is the risk of some system defining the pid_t type using a macro instead of a typedef, which would break things. So, use the _type suffix instead. Change-Id: I820b0bea9dafcb4914f1c9ba4bb96b5c666c8dec --- gdbsupport/ptid.h | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/gdbsupport/ptid.h b/gdbsupport/ptid.h index d66cd988459..6dcab984b99 100644 --- a/gdbsupport/ptid.h +++ b/gdbsupport/ptid.h @@ -39,6 +39,10 @@ class ptid_t { public: + using pid_type = int; + using lwp_type = long; + using tid_type = ULONGEST; + /* Must have a trivial defaulted default constructor so that the type remains POD. */ ptid_t () noexcept = default; @@ -48,13 +52,13 @@ class ptid_t A ptid with only a PID (LWP and TID equal to zero) is usually used to represent a whole process, including all its lwps/threads. */ - explicit constexpr ptid_t (int pid, long lwp = 0, ULONGEST tid = 0) + explicit constexpr ptid_t (pid_type pid, lwp_type lwp = 0, tid_type tid = 0) : m_pid (pid), m_lwp (lwp), m_tid (tid) {} /* Fetch the pid (process id) component from the ptid. */ - constexpr int pid () const + constexpr pid_type pid () const { return m_pid; } /* Return true if the ptid's lwp member is non-zero. */ @@ -64,7 +68,7 @@ class ptid_t /* Fetch the lwp (lightweight process) component from the ptid. */ - constexpr long lwp () const + constexpr lwp_type lwp () const { return m_lwp; } /* Return true if the ptid's tid member is non-zero. */ @@ -74,7 +78,7 @@ class ptid_t /* Fetch the tid (thread id) component from a ptid. */ - constexpr ULONGEST tid () const + constexpr tid_type tid () const { return m_tid; } /* Return true if the ptid represents a whole process, including all its @@ -144,13 +148,13 @@ class ptid_t private: /* Process id. */ - int m_pid; + pid_type m_pid; /* Lightweight process id. */ - long m_lwp; + lwp_type m_lwp; /* Thread id. */ - ULONGEST m_tid; + tid_type m_tid; }; /* Functor to hash a ptid. */ From patchwork Tue Dec 6 13:57:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 61556 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4CE44384698D for ; Tue, 6 Dec 2022 13:59:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4CE44384698D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1670335173; bh=FQDYcnZjFDDZjTb7O633Md1TssdurUEvo7lOK8AVXnM=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=DwRqdMP5ZXYcZSgwpsz8EKWmMyp/DouiSZ2OIh6EAzBR5QnQSGZQhrxKfElATE/iS r/yH+8JvtMgmlzQgHcDy1bbeQr5bwX8wFzubwlSfdBQU4DSmlgDz/mNABs83brLWgF NS+hgecHMbWRi64xGTHI/j/8C0XUnVQkfDPKcJVc= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id 5C6963864A32 for ; Tue, 6 Dec 2022 13:57:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5C6963864A32 X-ASG-Debug-ID: 1670335052-0c856e762b1bb00001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id ZheY87fI9JjM5O81 (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO); Tue, 06 Dec 2022 08:57:32 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@efficios.com X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from epycamd.internal.efficios.com (192-222-180-24.qc.cable.ebox.net [192.222.180.24]) by smtp.ebox.ca (Postfix) with ESMTP id 56704441D64; Tue, 6 Dec 2022 08:57:32 -0500 (EST) X-Barracuda-RBL-IP: 192.222.180.24 X-Barracuda-Effective-Source-IP: 192-222-180-24.qc.cable.ebox.net[192.222.180.24] X-Barracuda-Apparent-Source-IP: 192.222.180.24 To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 04/12] gdb: add inferior_pre_detach observable Date: Tue, 6 Dec 2022 08:57:21 -0500 X-ASG-Orig-Subj: [PATCH 04/12] gdb: add inferior_pre_detach observable Message-Id: <20221206135729.3937767-5-simon.marchi@efficios.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221206135729.3937767-1-simon.marchi@efficios.com> References: <20221206135729.3937767-1-simon.marchi@efficios.com> MIME-Version: 1.0 X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1670335052 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 2102 X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=5.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.102644 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Spam-Status: No, score=-3498.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_SOFTFAIL, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" Add an observable notified in target_detach just before calling the detach method on the inferior's target stack. This allows observer to do some work on the inferior while it's still ptrace-attached, in the case of a native Linux inferior. Specifically, the amd-dbgapi target will need it in order to call amd_dbgapi_process_detach before the process gets ptrace-detached. Change-Id: I28b6065e251012a4c2db8a600fe13ba31671e3c9 --- gdb/observable.c | 1 + gdb/observable.h | 3 +++ gdb/target.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/gdb/observable.c b/gdb/observable.c index 0bc8697f137..7b23e038b25 100644 --- a/gdb/observable.c +++ b/gdb/observable.c @@ -62,6 +62,7 @@ DEFINE_OBSERVABLE (architecture_changed); DEFINE_OBSERVABLE (thread_ptid_changed); DEFINE_OBSERVABLE (inferior_added); DEFINE_OBSERVABLE (inferior_appeared); +DEFINE_OBSERVABLE (inferior_pre_detach); DEFINE_OBSERVABLE (inferior_exit); DEFINE_OBSERVABLE (inferior_removed); DEFINE_OBSERVABLE (memory_changed); diff --git a/gdb/observable.h b/gdb/observable.h index 1103c5c98a6..e8cc2d28a86 100644 --- a/gdb/observable.h +++ b/gdb/observable.h @@ -181,6 +181,9 @@ extern observable inferior_added; process. */ extern observable inferior_appeared; +/* Inferior INF is about to be detached. */ +extern observable inferior_pre_detach; + /* Either the inferior associated with INF has been detached from the process, or the process has exited. */ extern observable inferior_exit; diff --git a/gdb/target.c b/gdb/target.c index 1dd0f42af7d..04a4e1fd877 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -2561,6 +2561,8 @@ target_detach (inferior *inf, int from_tty) prepare_for_detach (); + gdb::observers::inferior_pre_detach.notify (inf); + /* Hold a strong reference because detaching may unpush the target. */ auto proc_target_ref = target_ops_ref::new_reference (inf->process_target ()); From patchwork Tue Dec 6 13:57:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 61552 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0147D384230B for ; Tue, 6 Dec 2022 13:58:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0147D384230B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1670335118; bh=TEJL7ILYPqm/MfZU/Nk8IyNYmfz6ydZwigpcgGIKajc=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=Pv2v+mfPGxEJwYh1xHHbs2/8k7njSGiiP6jke0noLaj8B4PdKSSckcNxOZPifHCHM OmL3VIiq/iNEHLLtAZzdDd35+2r6qfE9ZCZMILhp5YujZ+Dlr0rXFElCiay2Ww5QoD RLn3hsaargqdPNZ3jJc7oHQZjCqNGFESIgzOEtCY= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id 2A63A384C901 for ; Tue, 6 Dec 2022 13:57:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2A63A384C901 X-ASG-Debug-ID: 1670335052-0c856e762a1bae0001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id VSyAPIzSrKDUCIZH (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO); Tue, 06 Dec 2022 08:57:32 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@efficios.com X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from epycamd.internal.efficios.com (192-222-180-24.qc.cable.ebox.net [192.222.180.24]) by smtp.ebox.ca (Postfix) with ESMTP id 71485441D65; Tue, 6 Dec 2022 08:57:32 -0500 (EST) X-Barracuda-RBL-IP: 192.222.180.24 X-Barracuda-Effective-Source-IP: 192-222-180-24.qc.cable.ebox.net[192.222.180.24] X-Barracuda-Apparent-Source-IP: 192.222.180.24 To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 05/12] gdb: make gdbarch_alloc take ownership of the tdep Date: Tue, 6 Dec 2022 08:57:22 -0500 X-ASG-Orig-Subj: [PATCH 05/12] gdb: make gdbarch_alloc take ownership of the tdep Message-Id: <20221206135729.3937767-6-simon.marchi@efficios.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221206135729.3937767-1-simon.marchi@efficios.com> References: <20221206135729.3937767-1-simon.marchi@efficios.com> MIME-Version: 1.0 X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1670335052 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 47011 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=5.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.102644 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Spam-Status: No, score=-3498.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_SOFTFAIL, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" From: Simon Marchi It's currently not clear how the ownership of gdbarch_tdep objects works. In fact, nothing ever takes ownership of it. This is mostly fine because we never free gdbarch objects, and thus we never free gdbarch_tdep objects. There is an exception to that however: when initialization fails, we do free the gdbarch object that is not going to be used, and we free the tdep too. Currently, i386 and s390 do it. To make things clearer, change gdbarch_alloc so that it takes ownership of the tdep. The tdep is thus automatically freed if the gdbarch is freed. Change all gdbarch initialization functions to pass a new gdbarch_tdep object to gdbarch_alloc and then retrieve a non-owning reference from the gdbarch object. Before this patch, the xtensa architecture had a single global instance of xtensa_gdbarch_tdep. Since we need to pass a dynamically allocated gdbarch_tdep_base instance to gdbarch_alloc, remove this global instance, and dynamically allocate one as needed, like we do for all other architectures. Make the `rmap` array externally visible and rename it to the less collision-prone `xtensa_rmap` name. Change-Id: Id3d70493ef80ce4bdff701c57636f4c79ed8aea2 --- gdb/aarch64-tdep.c | 5 +++-- gdb/alpha-tdep.c | 7 +++---- gdb/arc-tdep.c | 6 +++--- gdb/arch-utils.c | 2 +- gdb/arm-tdep.c | 6 +++--- gdb/avr-tdep.c | 6 +++--- gdb/bfin-tdep.c | 6 +++--- gdb/bpf-tdep.c | 4 ++-- gdb/cris-tdep.c | 6 +++--- gdb/csky-tdep.c | 7 ++++--- gdb/frv-tdep.c | 15 ++++++++------- gdb/ft32-tdep.c | 6 +++--- gdb/gdbarch.c | 6 +++--- gdb/gdbarch.h | 5 ++++- gdb/hppa-tdep.c | 7 +++---- gdb/i386-tdep.c | 7 +++---- gdb/ia64-tdep.c | 7 +++---- gdb/lm32-tdep.c | 6 ++---- gdb/loongarch-tdep.c | 6 ++++-- gdb/m32c-tdep.c | 5 ++--- gdb/m32r-tdep.c | 6 ++---- gdb/m68hc11-tdep.c | 7 ++++--- gdb/m68k-tdep.c | 7 ++++--- gdb/mep-tdep.c | 7 +++---- gdb/microblaze-tdep.c | 5 ++--- gdb/mips-tdep.c | 7 ++++--- gdb/mn10300-tdep.c | 6 +++--- gdb/moxie-tdep.c | 6 ++---- gdb/msp430-tdep.c | 7 ++++--- gdb/nds32-tdep.c | 8 ++++---- gdb/nios2-tdep.c | 6 +++--- gdb/or1k-tdep.c | 7 ++++--- gdb/riscv-tdep.c | 7 ++++--- gdb/rl78-tdep.c | 7 ++++--- gdb/rs6000-tdep.c | 8 ++++---- gdb/rx-tdep.c | 7 ++++--- gdb/s12z-tdep.c | 4 ++-- gdb/s390-tdep.c | 13 +++++-------- gdb/s390-tdep.h | 2 ++ gdb/sh-tdep.c | 6 ++---- gdb/sparc-tdep.c | 6 +++--- gdb/tic6x-tdep.c | 6 +++--- gdb/v850-tdep.c | 7 ++++--- gdb/xtensa-config.c | 4 +--- gdb/xtensa-tdep.c | 10 +++++----- gdb/z80-tdep.c | 6 +++--- 46 files changed, 148 insertions(+), 149 deletions(-) diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index cf20bb40b78..e59fcf726ae 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -3664,8 +3664,9 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* AArch64 code is always little-endian. */ info.byte_order_for_code = BFD_ENDIAN_LITTLE; - aarch64_gdbarch_tdep *tdep = new aarch64_gdbarch_tdep; - struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new aarch64_gdbarch_tdep)); + aarch64_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); /* This should be low enough for everything. */ tdep->lowest_pc = 0x20; diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c index 99e51b8afec..2691c9d0055 100644 --- a/gdb/alpha-tdep.c +++ b/gdb/alpha-tdep.c @@ -1719,15 +1719,14 @@ alpha_software_single_step (struct regcache *regcache) static struct gdbarch * alpha_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; - /* Find a candidate among extant architectures. */ arches = gdbarch_list_lookup_by_info (arches, &info); if (arches != NULL) return arches->gdbarch; - alpha_gdbarch_tdep *tdep = new alpha_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new alpha_gdbarch_tdep)); + alpha_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); /* Lowest text address. This is used by heuristic_proc_start() to decide when to stop looking. */ diff --git a/gdb/arc-tdep.c b/gdb/arc-tdep.c index 3ab0930bb29..a8c7bdab533 100644 --- a/gdb/arc-tdep.c +++ b/gdb/arc-tdep.c @@ -2256,11 +2256,11 @@ arc_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Allocate the ARC-private target-dependent information structure, and the GDB target-independent information structure. */ - std::unique_ptr tdep_holder (new arc_gdbarch_tdep); - arc_gdbarch_tdep *tdep = tdep_holder.get (); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new arc_gdbarch_tdep)); + arc_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); tdep->jb_pc = -1; /* No longjmp support by default. */ tdep->has_hw_loops = arc_check_for_hw_loops (tdesc, tdesc_data.get ()); - struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep_holder.release ()); /* Data types. */ set_gdbarch_short_bit (gdbarch, 16); diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index dbe78647d5e..6afad9ef445 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -1195,7 +1195,7 @@ gdbarch_tdep_1 (struct gdbarch *gdbarch) { if (gdbarch_debug >= 2) gdb_printf (gdb_stdlog, "gdbarch_tdep_1 called\n"); - return gdbarch->tdep; + return gdbarch->tdep.get (); } registry * diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 6f02f04b5cb..4ce8f08d908 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -9990,7 +9990,6 @@ arm_get_pc_address_flags (frame_info_ptr frame, CORE_ADDR pc) static struct gdbarch * arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; struct gdbarch_list *best_arch; enum arm_abi_kind arm_abi = arm_abi_global; enum arm_float_model fp_model = arm_fp_model; @@ -10534,8 +10533,9 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) if (best_arch != NULL) return best_arch->gdbarch; - arm_gdbarch_tdep *tdep = new arm_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new arm_gdbarch_tdep)); + arm_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); /* Record additional information about the architecture we are defining. These are gdbarch discriminators, like the OSABI. */ diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c index bac0b3f5008..80ab2750fa8 100644 --- a/gdb/avr-tdep.c +++ b/gdb/avr-tdep.c @@ -1426,7 +1426,6 @@ avr_address_class_name_to_type_flags (struct gdbarch *gdbarch, static struct gdbarch * avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; struct gdbarch_list *best_arch; int call_length; @@ -1466,8 +1465,9 @@ avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) } /* None found, create a new architecture from the information provided. */ - avr_gdbarch_tdep *tdep = new avr_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new avr_gdbarch_tdep)); + avr_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); tdep->call_length = call_length; diff --git a/gdb/bfin-tdep.c b/gdb/bfin-tdep.c index f751e278211..0f2b0021bdf 100644 --- a/gdb/bfin-tdep.c +++ b/gdb/bfin-tdep.c @@ -778,7 +778,6 @@ bfin_abi (struct gdbarch *gdbarch) static struct gdbarch * bfin_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; enum bfin_abi abi; abi = BFIN_ABI_FLAT; @@ -798,8 +797,9 @@ bfin_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) return arches->gdbarch; } - bfin_gdbarch_tdep *tdep = new bfin_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new bfin_gdbarch_tdep)); + bfin_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); tdep->bfin_abi = abi; diff --git a/gdb/bpf-tdep.c b/gdb/bpf-tdep.c index ea7c1147378..09d1545a4b8 100644 --- a/gdb/bpf-tdep.c +++ b/gdb/bpf-tdep.c @@ -321,8 +321,8 @@ bpf_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) return arches->gdbarch; /* Allocate space for the new architecture. */ - bpf_gdbarch_tdep *tdep = new bpf_gdbarch_tdep; - struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new bpf_gdbarch_tdep)); /* Information about registers, etc. */ set_gdbarch_num_regs (gdbarch, BPF_NUM_REGS); diff --git a/gdb/cris-tdep.c b/gdb/cris-tdep.c index d38850aa1af..55cef2606c2 100644 --- a/gdb/cris-tdep.c +++ b/gdb/cris-tdep.c @@ -3912,7 +3912,6 @@ set_cris_dwarf2_cfi (const char *ignore_args, int from_tty, static struct gdbarch * cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; unsigned int cris_version; if (usr_cmd_cris_version_valid) @@ -3948,9 +3947,10 @@ cris_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) } /* No matching architecture was found. Create a new one. */ - cris_gdbarch_tdep *tdep = new cris_gdbarch_tdep; info.byte_order = BFD_ENDIAN_LITTLE; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new cris_gdbarch_tdep)); + cris_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); tdep->cris_version = usr_cmd_cris_version; tdep->cris_mode = usr_cmd_cris_mode; diff --git a/gdb/csky-tdep.c b/gdb/csky-tdep.c index f293d204da2..5b3536f86fe 100644 --- a/gdb/csky-tdep.c +++ b/gdb/csky-tdep.c @@ -2671,7 +2671,6 @@ csky_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, static struct gdbarch * csky_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; /* Analyze info.abfd. */ unsigned int fpu_abi = 0; unsigned int vdsp_version = 0; @@ -2761,8 +2760,10 @@ csky_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* None found, create a new architecture from the information provided. */ - csky_gdbarch_tdep *tdep = new csky_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new csky_gdbarch_tdep)); + csky_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + tdep->fpu_abi = fpu_abi; tdep->vdsp_version = vdsp_version; tdep->fpu_hardfp = fpu_hardfp; diff --git a/gdb/frv-tdep.c b/gdb/frv-tdep.c index 056aad3f17e..eacfb6efb14 100644 --- a/gdb/frv-tdep.c +++ b/gdb/frv-tdep.c @@ -89,6 +89,8 @@ struct frv_gdbarch_tdep : gdbarch_tdep_base const char **register_names = nullptr; }; +using frv_gdbarch_tdep_up = std::unique_ptr; + /* Return the FR-V ABI associated with GDBARCH. */ enum frv_abi frv_abi (struct gdbarch *gdbarch) @@ -130,12 +132,12 @@ frv_fdpic_loadmap_addresses (struct gdbarch *gdbarch, CORE_ADDR *interp_addr, /* Allocate a new variant structure, and set up default values for all the fields. */ -static frv_gdbarch_tdep * -new_variant (void) +static frv_gdbarch_tdep_up +new_variant () { int r; - frv_gdbarch_tdep *var = new frv_gdbarch_tdep; + frv_gdbarch_tdep_up var (new frv_gdbarch_tdep); var->frv_abi = FRV_ABI_EABI; var->num_gprs = 64; @@ -1427,7 +1429,6 @@ static const struct frame_base frv_frame_base = { static struct gdbarch * frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; int elf_flags = 0; /* Check to see if we've already built an appropriate architecture @@ -1437,7 +1438,9 @@ frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) return arches->gdbarch; /* Select the right tdep structure for this variant. */ - frv_gdbarch_tdep *var = new_variant (); + gdbarch *gdbarch = gdbarch_alloc (&info, new_variant ()); + frv_gdbarch_tdep *var = gdbarch_tdep (gdbarch); + switch (info.bfd_arch_info->mach) { case bfd_mach_frv: @@ -1471,8 +1474,6 @@ frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) if (elf_flags & EF_FRV_CPU_FR450) set_variant_scratch_registers (var); - gdbarch = gdbarch_alloc (&info, var); - set_gdbarch_short_bit (gdbarch, 16); set_gdbarch_int_bit (gdbarch, 32); set_gdbarch_long_bit (gdbarch, 32); diff --git a/gdb/ft32-tdep.c b/gdb/ft32-tdep.c index 8da3dbae592..0be8a95f298 100644 --- a/gdb/ft32-tdep.c +++ b/gdb/ft32-tdep.c @@ -558,7 +558,6 @@ static const struct frame_base ft32_frame_base = static struct gdbarch * ft32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; struct type *void_type; struct type *func_void_type; @@ -568,8 +567,9 @@ ft32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) return arches->gdbarch; /* Allocate space for the new architecture. */ - ft32_gdbarch_tdep *tdep = new ft32_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new ft32_gdbarch_tdep)); + ft32_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); /* Create a type for PC. We can't use builtin types here, as they may not be defined. */ diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index 74c12c5e3ff..e4ca74eb44b 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -45,7 +45,7 @@ struct gdbarch const struct target_desc * target_desc; /* target specific vector. */ - struct gdbarch_tdep_base *tdep = nullptr; + gdbarch_tdep_up tdep; gdbarch_dump_tdep_ftype *dump_tdep = nullptr; /* per-architecture data-pointers. */ @@ -262,13 +262,13 @@ struct gdbarch struct gdbarch * gdbarch_alloc (const struct gdbarch_info *info, - struct gdbarch_tdep_base *tdep) + gdbarch_tdep_up tdep) { struct gdbarch *gdbarch; gdbarch = new struct gdbarch; - gdbarch->tdep = tdep; + gdbarch->tdep = std::move (tdep); gdbarch->bfd_arch_info = info->bfd_arch_info; gdbarch->byte_order = info->byte_order; diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index aea6c4335d9..196c7981450 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -69,6 +69,8 @@ struct gdbarch_tdep_base virtual ~gdbarch_tdep_base() = default; }; +using gdbarch_tdep_up = std::unique_ptr; + /* The architecture associated with the inferior through the connection to the target. @@ -294,7 +296,8 @@ extern struct gdbarch_list *gdbarch_list_lookup_by_info (struct gdbarch_list *ar parameters. set_gdbarch_*() functions are called to complete the initialization of the object. */ -extern struct gdbarch *gdbarch_alloc (const struct gdbarch_info *info, struct gdbarch_tdep_base *tdep); +extern struct gdbarch *gdbarch_alloc (const struct gdbarch_info *info, + gdbarch_tdep_up tdep); /* Helper function. Free a partially-constructed ``struct gdbarch''. diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c index fb4c4b42eab..da5f025d4d4 100644 --- a/gdb/hppa-tdep.c +++ b/gdb/hppa-tdep.c @@ -2982,16 +2982,15 @@ hppa_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc) static struct gdbarch * hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; - /* find a candidate among the list of pre-declared architectures. */ arches = gdbarch_list_lookup_by_info (arches, &info); if (arches != NULL) return (arches->gdbarch); /* If none found, then allocate and initialize one. */ - hppa_gdbarch_tdep *tdep = new hppa_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new hppa_gdbarch_tdep)); + hppa_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); /* Determine from the bfd_arch_info structure if we are dealing with a 32 or 64 bits architecture. If the bfd_arch_info is not available, diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index e027df2b9c5..ea7f5b3e2b7 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -8443,7 +8443,6 @@ i386_type_align (struct gdbarch *gdbarch, struct type *type) static struct gdbarch * i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; const struct target_desc *tdesc; int mm0_regnum; int ymm0_regnum; @@ -8456,8 +8455,9 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) return arches->gdbarch; /* Allocate space for the new architecture. Assume i386 for now. */ - i386_gdbarch_tdep *tdep = new i386_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new i386_gdbarch_tdep)); + i386_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); /* General-purpose registers. */ tdep->gregset_reg_offset = NULL; @@ -8700,7 +8700,6 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) if (!i386_validate_tdesc_p (tdep, tdesc_data.get ())) { - delete tdep; gdbarch_free (gdbarch); return NULL; } diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c index 519c956e169..35ae7ab8c46 100644 --- a/gdb/ia64-tdep.c +++ b/gdb/ia64-tdep.c @@ -3918,15 +3918,14 @@ ia64_size_of_register_frame (frame_info_ptr this_frame, ULONGEST cfm) static struct gdbarch * ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; - /* If there is already a candidate, use it. */ arches = gdbarch_list_lookup_by_info (arches, &info); if (arches != NULL) return arches->gdbarch; - ia64_gdbarch_tdep *tdep = new ia64_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new ia64_gdbarch_tdep)); + ia64_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); tdep->size_of_register_frame = ia64_size_of_register_frame; diff --git a/gdb/lm32-tdep.c b/gdb/lm32-tdep.c index dd601320c3a..f534b626ffb 100644 --- a/gdb/lm32-tdep.c +++ b/gdb/lm32-tdep.c @@ -479,16 +479,14 @@ lm32_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp) static struct gdbarch * lm32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; - /* If there is already a candidate, use it. */ arches = gdbarch_list_lookup_by_info (arches, &info); if (arches != NULL) return arches->gdbarch; /* None found, create a new architecture from the information provided. */ - lm32_gdbarch_tdep *tdep = new lm32_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new lm32_gdbarch_tdep)); /* Type sizes. */ set_gdbarch_short_bit (gdbarch, 16); diff --git a/gdb/loongarch-tdep.c b/gdb/loongarch-tdep.c index d727bc85062..62630c34434 100644 --- a/gdb/loongarch-tdep.c +++ b/gdb/loongarch-tdep.c @@ -1441,7 +1441,6 @@ loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) size_t regnum = 0; struct loongarch_gdbarch_features features; tdesc_arch_data_up tdesc_data = tdesc_data_alloc (); - loongarch_gdbarch_tdep *tdep = new loongarch_gdbarch_tdep; const struct target_desc *tdesc = info.target_desc; /* Ensure we always have a target description. */ @@ -1531,7 +1530,10 @@ loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) return arches->gdbarch; /* None found, so create a new architecture from the information provided. */ - struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new loongarch_gdbarch_tdep)); + loongarch_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + tdep->abi_features = abi_features; /* Target data types. */ diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c index f5101635aed..552eaccf440 100644 --- a/gdb/m32c-tdep.c +++ b/gdb/m32c-tdep.c @@ -2587,7 +2587,6 @@ m32c_virtual_frame_pointer (struct gdbarch *gdbarch, CORE_ADDR pc, static struct gdbarch * m32c_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; unsigned long mach = info.bfd_arch_info->mach; /* Find a candidate among the list of architectures we've created @@ -2597,8 +2596,8 @@ m32c_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) arches = gdbarch_list_lookup_by_info (arches->next, &info)) return arches->gdbarch; - m32c_gdbarch_tdep *tdep = new m32c_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new m32c_gdbarch_tdep)); /* Essential types. */ make_types (gdbarch); diff --git a/gdb/m32r-tdep.c b/gdb/m32r-tdep.c index fc304757a60..d9e19654a6a 100644 --- a/gdb/m32r-tdep.c +++ b/gdb/m32r-tdep.c @@ -861,16 +861,14 @@ static gdbarch_init_ftype m32r_gdbarch_init; static struct gdbarch * m32r_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; - /* If there is already a candidate, use it. */ arches = gdbarch_list_lookup_by_info (arches, &info); if (arches != NULL) return arches->gdbarch; /* Allocate space for the new architecture. */ - m32r_gdbarch_tdep *tdep = new m32r_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new m32r_gdbarch_tdep)); set_gdbarch_wchar_bit (gdbarch, 16); set_gdbarch_wchar_signed (gdbarch, 0); diff --git a/gdb/m68hc11-tdep.c b/gdb/m68hc11-tdep.c index c48fe4424b6..e59e6638042 100644 --- a/gdb/m68hc11-tdep.c +++ b/gdb/m68hc11-tdep.c @@ -1396,7 +1396,6 @@ static struct gdbarch * m68hc11_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; int elf_flags; soft_reg_initialized = 0; @@ -1423,8 +1422,10 @@ m68hc11_gdbarch_init (struct gdbarch_info info, } /* Need a new architecture. Fill in a target specific vector. */ - m68gc11_gdbarch_tdep *tdep = new m68gc11_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new m68gc11_gdbarch_tdep)); + m68gc11_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + tdep->elf_flags = elf_flags; switch (info.bfd_arch_info->arch) diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c index c0a33118814..4556c80ff6a 100644 --- a/gdb/m68k-tdep.c +++ b/gdb/m68k-tdep.c @@ -1131,7 +1131,6 @@ m68k_embedded_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) static struct gdbarch * m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; struct gdbarch_list *best_arch; tdesc_arch_data_up tdesc_data; int i; @@ -1248,8 +1247,10 @@ m68k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) if (best_arch != NULL) return best_arch->gdbarch; - m68k_gdbarch_tdep *tdep = new m68k_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new m68k_gdbarch_tdep)); + m68k_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + tdep->fpregs_present = has_fp; tdep->float_return = float_return; tdep->flavour = flavour; diff --git a/gdb/mep-tdep.c b/gdb/mep-tdep.c index a6416085fe4..8b2d83b0c42 100644 --- a/gdb/mep-tdep.c +++ b/gdb/mep-tdep.c @@ -2331,8 +2331,6 @@ mep_push_dummy_call (struct gdbarch *gdbarch, struct value *function, static struct gdbarch * mep_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; - /* Which me_module are we building a gdbarch object for? */ CONFIG_ATTR me_module; @@ -2397,8 +2395,9 @@ mep_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) return arches->gdbarch; } - mep_gdbarch_tdep *tdep = new mep_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new mep_gdbarch_tdep)); + mep_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); /* Get a CGEN CPU descriptor for this architecture. */ { diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c index efa1daaa7fc..6c7f5fe71a3 100644 --- a/gdb/microblaze-tdep.c +++ b/gdb/microblaze-tdep.c @@ -637,7 +637,6 @@ microblaze_register_g_packet_guesses (struct gdbarch *gdbarch) static struct gdbarch * microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; tdesc_arch_data_up tdesc_data; const struct target_desc *tdesc = info.target_desc; @@ -683,8 +682,8 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) } /* Allocate space for the new architecture. */ - microblaze_gdbarch_tdep *tdep = new microblaze_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new microblaze_gdbarch_tdep)); set_gdbarch_long_double_bit (gdbarch, 128); diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 8c1643585f4..e9432eb760f 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -8075,7 +8075,6 @@ value_of_mips_user_reg (frame_info_ptr frame, const void *baton) static struct gdbarch * mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; int elf_flags; enum mips_abi mips_abi, found_abi, wanted_abi; int i, num_regs; @@ -8475,8 +8474,10 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) } /* Need a new architecture. Fill in a target specific vector. */ - mips_gdbarch_tdep *tdep = new mips_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new mips_gdbarch_tdep)); + mips_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + tdep->elf_flags = elf_flags; tdep->mips64_transfers_32bit_regs_p = mips64_transfers_32bit_regs_p; tdep->found_abi = found_abi; diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c index 815949c67ae..b85845ded12 100644 --- a/gdb/mn10300-tdep.c +++ b/gdb/mn10300-tdep.c @@ -1332,15 +1332,15 @@ static struct gdbarch * mn10300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; int num_regs; arches = gdbarch_list_lookup_by_info (arches, &info); if (arches != NULL) return arches->gdbarch; - mn10300_gdbarch_tdep *tdep = new mn10300_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new mn10300_gdbarch_tdep)); + mn10300_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); switch (info.bfd_arch_info->mach) { diff --git a/gdb/moxie-tdep.c b/gdb/moxie-tdep.c index f1841e4e57e..cd8d7d648bc 100644 --- a/gdb/moxie-tdep.c +++ b/gdb/moxie-tdep.c @@ -1049,16 +1049,14 @@ moxie_process_record (struct gdbarch *gdbarch, struct regcache *regcache, static struct gdbarch * moxie_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; - /* If there is already a candidate, use it. */ arches = gdbarch_list_lookup_by_info (arches, &info); if (arches != NULL) return arches->gdbarch; /* Allocate space for the new architecture. */ - moxie_gdbarch_tdep *tdep = new moxie_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new moxie_gdbarch_tdep)); set_gdbarch_wchar_bit (gdbarch, 32); set_gdbarch_wchar_signed (gdbarch, 0); diff --git a/gdb/msp430-tdep.c b/gdb/msp430-tdep.c index 54554247230..5efb081a450 100644 --- a/gdb/msp430-tdep.c +++ b/gdb/msp430-tdep.c @@ -835,7 +835,6 @@ msp430_skip_trampoline_code (frame_info_ptr frame, CORE_ADDR pc) static struct gdbarch * msp430_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; int elf_flags, isa, code_model; /* Extract the elf_flags if available. */ @@ -917,8 +916,10 @@ msp430_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* None found, create a new architecture from the information provided. */ - msp430_gdbarch_tdep *tdep = new msp430_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new msp430_gdbarch_tdep)); + msp430_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + tdep->elf_flags = elf_flags; tdep->isa = isa; tdep->code_model = code_model; diff --git a/gdb/nds32-tdep.c b/gdb/nds32-tdep.c index 4ab91e67f06..0ace593831f 100644 --- a/gdb/nds32-tdep.c +++ b/gdb/nds32-tdep.c @@ -1940,7 +1940,6 @@ nds32_validate_tdesc_p (const struct target_desc *tdesc, static struct gdbarch * nds32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; struct gdbarch_list *best_arch; tdesc_arch_data_up tdesc_data; const struct target_desc *tdesc = info.target_desc; @@ -1981,14 +1980,15 @@ nds32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) return NULL; /* Allocate space for the new architecture. */ - nds32_gdbarch_tdep *tdep = new nds32_gdbarch_tdep; + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new nds32_gdbarch_tdep)); + nds32_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + tdep->fpu_freg = fpu_freg; tdep->use_pseudo_fsrs = use_pseudo_fsrs; tdep->fs0_regnum = -1; tdep->elf_abi = elf_abi; - gdbarch = gdbarch_alloc (&info, tdep); - set_gdbarch_wchar_bit (gdbarch, 16); set_gdbarch_wchar_signed (gdbarch, 0); diff --git a/gdb/nios2-tdep.c b/gdb/nios2-tdep.c index effa10bf97e..4c8e86165da 100644 --- a/gdb/nios2-tdep.c +++ b/gdb/nios2-tdep.c @@ -2274,7 +2274,6 @@ nios2_gcc_target_options (struct gdbarch *gdbarch) static struct gdbarch * nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; int i; tdesc_arch_data_up tdesc_data; const struct target_desc *tdesc = info.target_desc; @@ -2312,8 +2311,9 @@ nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* None found, create a new architecture from the information provided. */ - nios2_gdbarch_tdep *tdep = new nios2_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new nios2_gdbarch_tdep)); + nios2_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); /* longjmp support not enabled by default. */ tdep->jb_pc = -1; diff --git a/gdb/or1k-tdep.c b/gdb/or1k-tdep.c index efaf8745482..5394e7c2211 100644 --- a/gdb/or1k-tdep.c +++ b/gdb/or1k-tdep.c @@ -1142,7 +1142,6 @@ static const struct frame_unwind or1k_frame_unwind = { static struct gdbarch * or1k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; const struct bfd_arch_info *binfo; tdesc_arch_data_up tdesc_data; const struct target_desc *tdesc = info.target_desc; @@ -1157,10 +1156,12 @@ or1k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) actually know which target we are talking to, but put in some defaults for now. */ binfo = info.bfd_arch_info; - or1k_gdbarch_tdep *tdep = new or1k_gdbarch_tdep; + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new or1k_gdbarch_tdep)); + or1k_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + tdep->bytes_per_word = binfo->bits_per_word / binfo->bits_per_byte; tdep->bytes_per_address = binfo->bits_per_address / binfo->bits_per_byte; - gdbarch = gdbarch_alloc (&info, tdep); /* Target data types */ set_gdbarch_short_bit (gdbarch, 16); diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c index 0a050b272ff..d5133493b63 100644 --- a/gdb/riscv-tdep.c +++ b/gdb/riscv-tdep.c @@ -3783,7 +3783,6 @@ static struct gdbarch * riscv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; struct riscv_gdbarch_features features; const struct target_desc *tdesc = info.target_desc; @@ -3869,8 +3868,10 @@ riscv_gdbarch_init (struct gdbarch_info info, return arches->gdbarch; /* None found, so create a new architecture from the information provided. */ - riscv_gdbarch_tdep *tdep = new riscv_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new riscv_gdbarch_tdep)); + riscv_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + tdep->isa_features = features; tdep->abi_features = abi_features; diff --git a/gdb/rl78-tdep.c b/gdb/rl78-tdep.c index 206b9e2794f..edabc7d8602 100644 --- a/gdb/rl78-tdep.c +++ b/gdb/rl78-tdep.c @@ -1375,7 +1375,6 @@ rl78_push_dummy_call (struct gdbarch *gdbarch, struct value *function, static struct gdbarch * rl78_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; int elf_flags; /* Extract the elf_flags if available. */ @@ -1403,8 +1402,10 @@ rl78_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* None found, create a new architecture from the information provided. */ - rl78_gdbarch_tdep * tdep = new rl78_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new rl78_gdbarch_tdep)); + rl78_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + tdep->elf_flags = elf_flags; /* Initialize types. */ diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index cbd84514795..52e4a5a7dd9 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -7471,7 +7471,6 @@ rs6000_program_breakpoint_here_p (gdbarch *gdbarch, CORE_ADDR address) static struct gdbarch * rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; int wordsize, from_xcoff_exec, from_elf_exec; enum bfd_architecture arch; unsigned long mach; @@ -8179,15 +8178,16 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) - "set arch" trust blindly - GDB startup useless but harmless */ - ppc_gdbarch_tdep *tdep = new ppc_gdbarch_tdep; + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new ppc_gdbarch_tdep)); + ppc_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + tdep->wordsize = wordsize; tdep->elf_abi = elf_abi; tdep->soft_float = soft_float; tdep->long_double_abi = long_double_abi; tdep->vector_abi = vector_abi; - gdbarch = gdbarch_alloc (&info, tdep); - tdep->ppc_gp0_regnum = PPC_R0_REGNUM; tdep->ppc_toc_regnum = PPC_R0_REGNUM + 2; tdep->ppc_ps_regnum = PPC_MSR_REGNUM; diff --git a/gdb/rx-tdep.c b/gdb/rx-tdep.c index d1c294b9ef0..c588be1f4d7 100644 --- a/gdb/rx-tdep.c +++ b/gdb/rx-tdep.c @@ -944,7 +944,6 @@ rx_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) static struct gdbarch * rx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; int elf_flags; tdesc_arch_data_up tdesc_data; const struct target_desc *tdesc = info.target_desc; @@ -997,8 +996,10 @@ rx_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) gdb_assert(tdesc_data != NULL); - rx_gdbarch_tdep *tdep = new rx_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new rx_gdbarch_tdep)); + rx_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + tdep->elf_flags = elf_flags; set_gdbarch_num_regs (gdbarch, RX_NUM_REGS); diff --git a/gdb/s12z-tdep.c b/gdb/s12z-tdep.c index ccc47c99804..79b33f2f8a4 100644 --- a/gdb/s12z-tdep.c +++ b/gdb/s12z-tdep.c @@ -616,8 +616,8 @@ show_bdccsr_command (const char *args, int from_tty) static struct gdbarch * s12z_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - s12z_gdbarch_tdep *tdep = new s12z_gdbarch_tdep; - struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new s12z_gdbarch_tdep)); add_cmd ("bdccsr", class_support, show_bdccsr_command, _("Show the current value of the microcontroller's BDCCSR."), diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c index d0dba7654bb..83b8869a87e 100644 --- a/gdb/s390-tdep.c +++ b/gdb/s390-tdep.c @@ -6983,13 +6983,12 @@ s390_tdesc_valid (s390_gdbarch_tdep *tdep, return true; } -/* Allocate and initialize new gdbarch_tdep. Caller is responsible to free - memory after use. */ +/* Allocate and initialize new gdbarch_tdep. */ -static s390_gdbarch_tdep * +static s390_gdbarch_tdep_up s390_gdbarch_tdep_alloc () { - s390_gdbarch_tdep *tdep = new s390_gdbarch_tdep; + s390_gdbarch_tdep_up tdep (new s390_gdbarch_tdep); tdep->tdesc = NULL; @@ -7026,8 +7025,8 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) static const char *const stap_register_indirection_suffixes[] = { ")", NULL }; - s390_gdbarch_tdep *tdep = s390_gdbarch_tdep_alloc (); - struct gdbarch *gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch = gdbarch_alloc (&info, s390_gdbarch_tdep_alloc ()); + s390_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); tdesc_arch_data_up tdesc_data = tdesc_data_alloc (); info.tdesc_data = tdesc_data.get (); @@ -7156,7 +7155,6 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Check any target description for validity. */ if (!s390_tdesc_valid (tdep, tdesc_data.get ())) { - delete tdep; gdbarch_free (gdbarch); return NULL; } @@ -7189,7 +7187,6 @@ s390_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) if (tmp->vector_abi != tdep->vector_abi) continue; - delete tdep; gdbarch_free (gdbarch); return arches->gdbarch; } diff --git a/gdb/s390-tdep.h b/gdb/s390-tdep.h index f0f7019ac6a..e75ee48df9a 100644 --- a/gdb/s390-tdep.h +++ b/gdb/s390-tdep.h @@ -67,6 +67,8 @@ struct s390_gdbarch_tdep : gdbarch_tdep_base = nullptr; }; +using s390_gdbarch_tdep_up = std::unique_ptr; + /* Decoding S/390 instructions. */ /* Named opcode values for the S/390 instructions we recognize. Some diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c index a2e91483229..40c4bdda212 100644 --- a/gdb/sh-tdep.c +++ b/gdb/sh-tdep.c @@ -2195,8 +2195,6 @@ sh_return_in_first_hidden_param_p (struct gdbarch *gdbarch, static struct gdbarch * sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; - /* If there is already a candidate, use it. */ arches = gdbarch_list_lookup_by_info (arches, &info); if (arches != NULL) @@ -2204,8 +2202,8 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* None found, create a new architecture from the information provided. */ - sh_gdbarch_tdep *tdep = new sh_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new sh_gdbarch_tdep)); set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT); set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT); diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c index 49c055e43cb..b003ebcb90a 100644 --- a/gdb/sparc-tdep.c +++ b/gdb/sparc-tdep.c @@ -1807,7 +1807,6 @@ static struct gdbarch * sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { const struct target_desc *tdesc = info.target_desc; - struct gdbarch *gdbarch; int valid_p = 1; /* If there is already a candidate, use it. */ @@ -1816,8 +1815,9 @@ sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) return arches->gdbarch; /* Allocate space for the new architecture. */ - sparc_gdbarch_tdep *tdep = new sparc_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new sparc_gdbarch_tdep)); + sparc_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); tdep->pc_regnum = SPARC32_PC_REGNUM; tdep->npc_regnum = SPARC32_NPC_REGNUM; diff --git a/gdb/tic6x-tdep.c b/gdb/tic6x-tdep.c index 054f0e6f3b2..b59fbcc2f03 100644 --- a/gdb/tic6x-tdep.c +++ b/gdb/tic6x-tdep.c @@ -1136,7 +1136,6 @@ tic6x_return_in_first_hidden_param_p (struct gdbarch *gdbarch, static struct gdbarch * tic6x_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; tdesc_arch_data_up tdesc_data; const struct target_desc *tdesc = info.target_desc; int has_gp = 0; @@ -1221,10 +1220,11 @@ tic6x_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) return arches->gdbarch; } - tic6x_gdbarch_tdep *tdep = new tic6x_gdbarch_tdep; + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new tic6x_gdbarch_tdep)); + tic6x_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); tdep->has_gp = has_gp; - gdbarch = gdbarch_alloc (&info, tdep); /* Data type sizes. */ set_gdbarch_ptr_bit (gdbarch, 32); diff --git a/gdb/v850-tdep.c b/gdb/v850-tdep.c index a40e9abf077..d8406a5f14c 100644 --- a/gdb/v850-tdep.c +++ b/gdb/v850-tdep.c @@ -1348,7 +1348,6 @@ static const struct frame_base v850_frame_base = { static struct gdbarch * v850_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; int e_flags, e_machine; /* Extract the elf_flags if available. */ @@ -1380,7 +1379,10 @@ v850_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) return arches->gdbarch; } - v850_gdbarch_tdep *tdep = new v850_gdbarch_tdep; + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new v850_gdbarch_tdep)); + v850_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + tdep->e_flags = e_flags; tdep->e_machine = e_machine; @@ -1395,7 +1397,6 @@ v850_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) } tdep->eight_byte_align = (tdep->e_flags & EF_RH850_DATA_ALIGN8) ? 1 : 0; - gdbarch = gdbarch_alloc (&info, tdep); switch (info.bfd_arch_info->mach) { diff --git a/gdb/xtensa-config.c b/gdb/xtensa-config.c index a28ffd58c96..37f893aa8f1 100644 --- a/gdb/xtensa-config.c +++ b/gdb/xtensa-config.c @@ -62,7 +62,7 @@ const xtensa_mask_t xtensa_mask15 = { 1, xtensa_submask15 }; /* Register map. */ -static xtensa_register_t rmap[] = +xtensa_register_t xtensa_rmap[] = { /* idx ofs bi sz al targno flags cp typ group name */ XTREG( 0, 0,32, 4, 4,0x0020,0x0006,-2, 9,0x0100,pc, 0,0,0,0,0,0) @@ -212,5 +212,3 @@ static xtensa_register_t rmap[] = 0,0,&xtensa_mask15,0,0,0) XTREG_END }; - -xtensa_gdbarch_tdep xtensa_tdep (rmap); diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c index 27634f5f4ce..78b328c50dc 100644 --- a/gdb/xtensa-tdep.c +++ b/gdb/xtensa-tdep.c @@ -3145,13 +3145,11 @@ xtensa_derive_tdep (xtensa_gdbarch_tdep *tdep) /* Module "constructor" function. */ -extern xtensa_gdbarch_tdep xtensa_tdep; +extern xtensa_register_t xtensa_rmap[]; static struct gdbarch * xtensa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; - DEBUGTRACE ("gdbarch_init()\n"); if (!xtensa_default_isa) @@ -3160,8 +3158,10 @@ xtensa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* We have to set the byte order before we call gdbarch_alloc. */ info.byte_order = XCHAL_HAVE_BE ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE; - xtensa_gdbarch_tdep *tdep = &xtensa_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, + gdbarch_tdep_up (new xtensa_gdbarch_tdep (xtensa_rmap))); + xtensa_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); xtensa_derive_tdep (tdep); /* Verify our configuration. */ diff --git a/gdb/z80-tdep.c b/gdb/z80-tdep.c index 3141feb4d80..84a37b2d78d 100644 --- a/gdb/z80-tdep.c +++ b/gdb/z80-tdep.c @@ -1081,7 +1081,6 @@ z80_frame_unwind = static struct gdbarch * z80_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { - struct gdbarch *gdbarch; struct gdbarch_list *best_arch; tdesc_arch_data_up tdesc_data; unsigned long mach = info.bfd_arch_info->mach; @@ -1123,8 +1122,9 @@ z80_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) } /* None found, create a new architecture from the information provided. */ - z80_gdbarch_tdep *tdep = new z80_gdbarch_tdep; - gdbarch = gdbarch_alloc (&info, tdep); + gdbarch *gdbarch + = gdbarch_alloc (&info, gdbarch_tdep_up (new z80_gdbarch_tdep)); + z80_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); if (mach == bfd_mach_ez80_adl) { From patchwork Tue Dec 6 13:57:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 61554 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7577F383FD4A for ; Tue, 6 Dec 2022 13:59:07 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7577F383FD4A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1670335147; bh=skk0fgVDuOqqGOqay+Ny9Vbct64fr5RKbCbfX/jQTsk=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=ngWOG4/ER6q0jftav/vPG9IJ4lVDSCOgxWnj4XqBJAuVoRnYBORGCe/1xUy81t3KP OK6Rn8YviKtWKLTiMzN7pnDEcTQBUcPKVGAGgxXcN1vYPcsVWuAa+qnrMGQSOl2A8t fXfoLx4hbR5247FVYdNlUkmn8SK0tQUc7r0OsZGw= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id 2D58B384C902 for ; Tue, 6 Dec 2022 13:57:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2D58B384C902 X-ASG-Debug-ID: 1670335052-0c856e762b1bb10001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id u6GuaxAHMy0WxNsI (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO); Tue, 06 Dec 2022 08:57:32 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@efficios.com X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from epycamd.internal.efficios.com (192-222-180-24.qc.cable.ebox.net [192.222.180.24]) by smtp.ebox.ca (Postfix) with ESMTP id 8CB50441D64; Tue, 6 Dec 2022 08:57:32 -0500 (EST) X-Barracuda-RBL-IP: 192.222.180.24 X-Barracuda-Effective-Source-IP: 192-222-180-24.qc.cable.ebox.net[192.222.180.24] X-Barracuda-Apparent-Source-IP: 192.222.180.24 To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 06/12] gdb: add gdbarch_up Date: Tue, 6 Dec 2022 08:57:23 -0500 X-ASG-Orig-Subj: [PATCH 06/12] gdb: add gdbarch_up Message-Id: <20221206135729.3937767-7-simon.marchi@efficios.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221206135729.3937767-1-simon.marchi@efficios.com> References: <20221206135729.3937767-1-simon.marchi@efficios.com> MIME-Version: 1.0 X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1670335052 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 826 X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=5.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.102644 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Spam-Status: No, score=-3498.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_SOFTFAIL, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" Add a gdbarch_up unique pointer type, that calls gdbarch_free on deletion. This is used in the ROCm support patch at the end of this series. Change-Id: I4b808892d35d69a590ce83180f41afd91705b2c8 --- gdb/gdbarch.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 196c7981450..d3af5ee00d1 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -306,6 +306,14 @@ extern struct gdbarch *gdbarch_alloc (const struct gdbarch_info *info, extern void gdbarch_free (struct gdbarch *); +struct gdbarch_deleter +{ + void operator() (gdbarch *arch) const + { gdbarch_free (arch); } +}; + +using gdbarch_up = std::unique_ptr; + /* Get the obstack owned by ARCH. */ extern obstack *gdbarch_obstack (gdbarch *arch); From patchwork Tue Dec 6 13:57:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 61555 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id F3A5F384233B for ; Tue, 6 Dec 2022 13:59:09 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F3A5F384233B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1670335150; bh=C8i5EcGQgNQCjBgpw5yJJRv68KUFRwNuuEE1NFYuFpA=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=WNIW8CNfZhbUbpvBn+G6EHhltMTxVSXfUud4Eb0JrT8vvq5fvJ1j6JwtEkc+Fzczx npSA5701WC/r+7WiAoB7BVr735GitnxfCj5GU0gGb9qUJzl4tAfdIaz9GO9S7eHNGv SJj5QVKFEmgjBdUu/pDSAOFcCV7TQcbd7eopQOhI= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id 2A5EB384C900 for ; Tue, 6 Dec 2022 13:57:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2A5EB384C900 X-ASG-Debug-ID: 1670335052-0c856e762b1bb20001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id kF7HhTk5ZYB0HAMN (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO); Tue, 06 Dec 2022 08:57:32 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@efficios.com X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from epycamd.internal.efficios.com (192-222-180-24.qc.cable.ebox.net [192.222.180.24]) by smtp.ebox.ca (Postfix) with ESMTP id B1110441D65; Tue, 6 Dec 2022 08:57:32 -0500 (EST) X-Barracuda-RBL-IP: 192.222.180.24 X-Barracuda-Effective-Source-IP: 192-222-180-24.qc.cable.ebox.net[192.222.180.24] X-Barracuda-Apparent-Source-IP: 192.222.180.24 To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 07/12] gdbsupport: move libxxhash configure check to gdbsupport Date: Tue, 6 Dec 2022 08:57:24 -0500 X-ASG-Orig-Subj: [PATCH 07/12] gdbsupport: move libxxhash configure check to gdbsupport Message-Id: <20221206135729.3937767-8-simon.marchi@efficios.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221206135729.3937767-1-simon.marchi@efficios.com> References: <20221206135729.3937767-1-simon.marchi@efficios.com> MIME-Version: 1.0 X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1670335052 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 280880 X-Barracuda-Spam-Score: -1001.00 X-Barracuda-Spam-Status: No, SCORE=-1001.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=5.0 X-Spam-Status: No, score=-3497.7 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LINEPADDING, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_SOFTFAIL, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" The following patch moves the fast_hash function, which uses libxxhash, to gdbsupport. Move the libxxhash configure check to gdbsupport (and transitively to gdbserver). Change-Id: I242499e50c8cd6fe9f51e6e92dc53a1b3daaa96e --- gdb/configure | 5994 ++++++++++++++++++++-------------------- gdb/configure.ac | 23 - gdbserver/config.in | 3 + gdbserver/configure | 514 ++++ gdbsupport/Makefile.in | 3 + gdbsupport/common.m4 | 24 + gdbsupport/config.in | 3 + gdbsupport/configure | 514 ++++ 8 files changed, 4058 insertions(+), 3020 deletions(-) diff --git a/gdb/configure b/gdb/configure index 23e6b7160ec..1b07e1e798c 100755 --- a/gdb/configure +++ b/gdb/configure @@ -638,9 +638,6 @@ GDB_TRANSFORM_NAME XSLTPROC NM_H GDB_NM_FILE -LTLIBXXHASH -LIBXXHASH -HAVE_LIBXXHASH CTF_DEPS LIBCTF LTLIBBABELTRACE @@ -716,6 +713,9 @@ SYSTEM_GDBINIT TARGET_SYSTEM_ROOT CONFIG_LDFLAGS RDYNAMIC +LTLIBXXHASH +LIBXXHASH +HAVE_LIBXXHASH LTLIBIPT LIBIPT HAVE_LIBIPT @@ -947,6 +947,9 @@ enable_threading with_intel_pt with_libipt_prefix with_libipt_type +with_xxhash +with_libxxhash_prefix +with_libxxhash_type with_sysroot with_system_gdbinit with_system_gdbinit_dir @@ -965,10 +968,7 @@ enable_libbacktrace with_babeltrace with_libbabeltrace_prefix with_libbabeltrace_type -with_xxhash enable_libctf -with_libxxhash_prefix -with_libxxhash_type enable_unit_tests ' ac_precious_vars='build_alias @@ -1714,6 +1714,10 @@ Optional Packages: --with-libipt-prefix[=DIR] search for libipt in DIR/include and DIR/lib --without-libipt-prefix don't search for libipt in includedir and libdir --with-libipt-type=TYPE type of library to search for (auto/static/shared) + --with-xxhash use libxxhash for hashing (faster) (auto/yes/no) + --with-libxxhash-prefix[=DIR] search for libxxhash in DIR/include and DIR/lib + --without-libxxhash-prefix don't search for libxxhash in includedir and libdir + --with-libxxhash-type=TYPE type of library to search for (auto/static/shared) --with-sysroot[=DIR] search for usr/lib et al within DIR --with-system-gdbinit=PATH automatically load a system-wide gdbinit file @@ -1731,10 +1735,6 @@ Optional Packages: --with-libbabeltrace-prefix[=DIR] search for libbabeltrace in DIR/include and DIR/lib --without-libbabeltrace-prefix don't search for libbabeltrace in includedir and libdir --with-libbabeltrace-type=TYPE type of library to search for (auto/static/shared) - --with-xxhash use libxxhash for hashing (faster) (auto/yes/no) - --with-libxxhash-prefix[=DIR] search for libxxhash in DIR/include and DIR/lib - --without-libxxhash-prefix don't search for libxxhash in includedir and libdir - --with-libxxhash-type=TYPE type of library to search for (auto/static/shared) Some influential environment variables: CC C compiler command @@ -26973,3669 +26973,3633 @@ $as_echo "$bfd_cv_have_sys_procfs_type_elf_fpregset_t" >&6; } fi + # Check for xxhash -# Check the return and argument types of ptrace. - - -for ac_header in sys/ptrace.h ptrace.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -gdb_ptrace_headers=' -#include -#if HAVE_SYS_PTRACE_H -# include -#endif -#if HAVE_UNISTD_H -# include -#endif -' - -# Check return type. Varargs (used on GNU/Linux) conflict with the -# empty argument list, so check for that explicitly. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of ptrace" >&5 -$as_echo_n "checking return type of ptrace... " >&6; } -if ${gdb_cv_func_ptrace_ret+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - $gdb_ptrace_headers -int -main () -{ -extern long ptrace (enum __ptrace_request, ...); - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - gdb_cv_func_ptrace_ret='long' -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$gdb_ptrace_headers -int -main () -{ -extern int ptrace (); - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - gdb_cv_func_ptrace_ret='int' +# Check whether --with-xxhash was given. +if test "${with_xxhash+set}" = set; then : + withval=$with_xxhash; else - gdb_cv_func_ptrace_ret='long' - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - + with_xxhash=auto fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_func_ptrace_ret" >&5 -$as_echo "$gdb_cv_func_ptrace_ret" >&6; } - -cat >>confdefs.h <<_ACEOF -#define PTRACE_TYPE_RET $gdb_cv_func_ptrace_ret -_ACEOF + if test "x$with_xxhash" != "xno"; then -# Check argument types. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking types of arguments for ptrace" >&5 -$as_echo_n "checking types of arguments for ptrace... " >&6; } -if ${gdb_cv_func_ptrace_args+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$gdb_ptrace_headers -int -main () -{ -extern long ptrace (enum __ptrace_request, ...); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - gdb_cv_func_ptrace_args='enum __ptrace_request,int,long,long' -else - for gdb_arg1 in 'int' 'long'; do - for gdb_arg2 in 'pid_t' 'int' 'long'; do - for gdb_arg3 in 'int *' 'caddr_t' 'int' 'long' 'void *'; do - for gdb_arg4 in 'int' 'long' 'void *'; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$gdb_ptrace_headers -int -main () -{ -extern $gdb_cv_func_ptrace_ret ptrace ($gdb_arg1, $gdb_arg2, $gdb_arg3, $gdb_arg4); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - gdb_cv_func_ptrace_args="$gdb_arg1,$gdb_arg2,$gdb_arg3,$gdb_arg4"; - break 4; -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - for gdb_arg5 in 'int *' 'int' 'long'; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$gdb_ptrace_headers -int -main () -{ -extern $gdb_cv_func_ptrace_ret ptrace ($gdb_arg1, $gdb_arg2, $gdb_arg3, $gdb_arg4, $gdb_arg5); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - gdb_cv_func_ptrace_args="$gdb_arg1,$gdb_arg2,$gdb_arg3,$gdb_arg4,$gdb_arg5"; - break 5; -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done - done - done - done - done - # Provide a safe default value. - : ${gdb_cv_func_ptrace_args='int,int,long,long'} -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + use_additional=yes -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_func_ptrace_args" >&5 -$as_echo "$gdb_cv_func_ptrace_args" >&6; } + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" -ac_save_IFS=$IFS; IFS=',' -set dummy `echo "$gdb_cv_func_ptrace_args" | sed 's/\*/\*/g'` -IFS=$ac_save_IFS -shift + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" -cat >>confdefs.h <<_ACEOF -#define PTRACE_TYPE_ARG1 $1 -_ACEOF + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" -cat >>confdefs.h <<_ACEOF -#define PTRACE_TYPE_ARG3 $3 -_ACEOF +# Check whether --with-libxxhash-prefix was given. +if test "${with_libxxhash_prefix+set}" = set; then : + withval=$with_libxxhash_prefix; + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" -cat >>confdefs.h <<_ACEOF -#define PTRACE_TYPE_ARG4 $4 -_ACEOF + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" -if test -n "$5"; then + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" -cat >>confdefs.h <<_ACEOF -#define PTRACE_TYPE_ARG5 $5 -_ACEOF + else + additional_includedir="$withval/include" + additional_libdir="$withval/lib" + fi + fi fi -if test "$cross_compiling" = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether setpgrp takes no argument" >&5 -$as_echo_n "checking whether setpgrp takes no argument... " >&6; } -if ${ac_cv_func_setpgrp_void+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - as_fn_error $? "cannot check setpgrp when cross compiling" "$LINENO" 5 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -/* If this system has a BSD-style setpgrp which takes arguments, - setpgrp(1, 1) will fail with ESRCH and return -1, in that case - exit successfully. */ - return setpgrp (1,1) != -1; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_func_setpgrp_void=no +# Check whether --with-libxxhash-type was given. +if test "${with_libxxhash_type+set}" = set; then : + withval=$with_libxxhash_type; with_libxxhash_type=$withval else - ac_cv_func_setpgrp_void=yes -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - + with_libxxhash_type=auto fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_setpgrp_void" >&5 -$as_echo "$ac_cv_func_setpgrp_void" >&6; } -if test $ac_cv_func_setpgrp_void = yes; then -$as_echo "#define SETPGRP_VOID 1" >>confdefs.h + lib_type=`eval echo \$with_libxxhash_type` -fi - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether setpgrp takes no argument" >&5 -$as_echo_n "checking whether setpgrp takes no argument... " >&6; } -if ${ac_cv_func_setpgrp_void+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -if (setpgrp(1,1) == -1) - exit (0); - else - exit (1); - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_setpgrp_void=no -else - ac_cv_func_setpgrp_void=yes - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_setpgrp_void" >&5 -$as_echo "$ac_cv_func_setpgrp_void" >&6; } -if test "$ac_cv_func_setpgrp_void" = yes; then - $as_echo "#define SETPGRP_VOID 1" >>confdefs.h - -fi -fi - -# Check if defines `struct thread' with a td_pcb member. -ac_fn_c_check_member "$LINENO" "struct thread" "td_pcb" "ac_cv_member_struct_thread_td_pcb" "#include -#include - -" -if test "x$ac_cv_member_struct_thread_td_pcb" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_THREAD_TD_PCB 1 -_ACEOF - - -fi - - -# See if defines `struct lwp`. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct lwp" >&5 -$as_echo_n "checking for struct lwp... " >&6; } -if ${gdb_cv_struct_lwp+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - #define _KMEMUSER - #include -int -main () -{ -struct lwp l; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - gdb_cv_struct_lwp=yes -else - gdb_cv_struct_lwp=no - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_struct_lwp" >&5 -$as_echo "$gdb_cv_struct_lwp" >&6; } -if test "$gdb_cv_struct_lwp" = yes; then - -$as_echo "#define HAVE_STRUCT_LWP 1" >>confdefs.h - -fi - -# See if degines `struct reg'. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct reg in machine/reg.h" >&5 -$as_echo_n "checking for struct reg in machine/reg.h... " >&6; } -if ${gdb_cv_struct_reg+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - #include -int -main () -{ -struct reg r; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - gdb_cv_struct_reg=yes -else - gdb_cv_struct_reg=no - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_struct_reg" >&5 -$as_echo "$gdb_cv_struct_reg" >&6; } -if test "$gdb_cv_struct_reg" = yes; then - -$as_echo "#define HAVE_STRUCT_REG 1" >>confdefs.h - -fi - -# See if supports the %fs and %gs i386 segment registers. -# Older i386 BSD's don't have the r_fs and r_gs members of `struct reg'. -ac_fn_c_check_member "$LINENO" "struct reg" "r_fs" "ac_cv_member_struct_reg_r_fs" "#include -#include -" -if test "x$ac_cv_member_struct_reg_r_fs" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_REG_R_FS 1 -_ACEOF - - -fi -ac_fn_c_check_member "$LINENO" "struct reg" "r_gs" "ac_cv_member_struct_reg_r_gs" "#include -#include -" -if test "x$ac_cv_member_struct_reg_r_gs" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_REG_R_GS 1 -_ACEOF - - -fi - - -# See if provides the PTRACE_GETREGS request. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTRACE_GETREGS" >&5 -$as_echo_n "checking for PTRACE_GETREGS... " >&6; } -if ${gdb_cv_have_ptrace_getregs+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -PTRACE_GETREGS; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - gdb_cv_have_ptrace_getregs=yes -else - gdb_cv_have_ptrace_getregs=no - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_have_ptrace_getregs" >&5 -$as_echo "$gdb_cv_have_ptrace_getregs" >&6; } -if test "$gdb_cv_have_ptrace_getregs" = yes; then - -$as_echo "#define HAVE_PTRACE_GETREGS 1" >>confdefs.h - -fi - -# See if provides the PTRACE_GETFPXREGS request. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTRACE_GETFPXREGS" >&5 -$as_echo_n "checking for PTRACE_GETFPXREGS... " >&6; } -if ${gdb_cv_have_ptrace_getfpxregs+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -PTRACE_GETFPXREGS; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - gdb_cv_have_ptrace_getfpxregs=yes -else - gdb_cv_have_ptrace_getfpxregs=no - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_have_ptrace_getfpxregs" >&5 -$as_echo "$gdb_cv_have_ptrace_getfpxregs" >&6; } -if test "$gdb_cv_have_ptrace_getfpxregs" = yes; then - -$as_echo "#define HAVE_PTRACE_GETFPXREGS 1" >>confdefs.h - -fi - -# See if provides the PT_GETDBREGS request. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PT_GETDBREGS" >&5 -$as_echo_n "checking for PT_GETDBREGS... " >&6; } -if ${gdb_cv_have_pt_getdbregs+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - #include -int -main () -{ -PT_GETDBREGS; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - gdb_cv_have_pt_getdbregs=yes -else - gdb_cv_have_pt_getdbregs=no - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + LIBXXHASH= + LTLIBXXHASH= + INCXXHASH= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='xxhash ' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }$value" + else + : + fi + else + found_dir= + found_la= + found_so= + found_a= + if test $use_additional = yes; then + if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext" && test x$lib_type != xstatic; then + found_dir="$additional_libdir" + found_so="$additional_libdir/lib$name.$shlibext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + elif test x$lib_type != xshared; then + if test -f "$additional_libdir/lib$name.$libext"; then + found_dir="$additional_libdir" + found_a="$additional_libdir/lib$name.$libext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIBXXHASH; do -fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_have_pt_getdbregs" >&5 -$as_echo "$gdb_cv_have_pt_getdbregs" >&6; } -if test "$gdb_cv_have_pt_getdbregs" = yes; then + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext" && test x$lib_type != xstatic; then + found_dir="$dir" + found_so="$dir/lib$name.$shlibext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + elif test x$lib_type != xshared; then + if test -f "$dir/lib$name.$libext"; then + found_dir="$dir" + found_a="$dir/lib$name.$libext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$found_so" + else + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + if test "$hardcode_direct" = yes; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$found_so" + else + if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$found_so" + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + haveit= + for x in $LDFLAGS $LIBXXHASH; do -$as_echo "#define HAVE_PT_GETDBREGS 1" >>confdefs.h + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" -fi + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-L$found_dir" + fi + if test "$hardcode_minus_L" != no; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$found_so" + else + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$found_a" + else + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-L$found_dir -l$name" + fi + fi + additional_includedir= + case "$found_dir" in + */lib | */lib/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INCXXHASH; do -# See if supports LWP names on FreeBSD -# Older FreeBSD versions don't have the pl_tdname member of -# `struct ptrace_lwpinfo'. -ac_fn_c_check_member "$LINENO" "struct ptrace_lwpinfo" "pl_tdname" "ac_cv_member_struct_ptrace_lwpinfo_pl_tdname" "#include -" -if test "x$ac_cv_member_struct_ptrace_lwpinfo_pl_tdname" = xyes; then : + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME 1 -_ACEOF + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + INCXXHASH="${INCXXHASH}${INCXXHASH:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + if test -n "$found_la"; then + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + if test "X$additional_libdir" != "X/usr/lib"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/lib"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIBXXHASH; do + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" -fi + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIBXXHASH; do + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" -# See if supports syscall fields on FreeBSD. The -# pl_syscall_code member of `struct ptrace_lwpinfo' was added in -# FreeBSD 10.3. -ac_fn_c_check_member "$LINENO" "struct ptrace_lwpinfo" "pl_syscall_code" "ac_cv_member_struct_ptrace_lwpinfo_pl_syscall_code" "#include -" -if test "x$ac_cv_member_struct_ptrace_lwpinfo_pl_syscall_code" = xyes; then : + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$dep" + LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }$dep" + ;; + esac + done + fi + else + if test "x$lib_type" = "xauto" || test "x$lib_type" = "xshared"; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-l$name" + LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }-l$name" + else + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-l:lib$name.$libext" + LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }-l:lib$name.$libext" + fi + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$hardcode_libdir_separator"; then + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$flag" + else + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + for found_dir in $ltrpathdirs; do + LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }-R$found_dir" + done + fi -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE 1 -_ACEOF + ac_save_CPPFLAGS="$CPPFLAGS" -fi + for element in $INCXXHASH; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done -# Check if the compiler supports the `long long' type. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long support in compiler" >&5 -$as_echo_n "checking for long long support in compiler... " >&6; } -if ${gdb_cv_c_long_long+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libxxhash" >&5 +$as_echo_n "checking for libxxhash... " >&6; } +if ${ac_cv_libxxhash+:} false; then : $as_echo_n "(cached) " >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + + ac_save_LIBS="$LIBS" + LIBS="$LIBS $LIBXXHASH" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -extern long long foo; +#include int main () { -switch (foo & 2) { case 0: return 1; } +XXH32("foo", 3, 0); + ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - gdb_cv_c_long_long=yes +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_libxxhash=yes else - gdb_cv_c_long_long=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_libxxhash=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_c_long_long" >&5 -$as_echo "$gdb_cv_c_long_long" >&6; } -if test "$gdb_cv_c_long_long" != yes; then - # libdecnumber requires long long. - as_fn_error $? "Compiler must support long long for GDB." "$LINENO" 5 +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$ac_save_LIBS" + fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libxxhash" >&5 +$as_echo "$ac_cv_libxxhash" >&6; } + if test "$ac_cv_libxxhash" = yes; then + HAVE_LIBXXHASH=yes -# Check if the compiler and runtime support printing decfloats. +$as_echo "#define HAVE_LIBXXHASH 1" >>confdefs.h -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for decfloat support in printf" >&5 -$as_echo_n "checking for decfloat support in printf... " >&6; } -if ${gdb_cv_printf_has_decfloat+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - gdb_cv_printf_has_decfloat=no -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -char buf[64]; - _Decimal32 d32 = 1.2345df; - _Decimal64 d64 = 1.2345dd; - _Decimal128 d128 = 1.2345dl; - sprintf (buf, "Decimal32: %H\nDecimal64: %D\nDecimal128: %DD", d32, d64, d128); - return (strcmp ("Decimal32: 1.2345\nDecimal64: 1.2345\nDecimal128: 1.2345", buf)); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - gdb_cv_printf_has_decfloat=yes -else - gdb_cv_printf_has_decfloat=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libxxhash" >&5 +$as_echo_n "checking how to link with libxxhash... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBXXHASH" >&5 +$as_echo "$LIBXXHASH" >&6; } + else + HAVE_LIBXXHASH=no + CPPFLAGS="$ac_save_CPPFLAGS" + LIBXXHASH= + LTLIBXXHASH= + fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_printf_has_decfloat" >&5 -$as_echo "$gdb_cv_printf_has_decfloat" >&6; } -if test "$gdb_cv_printf_has_decfloat" = yes; then -$as_echo "#define PRINTF_HAS_DECFLOAT 1" >>confdefs.h -fi -# Check if the compiler supports the `long double' type. We can't use -# AC_C_LONG_DOUBLE because that one does additional checks on the -# constants defined in that fail on some systems, -# e.g. FreeBSD/i386 4.7 and OpenBSD/i386 3.6. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for long double support in compiler" >&5 -$as_echo_n "checking for long double support in compiler... " >&6; } -if ${gdb_cv_c_long_double+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -long double foo; -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - gdb_cv_c_long_double=yes -else - gdb_cv_c_long_double=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_c_long_double" >&5 -$as_echo "$gdb_cv_c_long_double" >&6; } -if test "$gdb_cv_c_long_double" = yes; then -$as_echo "#define HAVE_LONG_DOUBLE 1" >>confdefs.h + if test "$HAVE_LIBXXHASH" != yes; then + if test "$with_xxhash" = yes; then + as_fn_error $? "xxhash is missing or unusable" "$LINENO" 5 + fi + fi + if test "x$with_xxhash" = "xauto"; then + with_xxhash="$HAVE_LIBXXHASH" + fi + fi -fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use xxhash" >&5 +$as_echo_n "checking whether to use xxhash... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_xxhash" >&5 +$as_echo "$with_xxhash" >&6; } -# Check if the compiler and runtime support printing long doubles. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for long double support in printf" >&5 -$as_echo_n "checking for long double support in printf... " >&6; } -if ${gdb_cv_printf_has_long_double+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - gdb_cv_printf_has_long_double=no -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -char buf[16]; - long double f = 3.141592653; - sprintf (buf, "%Lg", f); - return (strncmp ("3.14159", buf, 7)); - ; - return 0; -} +# Check the return and argument types of ptrace. + + +for ac_header in sys/ptrace.h ptrace.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - gdb_cv_printf_has_long_double=yes -else - gdb_cv_printf_has_long_double=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_printf_has_long_double" >&5 -$as_echo "$gdb_cv_printf_has_long_double" >&6; } -if test "$gdb_cv_printf_has_long_double" = yes; then -$as_echo "#define PRINTF_HAS_LONG_DOUBLE 1" >>confdefs.h +done -fi -# Check if the compiler and runtime support scanning long doubles. +gdb_ptrace_headers=' +#include +#if HAVE_SYS_PTRACE_H +# include +#endif +#if HAVE_UNISTD_H +# include +#endif +' -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for long double support in scanf" >&5 -$as_echo_n "checking for long double support in scanf... " >&6; } -if ${gdb_cv_scanf_has_long_double+:} false; then : +# Check return type. Varargs (used on GNU/Linux) conflict with the +# empty argument list, so check for that explicitly. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of ptrace" >&5 +$as_echo_n "checking return type of ptrace... " >&6; } +if ${gdb_cv_func_ptrace_ret+:} false; then : $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - gdb_cv_scanf_has_long_double=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include + $gdb_ptrace_headers int main () { -char *buf = "3.141592653"; - long double f = 0; - sscanf (buf, "%Lg", &f); - return !(f > 3.14159 && f < 3.14160); +extern long ptrace (enum __ptrace_request, ...); + ; return 0; } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - gdb_cv_scanf_has_long_double=yes -else - gdb_cv_scanf_has_long_double=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_scanf_has_long_double" >&5 -$as_echo "$gdb_cv_scanf_has_long_double" >&6; } -if test "$gdb_cv_scanf_has_long_double" = yes; then - -$as_echo "#define SCANF_HAS_LONG_DOUBLE 1" >>confdefs.h - -fi - -case ${host_os} in -aix*) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -bbigtoc option" >&5 -$as_echo_n "checking for -bbigtoc option... " >&6; } -if ${gdb_cv_bigtoc+:} false; then : - $as_echo_n "(cached) " >&6 +if ac_fn_c_try_compile "$LINENO"; then : + gdb_cv_func_ptrace_ret='long' else - SAVE_LDFLAGS=$LDFLAGS - - case $GCC in - yes) gdb_cv_bigtoc=-Wl,-bbigtoc ;; - *) gdb_cv_bigtoc=-bbigtoc ;; - esac - - LDFLAGS=$LDFLAGS\ $gdb_cv_bigtoc - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - +$gdb_ptrace_headers int main () { -int i; +extern int ptrace (); + ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - +if ac_fn_c_try_compile "$LINENO"; then : + gdb_cv_func_ptrace_ret='int' else - gdb_cv_bigtoc= + gdb_cv_func_ptrace_ret='long' fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS="${SAVE_LDFLAGS}" +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_bigtoc" >&5 -$as_echo "$gdb_cv_bigtoc" >&6; } - CONFIG_LDFLAGS="${CONFIG_LDFLAGS} ${gdb_cv_bigtoc}" - ;; -esac +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_func_ptrace_ret" >&5 +$as_echo "$gdb_cv_func_ptrace_ret" >&6; } + + +cat >>confdefs.h <<_ACEOF +#define PTRACE_TYPE_RET $gdb_cv_func_ptrace_ret +_ACEOF -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the dynamic export flag" >&5 -$as_echo_n "checking for the dynamic export flag... " >&6; } -dynamic_list=false -if test "${gdb_native}" = yes; then - # The dynamically loaded libthread_db needs access to symbols in the gdb - # executable. Older GNU ld supports --export-dynamic but --dynamic-list - # may not be supported there. - old_LDFLAGS="$LDFLAGS" - # Older GNU ld supports --export-dynamic but --dynamic-list it does not. - RDYNAMIC="-Wl,--dynamic-list=${srcdir}/proc-service.list" - LDFLAGS="$LDFLAGS $RDYNAMIC" - if test "${have_libpython}" = no; then - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +# Check argument types. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking types of arguments for ptrace" >&5 +$as_echo_n "checking types of arguments for ptrace... " >&6; } +if ${gdb_cv_func_ptrace_args+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$gdb_ptrace_headers int main () { +extern long ptrace (enum __ptrace_request, ...); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - dynamic_list=true -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - else - # Workaround http://bugs.python.org/issue4434 where static - # libpythonX.Y.a would get its symbols required for - # pythonX.Y/lib-dynload/*.so modules hidden by -Wl,--dynamic-list. - # Problem does not happen for the recommended libpythonX.Y.so linkage. - - # Note the workaround for Python - # http://bugs.python.org/issue10112 earlier has removed - # -export-dynamic from PYTHON_LIBS. That's exactly what we want - # here too, as otherwise it'd make this -Wl,--dynamic-list test - # always pass. - old_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $PYTHON_CFLAGS" - old_LIBS="$LIBS" - LIBS="$LIBS $PYTHON_LIBS" - old_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $PYTHON_CPPFLAGS" - if test "$cross_compiling" = yes; then : - true +if ac_fn_c_try_compile "$LINENO"; then : + gdb_cv_func_ptrace_args='enum __ptrace_request,int,long,long' else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + for gdb_arg1 in 'int' 'long'; do + for gdb_arg2 in 'pid_t' 'int' 'long'; do + for gdb_arg3 in 'int *' 'caddr_t' 'int' 'long' 'void *'; do + for gdb_arg4 in 'int' 'long' 'void *'; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include "Python.h" +$gdb_ptrace_headers int main () { -int err; - Py_Initialize (); - err = PyRun_SimpleString ("import ctypes\n"); - Py_Finalize (); - return err == 0 ? 0 : 1; +extern $gdb_cv_func_ptrace_ret ptrace ($gdb_arg1, $gdb_arg2, $gdb_arg3, $gdb_arg4); + ; return 0; } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - dynamic_list=true -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi +if ac_fn_c_try_compile "$LINENO"; then : + gdb_cv_func_ptrace_args="$gdb_arg1,$gdb_arg2,$gdb_arg3,$gdb_arg4"; + break 4; - LIBS="$old_LIBS" - CFLAGS="$old_CFLAGS" - CPPFLAGS="$old_CPPFLAGS" - fi - LDFLAGS="$old_LDFLAGS" -fi -if $dynamic_list; then - found="-Wl,--dynamic-list" - RDYNAMIC='-Wl,--dynamic-list=$(srcdir)/proc-service.list' -else - found="-rdynamic" - RDYNAMIC="-rdynamic" fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $found" >&5 -$as_echo "$found" >&6; } - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether execinfo.h backtrace is available" >&5 -$as_echo_n "checking whether execinfo.h backtrace is available... " >&6; } -if ${gdb_cv_execinfo_backtrace+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + for gdb_arg5 in 'int *' 'int' 'long'; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - - #include - +$gdb_ptrace_headers int main () { - - int f; - void *b[2]; - f = backtrace (b, 2); - backtrace_symbols_fd (b, f, 2); +extern $gdb_cv_func_ptrace_ret ptrace ($gdb_arg1, $gdb_arg2, $gdb_arg3, $gdb_arg4, $gdb_arg5); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - gdb_cv_execinfo_backtrace=yes -else - gdb_cv_execinfo_backtrace=no +if ac_fn_c_try_compile "$LINENO"; then : + gdb_cv_func_ptrace_args="$gdb_arg1,$gdb_arg2,$gdb_arg3,$gdb_arg4,$gdb_arg5"; + break 5; + fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done + done + done + done + done + # Provide a safe default value. + : ${gdb_cv_func_ptrace_args='int,int,long,long'} + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_execinfo_backtrace" >&5 -$as_echo "$gdb_cv_execinfo_backtrace" >&6; } -if test "$gdb_cv_execinfo_backtrace" = yes; then +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -$as_echo "#define HAVE_EXECINFO_BACKTRACE 1" >>confdefs.h +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_func_ptrace_args" >&5 +$as_echo "$gdb_cv_func_ptrace_args" >&6; } + +ac_save_IFS=$IFS; IFS=',' +set dummy `echo "$gdb_cv_func_ptrace_args" | sed 's/\*/\*/g'` +IFS=$ac_save_IFS +shift + +cat >>confdefs.h <<_ACEOF +#define PTRACE_TYPE_ARG1 $1 +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PTRACE_TYPE_ARG3 $3 +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PTRACE_TYPE_ARG4 $4 +_ACEOF + +if test -n "$5"; then + +cat >>confdefs.h <<_ACEOF +#define PTRACE_TYPE_ARG5 $5 +_ACEOF fi -if test "${build}" = "${host}" -a "${host}" = "${target}" ; then - case ${host_os} in - aix*) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for AiX thread debugging library" >&5 -$as_echo_n "checking for AiX thread debugging library... " >&6; } - if ${gdb_cv_have_aix_thread_debug+:} false; then : +if test "$cross_compiling" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether setpgrp takes no argument" >&5 +$as_echo_n "checking whether setpgrp takes no argument... " >&6; } +if ${ac_cv_func_setpgrp_void+:} false; then : $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + as_fn_error $? "cannot check setpgrp when cross compiling" "$LINENO" 5 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include +$ac_includes_default int main () { -#ifndef PTHDB_VERSION_3 - #error - #endif - +/* If this system has a BSD-style setpgrp which takes arguments, + setpgrp(1, 1) will fail with ESRCH and return -1, in that case + exit successfully. */ + return setpgrp (1,1) != -1; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - gdb_cv_have_aix_thread_debug=yes +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_setpgrp_void=no else - gdb_cv_have_aix_thread_debug=no - + ac_cv_func_setpgrp_void=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_have_aix_thread_debug" >&5 -$as_echo "$gdb_cv_have_aix_thread_debug" >&6; } - if test "$gdb_cv_have_aix_thread_debug" = yes; then - CONFIG_SRCS="${CONFIG_SRCS} aix-thread.c" - CONFIG_OBS="${CONFIG_OBS} aix-thread.o" - LIBS="$LIBS -lpthdebug" - - # Older versions of AIX do not provide the declaration for - # the getthrds function (it appears that it was introduced - # with AIX 6.x). - ac_fn_c_check_decl "$LINENO" "getthrds" "ac_cv_have_decl_getthrds" "#include -" -if test "x$ac_cv_have_decl_getthrds" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_setpgrp_void" >&5 +$as_echo "$ac_cv_func_setpgrp_void" >&6; } +if test $ac_cv_func_setpgrp_void = yes; then -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_GETTHRDS $ac_have_decl -_ACEOF - - fi - ;; - esac +$as_echo "#define SETPGRP_VOID 1" >>confdefs.h fi - -if test "x$ac_cv_header_thread_db_h" = "xyes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether has TD_NOTALLOC" >&5 -$as_echo_n "checking whether has TD_NOTALLOC... " >&6; } -if ${gdb_cv_thread_db_h_has_td_notalloc+:} false; then : + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether setpgrp takes no argument" >&5 +$as_echo_n "checking whether setpgrp takes no argument... " >&6; } +if ${ac_cv_func_setpgrp_void+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include +#include int main () { -int i = TD_NOTALLOC; +if (setpgrp(1,1) == -1) + exit (0); + else + exit (1); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - gdb_cv_thread_db_h_has_td_notalloc=yes + ac_cv_func_setpgrp_void=no else - gdb_cv_thread_db_h_has_td_notalloc=no + ac_cv_func_setpgrp_void=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_thread_db_h_has_td_notalloc" >&5 -$as_echo "$gdb_cv_thread_db_h_has_td_notalloc" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_setpgrp_void" >&5 +$as_echo "$ac_cv_func_setpgrp_void" >&6; } +if test "$ac_cv_func_setpgrp_void" = yes; then + $as_echo "#define SETPGRP_VOID 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether has TD_VERSION" >&5 -$as_echo_n "checking whether has TD_VERSION... " >&6; } -if ${gdb_cv_thread_db_h_has_td_version+:} false; then : +fi +fi + +# Check if defines `struct thread' with a td_pcb member. +ac_fn_c_check_member "$LINENO" "struct thread" "td_pcb" "ac_cv_member_struct_thread_td_pcb" "#include +#include + +" +if test "x$ac_cv_member_struct_thread_td_pcb" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_THREAD_TD_PCB 1 +_ACEOF + + +fi + + +# See if defines `struct lwp`. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct lwp" >&5 +$as_echo_n "checking for struct lwp... " >&6; } +if ${gdb_cv_struct_lwp+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include +#include + #define _KMEMUSER + #include int main () { -int i = TD_VERSION; +struct lwp l; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - gdb_cv_thread_db_h_has_td_version=yes + gdb_cv_struct_lwp=yes else - gdb_cv_thread_db_h_has_td_version=no + gdb_cv_struct_lwp=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_thread_db_h_has_td_version" >&5 -$as_echo "$gdb_cv_thread_db_h_has_td_version" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_struct_lwp" >&5 +$as_echo "$gdb_cv_struct_lwp" >&6; } +if test "$gdb_cv_struct_lwp" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether has TD_NOTLS" >&5 -$as_echo_n "checking whether has TD_NOTLS... " >&6; } -if ${gdb_cv_thread_db_h_has_td_notls+:} false; then : +$as_echo "#define HAVE_STRUCT_LWP 1" >>confdefs.h + +fi + +# See if degines `struct reg'. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct reg in machine/reg.h" >&5 +$as_echo_n "checking for struct reg in machine/reg.h... " >&6; } +if ${gdb_cv_struct_reg+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include +#include + #include int main () { -int i = TD_NOTLS; +struct reg r; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - gdb_cv_thread_db_h_has_td_notls=yes + gdb_cv_struct_reg=yes else - gdb_cv_thread_db_h_has_td_notls=no + gdb_cv_struct_reg=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_thread_db_h_has_td_notls" >&5 -$as_echo "$gdb_cv_thread_db_h_has_td_notls" >&6; } -fi -if test "x$gdb_cv_thread_db_h_has_td_notalloc" = "xyes"; then - -$as_echo "#define THREAD_DB_HAS_TD_NOTALLOC 1" >>confdefs.h - -fi -if test "x$gdb_cv_thread_db_h_has_td_version" = "xyes"; then - -$as_echo "#define THREAD_DB_HAS_TD_VERSION 1" >>confdefs.h - -fi -if test "x$gdb_cv_thread_db_h_has_td_notls" = "xyes"; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_struct_reg" >&5 +$as_echo "$gdb_cv_struct_reg" >&6; } +if test "$gdb_cv_struct_reg" = yes; then -$as_echo "#define THREAD_DB_HAS_TD_NOTLS 1" >>confdefs.h +$as_echo "#define HAVE_STRUCT_REG 1" >>confdefs.h fi -case $host_os in - go32* | *djgpp*) - gdbinit=gdb.ini - ;; - *) - gdbinit=.gdbinit - ;; -esac - -cat >>confdefs.h <<_ACEOF -#define GDBINIT "$gdbinit" -_ACEOF - - +# See if supports the %fs and %gs i386 segment registers. +# Older i386 BSD's don't have the r_fs and r_gs members of `struct reg'. +ac_fn_c_check_member "$LINENO" "struct reg" "r_fs" "ac_cv_member_struct_reg_r_fs" "#include +#include +" +if test "x$ac_cv_member_struct_reg_r_fs" = xyes; then : cat >>confdefs.h <<_ACEOF -#define GDBEARLYINIT ".gdbearlyinit" +#define HAVE_STRUCT_REG_R_FS 1 _ACEOF - -# Support for --with-sysroot is a copy of GDB_AC_WITH_DIR, -# except that the argument to --with-sysroot is optional. -# --with-sysroot (or --with-sysroot=yes) sets the default sysroot path. -if test "x$with_sysroot" = xyes; then - with_sysroot="${exec_prefix}/${target_alias}/sys-root" -fi - -# Check whether --with-sysroot was given. -if test "${with_sysroot+set}" = set; then : - withval=$with_sysroot; TARGET_SYSTEM_ROOT=$withval -else - TARGET_SYSTEM_ROOT= fi - - - test "x$prefix" = xNONE && prefix="$ac_default_prefix" - test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - ac_define_dir=`eval echo $TARGET_SYSTEM_ROOT` - ac_define_dir=`eval echo $ac_define_dir` +ac_fn_c_check_member "$LINENO" "struct reg" "r_gs" "ac_cv_member_struct_reg_r_gs" "#include +#include +" +if test "x$ac_cv_member_struct_reg_r_gs" = xyes; then : cat >>confdefs.h <<_ACEOF -#define TARGET_SYSTEM_ROOT "$ac_define_dir" +#define HAVE_STRUCT_REG_R_GS 1 _ACEOF +fi - if test "x$exec_prefix" = xNONE || test "x$exec_prefix" = 'x${prefix}'; then - if test "x$prefix" = xNONE; then - test_prefix=/usr/local - else - test_prefix=$prefix - fi - else - test_prefix=$exec_prefix - fi - value=0 - case ${ac_define_dir} in - "${test_prefix}"|"${test_prefix}/"*|\ - '${exec_prefix}'|'${exec_prefix}/'*) - value=1 - ;; - esac - -cat >>confdefs.h <<_ACEOF -#define TARGET_SYSTEM_ROOT_RELOCATABLE $value +# See if provides the PTRACE_GETREGS request. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTRACE_GETREGS" >&5 +$as_echo_n "checking for PTRACE_GETREGS... " >&6; } +if ${gdb_cv_have_ptrace_getregs+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +PTRACE_GETREGS; + ; + return 0; +} _ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gdb_cv_have_ptrace_getregs=yes +else + gdb_cv_have_ptrace_getregs=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_have_ptrace_getregs" >&5 +$as_echo "$gdb_cv_have_ptrace_getregs" >&6; } +if test "$gdb_cv_have_ptrace_getregs" = yes; then +$as_echo "#define HAVE_PTRACE_GETREGS 1" >>confdefs.h -# Check whether --with-system-gdbinit was given. -if test "${with_system_gdbinit+set}" = set; then : - withval=$with_system_gdbinit; - SYSTEM_GDBINIT=$withval -else - SYSTEM_GDBINIT= fi +# See if provides the PTRACE_GETFPXREGS request. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTRACE_GETFPXREGS" >&5 +$as_echo_n "checking for PTRACE_GETFPXREGS... " >&6; } +if ${gdb_cv_have_ptrace_getfpxregs+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +PTRACE_GETFPXREGS; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gdb_cv_have_ptrace_getfpxregs=yes +else + gdb_cv_have_ptrace_getfpxregs=no - test "x$prefix" = xNONE && prefix="$ac_default_prefix" - test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - ac_define_dir=`eval echo $SYSTEM_GDBINIT` - ac_define_dir=`eval echo $ac_define_dir` +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -cat >>confdefs.h <<_ACEOF -#define SYSTEM_GDBINIT "$ac_define_dir" -_ACEOF +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_have_ptrace_getfpxregs" >&5 +$as_echo "$gdb_cv_have_ptrace_getfpxregs" >&6; } +if test "$gdb_cv_have_ptrace_getfpxregs" = yes; then +$as_echo "#define HAVE_PTRACE_GETFPXREGS 1" >>confdefs.h +fi - if test "x$exec_prefix" = xNONE || test "x$exec_prefix" = 'x${prefix}'; then - if test "x$prefix" = xNONE; then - test_prefix=/usr/local - else - test_prefix=$prefix - fi - else - test_prefix=$exec_prefix - fi - value=0 - case ${ac_define_dir} in - "${test_prefix}"|"${test_prefix}/"*|\ - '${exec_prefix}'|'${exec_prefix}/'*) - value=1 - ;; - esac +# See if provides the PT_GETDBREGS request. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PT_GETDBREGS" >&5 +$as_echo_n "checking for PT_GETDBREGS... " >&6; } +if ${gdb_cv_have_pt_getdbregs+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include +int +main () +{ +PT_GETDBREGS; -cat >>confdefs.h <<_ACEOF -#define SYSTEM_GDBINIT_RELOCATABLE $value + ; + return 0; +} _ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gdb_cv_have_pt_getdbregs=yes +else + gdb_cv_have_pt_getdbregs=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_have_pt_getdbregs" >&5 +$as_echo "$gdb_cv_have_pt_getdbregs" >&6; } +if test "$gdb_cv_have_pt_getdbregs" = yes; then +$as_echo "#define HAVE_PT_GETDBREGS 1" >>confdefs.h -# Check whether --with-system-gdbinit-dir was given. -if test "${with_system_gdbinit_dir+set}" = set; then : - withval=$with_system_gdbinit_dir; - SYSTEM_GDBINIT_DIR=$withval -else - SYSTEM_GDBINIT_DIR= fi - - test "x$prefix" = xNONE && prefix="$ac_default_prefix" - test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - ac_define_dir=`eval echo $SYSTEM_GDBINIT_DIR` - ac_define_dir=`eval echo $ac_define_dir` +# See if supports LWP names on FreeBSD +# Older FreeBSD versions don't have the pl_tdname member of +# `struct ptrace_lwpinfo'. +ac_fn_c_check_member "$LINENO" "struct ptrace_lwpinfo" "pl_tdname" "ac_cv_member_struct_ptrace_lwpinfo_pl_tdname" "#include +" +if test "x$ac_cv_member_struct_ptrace_lwpinfo_pl_tdname" = xyes; then : cat >>confdefs.h <<_ACEOF -#define SYSTEM_GDBINIT_DIR "$ac_define_dir" +#define HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME 1 _ACEOF +fi - if test "x$exec_prefix" = xNONE || test "x$exec_prefix" = 'x${prefix}'; then - if test "x$prefix" = xNONE; then - test_prefix=/usr/local - else - test_prefix=$prefix - fi - else - test_prefix=$exec_prefix - fi - value=0 - case ${ac_define_dir} in - "${test_prefix}"|"${test_prefix}/"*|\ - '${exec_prefix}'|'${exec_prefix}/'*) - value=1 - ;; - esac +# See if supports syscall fields on FreeBSD. The +# pl_syscall_code member of `struct ptrace_lwpinfo' was added in +# FreeBSD 10.3. +ac_fn_c_check_member "$LINENO" "struct ptrace_lwpinfo" "pl_syscall_code" "ac_cv_member_struct_ptrace_lwpinfo_pl_syscall_code" "#include +" +if test "x$ac_cv_member_struct_ptrace_lwpinfo_pl_syscall_code" = xyes; then : cat >>confdefs.h <<_ACEOF -#define SYSTEM_GDBINIT_DIR_RELOCATABLE $value +#define HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE 1 _ACEOF +fi +# Check if the compiler supports the `long long' type. - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking the compiler type" >&5 -$as_echo_n "checking the compiler type... " >&6; } -if ${gdb_cv_compiler_type+:} false; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long support in compiler" >&5 +$as_echo_n "checking for long long support in compiler... " >&6; } +if ${gdb_cv_c_long_long+:} false; then : $as_echo_n "(cached) " >&6 else - gdb_cv_compiler_type=unknown - if test "$gdb_cv_compiler_type" = unknown; then - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - +extern long long foo; int main () { - - #if !defined __GNUC__ || defined __clang__ - #error not gcc - #endif - +switch (foo & 2) { case 0: return 1; } ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - gdb_cv_compiler_type=gcc + gdb_cv_c_long_long=yes +else + gdb_cv_c_long_long=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_c_long_long" >&5 +$as_echo "$gdb_cv_c_long_long" >&6; } +if test "$gdb_cv_c_long_long" != yes; then + # libdecnumber requires long long. + as_fn_error $? "Compiler must support long long for GDB." "$LINENO" 5 +fi - if test "$gdb_cv_compiler_type" = unknown; then - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +# Check if the compiler and runtime support printing decfloats. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for decfloat support in printf" >&5 +$as_echo_n "checking for decfloat support in printf... " >&6; } +if ${gdb_cv_printf_has_decfloat+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + gdb_cv_printf_has_decfloat=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default int main () { - - #ifndef __clang__ - #error not clang - #endif - +char buf[64]; + _Decimal32 d32 = 1.2345df; + _Decimal64 d64 = 1.2345dd; + _Decimal128 d128 = 1.2345dl; + sprintf (buf, "Decimal32: %H\nDecimal64: %D\nDecimal128: %DD", d32, d64, d128); + return (strcmp ("Decimal32: 1.2345\nDecimal64: 1.2345\nDecimal128: 1.2345", buf)); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - gdb_cv_compiler_type=clang +if ac_fn_c_try_run "$LINENO"; then : + gdb_cv_printf_has_decfloat=yes +else + gdb_cv_printf_has_decfloat=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_compiler_type" >&5 -$as_echo "$gdb_cv_compiler_type" >&6; } - GDB_COMPILER_TYPE="$gdb_cv_compiler_type" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_printf_has_decfloat" >&5 +$as_echo "$gdb_cv_printf_has_decfloat" >&6; } +if test "$gdb_cv_printf_has_decfloat" = yes; then +$as_echo "#define PRINTF_HAS_DECFLOAT 1" >>confdefs.h -# Check whether --enable-werror was given. -if test "${enable_werror+set}" = set; then : - enableval=$enable_werror; case "${enableval}" in - yes | y) ERROR_ON_WARNING="yes" ;; - no | n) ERROR_ON_WARNING="no" ;; - *) as_fn_error $? "bad value ${enableval} for --enable-werror" "$LINENO" 5 ;; - esac fi +# Check if the compiler supports the `long double' type. We can't use +# AC_C_LONG_DOUBLE because that one does additional checks on the +# constants defined in that fail on some systems, +# e.g. FreeBSD/i386 4.7 and OpenBSD/i386 3.6. -# Enable -Werror by default when using gcc. Turn it off for releases. -if test "${GCC}" = yes -a -z "${ERROR_ON_WARNING}" && $development; then - ERROR_ON_WARNING=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for long double support in compiler" >&5 +$as_echo_n "checking for long double support in compiler... " >&6; } +if ${gdb_cv_c_long_double+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +long double foo; +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gdb_cv_c_long_double=yes +else + gdb_cv_c_long_double=no fi - -WERROR_CFLAGS="" -if test "${ERROR_ON_WARNING}" = yes ; then - WERROR_CFLAGS="-Werror" +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_c_long_double" >&5 +$as_echo "$gdb_cv_c_long_double" >&6; } +if test "$gdb_cv_c_long_double" = yes; then -# The options we'll try to enable. -build_warnings="-Wall -Wpointer-arith \ --Wno-unused -Wunused-value -Wunused-variable -Wunused-function \ --Wno-switch -Wno-char-subscripts \ --Wempty-body -Wunused-but-set-parameter -Wunused-but-set-variable \ --Wno-sign-compare -Wno-error=maybe-uninitialized \ --Wno-mismatched-tags \ --Wno-error=deprecated-register \ --Wsuggest-override \ --Wimplicit-fallthrough=3 \ --Wduplicated-cond \ --Wshadow=local \ --Wdeprecated-copy \ --Wdeprecated-copy-dtor \ --Wredundant-move \ --Wmissing-declarations \ --Wstrict-null-sentinel \ -" +$as_echo "#define HAVE_LONG_DOUBLE 1" >>confdefs.h -# The -Wmissing-prototypes flag will be accepted by GCC, but results -# in a warning being printed about the flag not being valid for C++, -# this is something to do with using ccache, and argument ordering. -if test "$GDB_COMPILER_TYPE" != gcc; then - build_warnings="$build_warnings -Wmissing-prototypes" fi -case "${host}" in - *-*-mingw32*) - # Enable -Wno-format by default when using gcc on mingw since many - # GCC versions complain about %I64. - build_warnings="$build_warnings -Wno-format" ;; - *-*-solaris*) - # Solaris 11.4 uses #pragma no_inline that GCC - # doesn't understand. - build_warnings="$build_warnings -Wno-unknown-pragmas" - # Solaris 11 marks vfork deprecated. - build_warnings="$build_warnings -Wno-deprecated-declarations" ;; - *) - # Note that gcc requires -Wformat for -Wformat-nonliteral to work, - # but there's a special case for this below. - build_warnings="$build_warnings -Wformat-nonliteral" ;; -esac +# Check if the compiler and runtime support printing long doubles. -# Check whether --enable-build-warnings was given. -if test "${enable_build_warnings+set}" = set; then : - enableval=$enable_build_warnings; case "${enableval}" in - yes) ;; - no) build_warnings="-w";; - ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"` - build_warnings="${build_warnings} ${t}";; - *,) t=`echo "${enableval}" | sed -e "s/,/ /g"` - build_warnings="${t} ${build_warnings}";; - *) build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;; -esac -if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then - echo "Setting compiler warning flags = $build_warnings" 6>&1 -fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for long double support in printf" >&5 +$as_echo_n "checking for long double support in printf... " >&6; } +if ${gdb_cv_printf_has_long_double+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + gdb_cv_printf_has_long_double=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +char buf[16]; + long double f = 3.141592653; + sprintf (buf, "%Lg", f); + return (strncmp ("3.14159", buf, 7)); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + gdb_cv_printf_has_long_double=yes +else + gdb_cv_printf_has_long_double=no fi -# Check whether --enable-gdb-build-warnings was given. -if test "${enable_gdb_build_warnings+set}" = set; then : - enableval=$enable_gdb_build_warnings; case "${enableval}" in - yes) ;; - no) build_warnings="-w";; - ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"` - build_warnings="${build_warnings} ${t}";; - *,) t=`echo "${enableval}" | sed -e "s/,/ /g"` - build_warnings="${t} ${build_warnings}";; - *) build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;; -esac -if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then - echo "Setting GDB specific compiler warning flags = $build_warnings" 6>&1 +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext fi + fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_printf_has_long_double" >&5 +$as_echo "$gdb_cv_printf_has_long_double" >&6; } +if test "$gdb_cv_printf_has_long_double" = yes; then -# The set of warnings supported by a C++ compiler is not the same as -# of the C compiler. -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +$as_echo "#define PRINTF_HAS_LONG_DOUBLE 1" >>confdefs.h +fi -WARN_CFLAGS="" -if test "x${build_warnings}" != x -a "x$GCC" = xyes -then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler warning flags" >&5 -$as_echo_n "checking compiler warning flags... " >&6; } - # Separate out the -Werror flag as some files just cannot be - # compiled with it enabled. - for w in ${build_warnings}; do - # GCC does not complain about -Wno-unknown-warning. Invert - # and test -Wunknown-warning instead. - case $w in - -Wno-*) - wtest=`echo $w | sed 's/-Wno-/-W/g'` ;; - -Wformat-nonliteral) - # gcc requires -Wformat before -Wformat-nonliteral - # will work, so stick them together. - w="-Wformat $w" - wtest="$w" - ;; - *) - wtest=$w ;; - esac +# Check if the compiler and runtime support scanning long doubles. - case $w in - -Werr*) WERROR_CFLAGS=-Werror ;; - *) - # Check whether GCC accepts it. - saved_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Werror $wtest" - saved_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$CXXFLAGS -Werror $wtest" - if test "x$w" = "x-Wunused-variable"; then - # Check for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=38958, - # fixed in GCC 4.9. This test is derived from the gdb - # source code that triggered this bug in GCC. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for long double support in scanf" >&5 +$as_echo_n "checking for long double support in scanf... " >&6; } +if ${gdb_cv_scanf_has_long_double+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + gdb_cv_scanf_has_long_double=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -struct scoped_restore_base {}; - struct scoped_restore_tmpl : public scoped_restore_base { - ~scoped_restore_tmpl() {} - }; +#include int main () { -const scoped_restore_base &b = scoped_restore_tmpl(); - +char *buf = "3.141592653"; + long double f = 0; + sscanf (buf, "%Lg", &f); + return !(f > 3.14159 && f < 3.14160); ; return 0; } _ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - WARN_CFLAGS="${WARN_CFLAGS} $w" +if ac_fn_c_try_run "$LINENO"; then : + gdb_cv_scanf_has_long_double=yes +else + gdb_cv_scanf_has_long_double=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_scanf_has_long_double" >&5 +$as_echo "$gdb_cv_scanf_has_long_double" >&6; } +if test "$gdb_cv_scanf_has_long_double" = yes; then + +$as_echo "#define SCANF_HAS_LONG_DOUBLE 1" >>confdefs.h + +fi + +case ${host_os} in +aix*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -bbigtoc option" >&5 +$as_echo_n "checking for -bbigtoc option... " >&6; } +if ${gdb_cv_bigtoc+:} false; then : + $as_echo_n "(cached) " >&6 +else + SAVE_LDFLAGS=$LDFLAGS + + case $GCC in + yes) gdb_cv_bigtoc=-Wl,-bbigtoc ;; + *) gdb_cv_bigtoc=-bbigtoc ;; + esac + + LDFLAGS=$LDFLAGS\ $gdb_cv_bigtoc + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { - +int i; ; return 0; } _ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - WARN_CFLAGS="${WARN_CFLAGS} $w" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - CFLAGS="$saved_CFLAGS" - CXXFLAGS="$saved_CXXFLAGS" - esac - done - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${WARN_CFLAGS} ${WERROR_CFLAGS}" >&5 -$as_echo "${WARN_CFLAGS} ${WERROR_CFLAGS}" >&6; } -fi +if ac_fn_c_try_link "$LINENO"; then : +else + gdb_cv_bigtoc= +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="${SAVE_LDFLAGS}" -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_bigtoc" >&5 +$as_echo "$gdb_cv_bigtoc" >&6; } + CONFIG_LDFLAGS="${CONFIG_LDFLAGS} ${gdb_cv_bigtoc}" + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the dynamic export flag" >&5 +$as_echo_n "checking for the dynamic export flag... " >&6; } +dynamic_list=false +if test "${gdb_native}" = yes; then + # The dynamically loaded libthread_db needs access to symbols in the gdb + # executable. Older GNU ld supports --export-dynamic but --dynamic-list + # may not be supported there. + old_LDFLAGS="$LDFLAGS" + # Older GNU ld supports --export-dynamic but --dynamic-list it does not. + RDYNAMIC="-Wl,--dynamic-list=${srcdir}/proc-service.list" + LDFLAGS="$LDFLAGS $RDYNAMIC" + if test "${have_libpython}" = no; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int +main () +{ -# Check whether --enable-ubsan was given. -if test "${enable_ubsan+set}" = set; then : - enableval=$enable_ubsan; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + dynamic_list=true +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + else + # Workaround http://bugs.python.org/issue4434 where static + # libpythonX.Y.a would get its symbols required for + # pythonX.Y/lib-dynload/*.so modules hidden by -Wl,--dynamic-list. + # Problem does not happen for the recommended libpythonX.Y.so linkage. + + # Note the workaround for Python + # http://bugs.python.org/issue10112 earlier has removed + # -export-dynamic from PYTHON_LIBS. That's exactly what we want + # here too, as otherwise it'd make this -Wl,--dynamic-list test + # always pass. + old_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PYTHON_CFLAGS" + old_LIBS="$LIBS" + LIBS="$LIBS $PYTHON_LIBS" + old_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $PYTHON_CPPFLAGS" + if test "$cross_compiling" = yes; then : + true else - enable_ubsan=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include "Python.h" +int +main () +{ +int err; + Py_Initialize (); + err = PyRun_SimpleString ("import ctypes\n"); + Py_Finalize (); + return err == 0 ? 0 : 1; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + dynamic_list=true +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext fi -if test "x$enable_ubsan" = xauto; then - if $development; then - enable_ubsan=yes - fi + LIBS="$old_LIBS" + CFLAGS="$old_CFLAGS" + CPPFLAGS="$old_CPPFLAGS" + fi + LDFLAGS="$old_LDFLAGS" fi -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if $dynamic_list; then + found="-Wl,--dynamic-list" + RDYNAMIC='-Wl,--dynamic-list=$(srcdir)/proc-service.list' +else + found="-rdynamic" + RDYNAMIC="-rdynamic" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $found" >&5 +$as_echo "$found" >&6; } -if test "x$enable_ubsan" = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -fsanitize=undefined is accepted" >&5 -$as_echo_n "checking whether -fsanitize=undefined is accepted... " >&6; } - saved_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$CXXFLAGS -fsanitize=undefined -fno-sanitize-recover=undefined" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether execinfo.h backtrace is available" >&5 +$as_echo_n "checking whether execinfo.h backtrace is available... " >&6; } +if ${gdb_cv_execinfo_backtrace+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ + #include + int main () { + int f; + void *b[2]; + f = backtrace (b, 2); + backtrace_symbols_fd (b, f, 2); + ; return 0; } _ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - enable_ubsan=yes +if ac_fn_c_try_link "$LINENO"; then : + gdb_cv_execinfo_backtrace=yes else - enable_ubsan=no - + gdb_cv_execinfo_backtrace=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext - CXXFLAGS="$saved_CXXFLAGS" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_ubsan" >&5 -$as_echo "$enable_ubsan" >&6; } - if test "x$enable_ubsan" = xyes; then - WARN_CFLAGS="$WARN_CFLAGS -fsanitize=undefined -fno-sanitize-recover=undefined" - CONFIG_LDFLAGS="$CONFIG_LDFLAGS -fsanitize=undefined" - fi fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_execinfo_backtrace" >&5 +$as_echo "$gdb_cv_execinfo_backtrace" >&6; } +if test "$gdb_cv_execinfo_backtrace" = yes; then +$as_echo "#define HAVE_EXECINFO_BACKTRACE 1" >>confdefs.h +fi -# In the Cygwin environment, we need some additional flags. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cygwin" >&5 -$as_echo_n "checking for cygwin... " >&6; } -if ${gdb_cv_os_cygwin+:} false; then : + +if test "${build}" = "${host}" -a "${host}" = "${target}" ; then + case ${host_os} in + aix*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for AiX thread debugging library" >&5 +$as_echo_n "checking for AiX thread debugging library... " >&6; } + if ${gdb_cv_have_aix_thread_debug+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +#include +int +main () +{ +#ifndef PTHDB_VERSION_3 + #error + #endif -#if defined (__CYGWIN__) || defined (__CYGWIN32__) -lose -#endif + ; + return 0; +} _ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "^lose$" >/dev/null 2>&1; then : - gdb_cv_os_cygwin=yes +if ac_fn_c_try_compile "$LINENO"; then : + gdb_cv_have_aix_thread_debug=yes else - gdb_cv_os_cygwin=no -fi -rm -f conftest* + gdb_cv_have_aix_thread_debug=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_os_cygwin" >&5 -$as_echo "$gdb_cv_os_cygwin" >&6; } - +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -SER_HARDWIRE="ser-base.o ser-unix.o ser-pipe.o ser-tcp.o" -case ${host} in - *go32* ) SER_HARDWIRE=ser-go32.o ;; - *djgpp* ) SER_HARDWIRE=ser-go32.o ;; - *mingw32*) SER_HARDWIRE="ser-base.o ser-tcp.o ser-mingw.o" ;; - *) SER_HARDWIRE="$SER_HARDWIRE ser-uds.o" ;; -esac +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_have_aix_thread_debug" >&5 +$as_echo "$gdb_cv_have_aix_thread_debug" >&6; } + if test "$gdb_cv_have_aix_thread_debug" = yes; then + CONFIG_SRCS="${CONFIG_SRCS} aix-thread.c" + CONFIG_OBS="${CONFIG_OBS} aix-thread.o" + LIBS="$LIBS -lpthdebug" -# libreadline needs libuser32.a in a cygwin environment -WIN32LIBS= -if test x"$gdb_cv_os_cygwin" = xyes; then - WIN32LIBS="-luser32" - case "${target}" in - *cygwin*) WIN32LIBS="$WIN32LIBS -limagehlp" - ;; - esac + # Older versions of AIX do not provide the declaration for + # the getthrds function (it appears that it was introduced + # with AIX 6.x). + ac_fn_c_check_decl "$LINENO" "getthrds" "ac_cv_have_decl_getthrds" "#include +" +if test "x$ac_cv_have_decl_getthrds" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 fi -# The ser-tcp.c module requires sockets. -# Note that WIN32APILIBS is set by GDB_AC_COMMON. -WIN32LIBS="$WIN32LIBS $WIN32APILIBS" +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_GETTHRDS $ac_have_decl +_ACEOF -# Add ELF support to GDB, but only if BFD includes ELF support. + fi + ;; + esac - OLD_CFLAGS=$CFLAGS - OLD_LDFLAGS=$LDFLAGS - OLD_LIBS=$LIBS - OLD_CC=$CC - # Put the old CFLAGS/LDFLAGS last, in case the user's (C|LD)FLAGS - # points somewhere with bfd, with -I/foo/lib and -L/foo/lib. We - # always want our bfd. - CFLAGS="-I${srcdir}/../include -I../bfd -I${srcdir}/../bfd $CFLAGS" - LDFLAGS="-L../bfd -L../libiberty" - intl=`echo $LIBINTL | sed 's,${top_builddir}/,,g'` - LIBS="-lbfd -liberty $intl $LIBS" - CC="./libtool --quiet --mode=link $CC" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ELF support in BFD" >&5 -$as_echo_n "checking for ELF support in BFD... " >&6; } -if ${gdb_cv_var_elf+:} false; then : +fi + +if test "x$ac_cv_header_thread_db_h" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether has TD_NOTALLOC" >&5 +$as_echo_n "checking whether has TD_NOTALLOC... " >&6; } +if ${gdb_cv_thread_db_h_has_td_notalloc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include - #include - #include "bfd.h" - #include "elf-bfd.h" +#include int main () { -return bfd_get_elf_phdr_upper_bound (NULL); +int i = TD_NOTALLOC; ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - gdb_cv_var_elf=yes +if ac_fn_c_try_compile "$LINENO"; then : + gdb_cv_thread_db_h_has_td_notalloc=yes else - gdb_cv_var_elf=no + gdb_cv_thread_db_h_has_td_notalloc=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_var_elf" >&5 -$as_echo "$gdb_cv_var_elf" >&6; } - CC=$OLD_CC - CFLAGS=$OLD_CFLAGS - LDFLAGS=$OLD_LDFLAGS - LIBS=$OLD_LIBS -if test "$gdb_cv_var_elf" = yes; then - CONFIG_OBS="$CONFIG_OBS elfread.o stap-probe.o dtrace-probe.o \ - gcore-elf.o elf-none-tdep.o" - -$as_echo "#define HAVE_ELF 1" >>confdefs.h +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_thread_db_h_has_td_notalloc" >&5 +$as_echo "$gdb_cv_thread_db_h_has_td_notalloc" >&6; } - # -ldl is provided by bfd/Makfile.am (LIBDL) . - if test "$plugins" = "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 -$as_echo_n "checking for library containing dlopen... " >&6; } -if ${ac_cv_search_dlopen+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether has TD_VERSION" >&5 +$as_echo_n "checking whether has TD_VERSION... " >&6; } +if ${gdb_cv_thread_db_h_has_td_version+:} false; then : $as_echo_n "(cached) " >&6 else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); +#include int main () { -return dlopen (); +int i = TD_VERSION; + ; return 0; } _ACEOF -for ac_lib in '' dl; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_dlopen=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_dlopen+:} false; then : - break -fi -done -if ${ac_cv_search_dlopen+:} false; then : - +if ac_fn_c_try_compile "$LINENO"; then : + gdb_cv_thread_db_h_has_td_version=yes else - ac_cv_search_dlopen=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 -$as_echo "$ac_cv_search_dlopen" >&6; } -ac_res=$ac_cv_search_dlopen -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + gdb_cv_thread_db_h_has_td_version=no fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_thread_db_h_has_td_version" >&5 +$as_echo "$gdb_cv_thread_db_h_has_td_version" >&6; } -# Add macho support to GDB, but only if BFD includes it. - - OLD_CFLAGS=$CFLAGS - OLD_LDFLAGS=$LDFLAGS - OLD_LIBS=$LIBS - OLD_CC=$CC - # Put the old CFLAGS/LDFLAGS last, in case the user's (C|LD)FLAGS - # points somewhere with bfd, with -I/foo/lib and -L/foo/lib. We - # always want our bfd. - CFLAGS="-I${srcdir}/../include -I../bfd -I${srcdir}/../bfd $CFLAGS" - LDFLAGS="-L../bfd -L../libiberty" - intl=`echo $LIBINTL | sed 's,${top_builddir}/,,g'` - LIBS="-lbfd -liberty $intl $LIBS" - CC="./libtool --quiet --mode=link $CC" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Mach-O support in BFD" >&5 -$as_echo_n "checking for Mach-O support in BFD... " >&6; } -if ${gdb_cv_var_macho+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether has TD_NOTLS" >&5 +$as_echo_n "checking whether has TD_NOTLS... " >&6; } +if ${gdb_cv_thread_db_h_has_td_notls+:} false; then : $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - #include - #include "bfd.h" - #include "mach-o.h" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include int main () { -return bfd_mach_o_lookup_command (NULL, 0, NULL); +int i = TD_NOTLS; ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - gdb_cv_var_macho=yes +if ac_fn_c_try_compile "$LINENO"; then : + gdb_cv_thread_db_h_has_td_notls=yes else - gdb_cv_var_macho=no + gdb_cv_thread_db_h_has_td_notls=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_var_macho" >&5 -$as_echo "$gdb_cv_var_macho" >&6; } - CC=$OLD_CC - CFLAGS=$OLD_CFLAGS - LDFLAGS=$OLD_LDFLAGS - LIBS=$OLD_LIBS -if test "$gdb_cv_var_macho" = yes; then - CONFIG_OBS="$CONFIG_OBS machoread.o" +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_thread_db_h_has_td_notls" >&5 +$as_echo "$gdb_cv_thread_db_h_has_td_notls" >&6; } fi +if test "x$gdb_cv_thread_db_h_has_td_notalloc" = "xyes"; then -# Add any host-specific objects to GDB. -CONFIG_OBS="${CONFIG_OBS} ${gdb_host_obs}" - -# If building on ELF, look for lzma support for embedded compressed debug info. -if test "$gdb_cv_var_elf" = yes; then +$as_echo "#define THREAD_DB_HAS_TD_NOTALLOC 1" >>confdefs.h -# Check whether --with-lzma was given. -if test "${with_lzma+set}" = set; then : - withval=$with_lzma; -else - with_lzma=auto fi +if test "x$gdb_cv_thread_db_h_has_td_version" = "xyes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use lzma" >&5 -$as_echo_n "checking whether to use lzma... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_lzma" >&5 -$as_echo "$with_lzma" >&6; } - - if test "${with_lzma}" != no; then - - - - - - - +$as_echo "#define THREAD_DB_HAS_TD_VERSION 1" >>confdefs.h - use_additional=yes +fi +if test "x$gdb_cv_thread_db_h_has_td_notls" = "xyes"; then - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" +$as_echo "#define THREAD_DB_HAS_TD_NOTLS 1" >>confdefs.h - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" +fi - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" +case $host_os in + go32* | *djgpp*) + gdbinit=gdb.ini + ;; + *) + gdbinit=.gdbinit + ;; +esac +cat >>confdefs.h <<_ACEOF +#define GDBINIT "$gdbinit" +_ACEOF -# Check whether --with-liblzma-prefix was given. -if test "${with_liblzma_prefix+set}" = set; then : - withval=$with_liblzma_prefix; - if test "X$withval" = "Xno"; then - use_additional=no - else - if test "X$withval" = "X"; then - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" +cat >>confdefs.h <<_ACEOF +#define GDBEARLYINIT ".gdbearlyinit" +_ACEOF - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - else - additional_includedir="$withval/include" - additional_libdir="$withval/lib" - fi - fi +# Support for --with-sysroot is a copy of GDB_AC_WITH_DIR, +# except that the argument to --with-sysroot is optional. +# --with-sysroot (or --with-sysroot=yes) sets the default sysroot path. +if test "x$with_sysroot" = xyes; then + with_sysroot="${exec_prefix}/${target_alias}/sys-root" fi - -# Check whether --with-liblzma-type was given. -if test "${with_liblzma_type+set}" = set; then : - withval=$with_liblzma_type; with_liblzma_type=$withval +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; TARGET_SYSTEM_ROOT=$withval else - with_liblzma_type=auto + TARGET_SYSTEM_ROOT= fi - lib_type=`eval echo \$with_liblzma_type` - LIBLZMA= - LTLIBLZMA= - INCLZMA= - rpathdirs= - ltrpathdirs= - names_already_handled= - names_next_round='lzma ' - while test -n "$names_next_round"; do - names_this_round="$names_next_round" - names_next_round= - for name in $names_this_round; do - already_handled= - for n in $names_already_handled; do - if test "$n" = "$name"; then - already_handled=yes - break - fi - done - if test -z "$already_handled"; then - names_already_handled="$names_already_handled $name" - uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` - eval value=\"\$HAVE_LIB$uppername\" - if test -n "$value"; then - if test "$value" = yes; then - eval value=\"\$LIB$uppername\" - test -z "$value" || LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$value" - eval value=\"\$LTLIB$uppername\" - test -z "$value" || LTLIBLZMA="${LTLIBLZMA}${LTLIBLZMA:+ }$value" - else - : - fi - else - found_dir= - found_la= - found_so= - found_a= - if test $use_additional = yes; then - if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext" && test x$lib_type != xstatic; then - found_dir="$additional_libdir" - found_so="$additional_libdir/lib$name.$shlibext" - if test -f "$additional_libdir/lib$name.la"; then - found_la="$additional_libdir/lib$name.la" - fi - elif test x$lib_type != xshared; then - if test -f "$additional_libdir/lib$name.$libext"; then - found_dir="$additional_libdir" - found_a="$additional_libdir/lib$name.$libext" - if test -f "$additional_libdir/lib$name.la"; then - found_la="$additional_libdir/lib$name.la" - fi - fi - fi - fi - if test "X$found_dir" = "X"; then - for x in $LDFLAGS $LTLIBLZMA; do + test "x$prefix" = xNONE && prefix="$ac_default_prefix" + test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + ac_define_dir=`eval echo $TARGET_SYSTEM_ROOT` + ac_define_dir=`eval echo $ac_define_dir` - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" +cat >>confdefs.h <<_ACEOF +#define TARGET_SYSTEM_ROOT "$ac_define_dir" +_ACEOF - case "$x" in - -L*) - dir=`echo "X$x" | sed -e 's/^X-L//'` - if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext" && test x$lib_type != xstatic; then - found_dir="$dir" - found_so="$dir/lib$name.$shlibext" - if test -f "$dir/lib$name.la"; then - found_la="$dir/lib$name.la" - fi - elif test x$lib_type != xshared; then - if test -f "$dir/lib$name.$libext"; then - found_dir="$dir" - found_a="$dir/lib$name.$libext" - if test -f "$dir/lib$name.la"; then - found_la="$dir/lib$name.la" - fi - fi - fi - ;; - esac - if test "X$found_dir" != "X"; then - break - fi - done - fi - if test "X$found_dir" != "X"; then - LTLIBLZMA="${LTLIBLZMA}${LTLIBLZMA:+ }-L$found_dir -l$name" - if test "X$found_so" != "X"; then - if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then - LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$found_so" - else - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $found_dir" - fi - if test "$hardcode_direct" = yes; then - LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$found_so" - else - if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then - LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$found_so" - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $found_dir" - fi - else - haveit= - for x in $LDFLAGS $LIBLZMA; do - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - if test "X$x" = "X-L$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - LIBLZMA="${LIBLZMA}${LIBLZMA:+ }-L$found_dir" - fi - if test "$hardcode_minus_L" != no; then - LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$found_so" - else - LIBLZMA="${LIBLZMA}${LIBLZMA:+ }-l$name" - fi - fi - fi - fi - else - if test "X$found_a" != "X"; then - LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$found_a" - else - LIBLZMA="${LIBLZMA}${LIBLZMA:+ }-L$found_dir -l$name" - fi - fi - additional_includedir= - case "$found_dir" in - */lib | */lib/) - basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` - additional_includedir="$basedir/include" - ;; - esac - if test "X$additional_includedir" != "X"; then - if test "X$additional_includedir" != "X/usr/include"; then - haveit= - if test "X$additional_includedir" = "X/usr/local/include"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - for x in $CPPFLAGS $INCLZMA; do - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" + if test "x$exec_prefix" = xNONE || test "x$exec_prefix" = 'x${prefix}'; then + if test "x$prefix" = xNONE; then + test_prefix=/usr/local + else + test_prefix=$prefix + fi + else + test_prefix=$exec_prefix + fi + value=0 + case ${ac_define_dir} in + "${test_prefix}"|"${test_prefix}/"*|\ + '${exec_prefix}'|'${exec_prefix}/'*) + value=1 + ;; + esac + +cat >>confdefs.h <<_ACEOF +#define TARGET_SYSTEM_ROOT_RELOCATABLE $value +_ACEOF + + - if test "X$x" = "X-I$additional_includedir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_includedir"; then - INCLZMA="${INCLZMA}${INCLZMA:+ }-I$additional_includedir" - fi - fi - fi - fi - fi - if test -n "$found_la"; then - save_libdir="$libdir" - case "$found_la" in - */* | *\\*) . "$found_la" ;; - *) . "./$found_la" ;; - esac - libdir="$save_libdir" - for dep in $dependency_libs; do - case "$dep" in - -L*) - additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` - if test "X$additional_libdir" != "X/usr/lib"; then - haveit= - if test "X$additional_libdir" = "X/usr/local/lib"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - haveit= - for x in $LDFLAGS $LIBLZMA; do - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - LIBLZMA="${LIBLZMA}${LIBLZMA:+ }-L$additional_libdir" - fi - fi - haveit= - for x in $LDFLAGS $LTLIBLZMA; do +# Check whether --with-system-gdbinit was given. +if test "${with_system_gdbinit+set}" = set; then : + withval=$with_system_gdbinit; + SYSTEM_GDBINIT=$withval +else + SYSTEM_GDBINIT= +fi - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - LTLIBLZMA="${LTLIBLZMA}${LTLIBLZMA:+ }-L$additional_libdir" - fi - fi - fi - fi - ;; - -R*) - dir=`echo "X$dep" | sed -e 's/^X-R//'` - if test "$enable_rpath" != no; then - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $dir" - fi - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $dir" - fi - fi - ;; - -l*) - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` - ;; - *.la) - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` - ;; - *) - LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$dep" - LTLIBLZMA="${LTLIBLZMA}${LTLIBLZMA:+ }$dep" - ;; - esac - done - fi - else - if test "x$lib_type" = "xauto" || test "x$lib_type" = "xshared"; then - LIBLZMA="${LIBLZMA}${LIBLZMA:+ }-l$name" - LTLIBLZMA="${LTLIBLZMA}${LTLIBLZMA:+ }-l$name" - else - LIBLZMA="${LIBLZMA}${LIBLZMA:+ }-l:lib$name.$libext" - LTLIBLZMA="${LTLIBLZMA}${LTLIBLZMA:+ }-l:lib$name.$libext" - fi - fi - fi - fi - done - done - if test "X$rpathdirs" != "X"; then - if test -n "$hardcode_libdir_separator"; then - alldirs= - for found_dir in $rpathdirs; do - alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" - done - acl_save_libdir="$libdir" - libdir="$alldirs" - eval flag=\"$hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$flag" - else - for found_dir in $rpathdirs; do - acl_save_libdir="$libdir" - libdir="$found_dir" - eval flag=\"$hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$flag" - done - fi + test "x$prefix" = xNONE && prefix="$ac_default_prefix" + test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + ac_define_dir=`eval echo $SYSTEM_GDBINIT` + ac_define_dir=`eval echo $ac_define_dir` + +cat >>confdefs.h <<_ACEOF +#define SYSTEM_GDBINIT "$ac_define_dir" +_ACEOF + + + + + if test "x$exec_prefix" = xNONE || test "x$exec_prefix" = 'x${prefix}'; then + if test "x$prefix" = xNONE; then + test_prefix=/usr/local + else + test_prefix=$prefix + fi + else + test_prefix=$exec_prefix fi - if test "X$ltrpathdirs" != "X"; then - for found_dir in $ltrpathdirs; do - LTLIBLZMA="${LTLIBLZMA}${LTLIBLZMA:+ }-R$found_dir" - done + value=0 + case ${ac_define_dir} in + "${test_prefix}"|"${test_prefix}/"*|\ + '${exec_prefix}'|'${exec_prefix}/'*) + value=1 + ;; + esac + +cat >>confdefs.h <<_ACEOF +#define SYSTEM_GDBINIT_RELOCATABLE $value +_ACEOF + + + + + +# Check whether --with-system-gdbinit-dir was given. +if test "${with_system_gdbinit_dir+set}" = set; then : + withval=$with_system_gdbinit_dir; + SYSTEM_GDBINIT_DIR=$withval +else + SYSTEM_GDBINIT_DIR= +fi + + + test "x$prefix" = xNONE && prefix="$ac_default_prefix" + test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + ac_define_dir=`eval echo $SYSTEM_GDBINIT_DIR` + ac_define_dir=`eval echo $ac_define_dir` + +cat >>confdefs.h <<_ACEOF +#define SYSTEM_GDBINIT_DIR "$ac_define_dir" +_ACEOF + + + + + if test "x$exec_prefix" = xNONE || test "x$exec_prefix" = 'x${prefix}'; then + if test "x$prefix" = xNONE; then + test_prefix=/usr/local + else + test_prefix=$prefix + fi + else + test_prefix=$exec_prefix fi + value=0 + case ${ac_define_dir} in + "${test_prefix}"|"${test_prefix}/"*|\ + '${exec_prefix}'|'${exec_prefix}/'*) + value=1 + ;; + esac +cat >>confdefs.h <<_ACEOF +#define SYSTEM_GDBINIT_DIR_RELOCATABLE $value +_ACEOF - ac_save_CPPFLAGS="$CPPFLAGS" - for element in $INCLZMA; do - haveit= - for x in $CPPFLAGS; do - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - if test "X$x" = "X$element"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" - fi - done - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblzma" >&5 -$as_echo_n "checking for liblzma... " >&6; } -if ${ac_cv_liblzma+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking the compiler type" >&5 +$as_echo_n "checking the compiler type... " >&6; } +if ${gdb_cv_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else + gdb_cv_compiler_type=unknown + if test "$gdb_cv_compiler_type" = unknown; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ - ac_save_LIBS="$LIBS" - LIBS="$LIBS $LIBLZMA" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +int +main () +{ + + #if !defined __GNUC__ || defined __clang__ + #error not gcc + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gdb_cv_compiler_type=gcc +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + + if test "$gdb_cv_compiler_type" = unknown; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + #ifndef __clang__ + #error not clang + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gdb_cv_compiler_type=clang +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_compiler_type" >&5 +$as_echo "$gdb_cv_compiler_type" >&6; } + + GDB_COMPILER_TYPE="$gdb_cv_compiler_type" + + +# Check whether --enable-werror was given. +if test "${enable_werror+set}" = set; then : + enableval=$enable_werror; case "${enableval}" in + yes | y) ERROR_ON_WARNING="yes" ;; + no | n) ERROR_ON_WARNING="no" ;; + *) as_fn_error $? "bad value ${enableval} for --enable-werror" "$LINENO" 5 ;; + esac +fi + + +# Enable -Werror by default when using gcc. Turn it off for releases. +if test "${GCC}" = yes -a -z "${ERROR_ON_WARNING}" && $development; then + ERROR_ON_WARNING=yes +fi + +WERROR_CFLAGS="" +if test "${ERROR_ON_WARNING}" = yes ; then + WERROR_CFLAGS="-Werror" +fi + +# The options we'll try to enable. +build_warnings="-Wall -Wpointer-arith \ +-Wno-unused -Wunused-value -Wunused-variable -Wunused-function \ +-Wno-switch -Wno-char-subscripts \ +-Wempty-body -Wunused-but-set-parameter -Wunused-but-set-variable \ +-Wno-sign-compare -Wno-error=maybe-uninitialized \ +-Wno-mismatched-tags \ +-Wno-error=deprecated-register \ +-Wsuggest-override \ +-Wimplicit-fallthrough=3 \ +-Wduplicated-cond \ +-Wshadow=local \ +-Wdeprecated-copy \ +-Wdeprecated-copy-dtor \ +-Wredundant-move \ +-Wmissing-declarations \ +-Wstrict-null-sentinel \ +" + +# The -Wmissing-prototypes flag will be accepted by GCC, but results +# in a warning being printed about the flag not being valid for C++, +# this is something to do with using ccache, and argument ordering. +if test "$GDB_COMPILER_TYPE" != gcc; then + build_warnings="$build_warnings -Wmissing-prototypes" +fi + +case "${host}" in + *-*-mingw32*) + # Enable -Wno-format by default when using gcc on mingw since many + # GCC versions complain about %I64. + build_warnings="$build_warnings -Wno-format" ;; + *-*-solaris*) + # Solaris 11.4 uses #pragma no_inline that GCC + # doesn't understand. + build_warnings="$build_warnings -Wno-unknown-pragmas" + # Solaris 11 marks vfork deprecated. + build_warnings="$build_warnings -Wno-deprecated-declarations" ;; + *) + # Note that gcc requires -Wformat for -Wformat-nonliteral to work, + # but there's a special case for this below. + build_warnings="$build_warnings -Wformat-nonliteral" ;; +esac + +# Check whether --enable-build-warnings was given. +if test "${enable_build_warnings+set}" = set; then : + enableval=$enable_build_warnings; case "${enableval}" in + yes) ;; + no) build_warnings="-w";; + ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"` + build_warnings="${build_warnings} ${t}";; + *,) t=`echo "${enableval}" | sed -e "s/,/ /g"` + build_warnings="${t} ${build_warnings}";; + *) build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;; +esac +if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then + echo "Setting compiler warning flags = $build_warnings" 6>&1 +fi +fi +# Check whether --enable-gdb-build-warnings was given. +if test "${enable_gdb_build_warnings+set}" = set; then : + enableval=$enable_gdb_build_warnings; case "${enableval}" in + yes) ;; + no) build_warnings="-w";; + ,*) t=`echo "${enableval}" | sed -e "s/,/ /g"` + build_warnings="${build_warnings} ${t}";; + *,) t=`echo "${enableval}" | sed -e "s/,/ /g"` + build_warnings="${t} ${build_warnings}";; + *) build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;; +esac +if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then + echo "Setting GDB specific compiler warning flags = $build_warnings" 6>&1 +fi +fi + +# The set of warnings supported by a C++ compiler is not the same as +# of the C compiler. +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + +WARN_CFLAGS="" +if test "x${build_warnings}" != x -a "x$GCC" = xyes +then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler warning flags" >&5 +$as_echo_n "checking compiler warning flags... " >&6; } + # Separate out the -Werror flag as some files just cannot be + # compiled with it enabled. + for w in ${build_warnings}; do + # GCC does not complain about -Wno-unknown-warning. Invert + # and test -Wunknown-warning instead. + case $w in + -Wno-*) + wtest=`echo $w | sed 's/-Wno-/-W/g'` ;; + -Wformat-nonliteral) + # gcc requires -Wformat before -Wformat-nonliteral + # will work, so stick them together. + w="-Wformat $w" + wtest="$w" + ;; + *) + wtest=$w ;; + esac + + case $w in + -Werr*) WERROR_CFLAGS=-Werror ;; + *) + # Check whether GCC accepts it. + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Werror $wtest" + saved_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS -Werror $wtest" + if test "x$w" = "x-Wunused-variable"; then + # Check for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=38958, + # fixed in GCC 4.9. This test is derived from the gdb + # source code that triggered this bug in GCC. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include "lzma.h" +struct scoped_restore_base {}; + struct scoped_restore_tmpl : public scoped_restore_base { + ~scoped_restore_tmpl() {} + }; int main () { -lzma_index_iter iter; - lzma_index_iter_init (&iter, 0); - lzma_mf_is_supported (LZMA_MF_HC3); +const scoped_restore_base &b = scoped_restore_tmpl(); + ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_liblzma=yes -else - ac_cv_liblzma=no +if ac_fn_cxx_try_compile "$LINENO"; then : + WARN_CFLAGS="${WARN_CFLAGS} $w" fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LIBS="$ac_save_LIBS" +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_liblzma" >&5 -$as_echo "$ac_cv_liblzma" >&6; } - if test "$ac_cv_liblzma" = yes; then - HAVE_LIBLZMA=yes +int +main () +{ -$as_echo "#define HAVE_LIBLZMA 1" >>confdefs.h + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + WARN_CFLAGS="${WARN_CFLAGS} $w" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + CFLAGS="$saved_CFLAGS" + CXXFLAGS="$saved_CXXFLAGS" + esac + done + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${WARN_CFLAGS} ${WERROR_CFLAGS}" >&5 +$as_echo "${WARN_CFLAGS} ${WERROR_CFLAGS}" >&6; } +fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with liblzma" >&5 -$as_echo_n "checking how to link with liblzma... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBLZMA" >&5 -$as_echo "$LIBLZMA" >&6; } - else - HAVE_LIBLZMA=no - CPPFLAGS="$ac_save_CPPFLAGS" - LIBLZMA= - LTLIBLZMA= - fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +# Check whether --enable-ubsan was given. +if test "${enable_ubsan+set}" = set; then : + enableval=$enable_ubsan; +else + enable_ubsan=no +fi - if test "$HAVE_LIBLZMA" != yes; then - if test "$with_lzma" = yes; then - as_fn_error $? "missing liblzma for --with-lzma" "$LINENO" 5 - fi - fi +if test "x$enable_ubsan" = xauto; then + if $development; then + enable_ubsan=yes fi fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -LIBGUI="../libgui/src/libgui.a" -GUI_CFLAGS_X="-I${srcdir}/../libgui/src" - - - -WIN32LDAPP= - - - -case "${host}" in -*-*-cygwin* | *-*-mingw* ) - configdir="win" - ;; -*) - configdir="unix" - ;; -esac - -GDBTKLIBS= -if test "${enable_gdbtk}" = "yes"; then +if test "x$enable_ubsan" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -fsanitize=undefined is accepted" >&5 +$as_echo_n "checking whether -fsanitize=undefined is accepted... " >&6; } + saved_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS -fsanitize=undefined -fno-sanitize-recover=undefined" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ - # Gdbtk must have an absolute path to srcdir in order to run - # properly when not installed. - here=`pwd` - cd ${srcdir} - GDBTK_SRC_DIR=`pwd` - cd $here +int +main () +{ + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + enable_ubsan=yes +else + enable_ubsan=no - # - # Ok, lets find the tcl configuration - # First, look for one uninstalled. - # the alternative search directory is invoked by --with-tcl - # +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + CXXFLAGS="$saved_CXXFLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_ubsan" >&5 +$as_echo "$enable_ubsan" >&6; } + if test "x$enable_ubsan" = xyes; then + WARN_CFLAGS="$WARN_CFLAGS -fsanitize=undefined -fno-sanitize-recover=undefined" + CONFIG_LDFLAGS="$CONFIG_LDFLAGS -fsanitize=undefined" + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu - if test x"${no_tcl}" = x ; then - # we reset no_tcl in case something fails here - no_tcl=true -# Check whether --with-tcl was given. -if test "${with_tcl+set}" = set; then : - withval=$with_tcl; with_tclconfig=${withval} -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl configuration" >&5 -$as_echo_n "checking for Tcl configuration... " >&6; } - if ${ac_cv_c_tclconfig+:} false; then : +# In the Cygwin environment, we need some additional flags. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cygwin" >&5 +$as_echo_n "checking for cygwin... " >&6; } +if ${gdb_cv_os_cygwin+:} false; then : $as_echo_n "(cached) " >&6 else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined (__CYGWIN__) || defined (__CYGWIN32__) +lose +#endif +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "^lose$" >/dev/null 2>&1; then : + gdb_cv_os_cygwin=yes +else + gdb_cv_os_cygwin=no +fi +rm -f conftest* - # First check to see if --with-tcl was specified. - case "${host}" in - *-*-cygwin*) platDir="win" ;; - *) platDir="unix" ;; - esac - if test x"${with_tclconfig}" != x ; then - if test -f "${with_tclconfig}/tclConfig.sh" ; then - ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` - else - as_fn_error $? "${with_tclconfig} directory doesn't contain tclConfig.sh" "$LINENO" 5 - fi - fi - - # then check for a private Tcl installation - if test x"${ac_cv_c_tclconfig}" = x ; then - for i in \ - ../tcl \ - `ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ - `ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \ - `ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \ - ../../tcl \ - `ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ - `ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \ - `ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \ - ../../../tcl \ - `ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ - `ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \ - `ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` ; do - if test -f "$i/$platDir/tclConfig.sh" ; then - ac_cv_c_tclconfig=`(cd $i/$platDir; pwd)` - break - fi - done - fi - - # on Darwin, check in Framework installation locations - if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then - for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ - `ls -d /Library/Frameworks 2>/dev/null` \ - `ls -d /Network/Library/Frameworks 2>/dev/null` \ - `ls -d /System/Library/Frameworks 2>/dev/null` \ - ; do - if test -f "$i/Tcl.framework/tclConfig.sh" ; then - ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)` - break - fi - done - fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_os_cygwin" >&5 +$as_echo "$gdb_cv_os_cygwin" >&6; } - # check in a few common install locations - if test x"${ac_cv_c_tclconfig}" = x ; then - for i in `ls -d ${libdir} 2>/dev/null` \ - `ls -d ${exec_prefix}/lib 2>/dev/null` \ - `ls -d ${prefix}/lib 2>/dev/null` \ - `ls -d /usr/local/lib 2>/dev/null` \ - `ls -d /usr/contrib/lib 2>/dev/null` \ - `ls -d /usr/lib 2>/dev/null` \ - ; do - if test -f "$i/tclConfig.sh" ; then - ac_cv_c_tclconfig=`(cd $i; pwd)` - break - fi - done - fi - # check in a few other private locations - if test x"${ac_cv_c_tclconfig}" = x ; then - for i in \ - ${srcdir}/../tcl \ - `ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ - `ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \ - `ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do - if test -f "$i/$platDir/tclConfig.sh" ; then - ac_cv_c_tclconfig=`(cd $i/$platDir; pwd)` - break - fi - done - fi +SER_HARDWIRE="ser-base.o ser-unix.o ser-pipe.o ser-tcp.o" +case ${host} in + *go32* ) SER_HARDWIRE=ser-go32.o ;; + *djgpp* ) SER_HARDWIRE=ser-go32.o ;; + *mingw32*) SER_HARDWIRE="ser-base.o ser-tcp.o ser-mingw.o" ;; + *) SER_HARDWIRE="$SER_HARDWIRE ser-uds.o" ;; +esac -fi +# libreadline needs libuser32.a in a cygwin environment +WIN32LIBS= +if test x"$gdb_cv_os_cygwin" = xyes; then + WIN32LIBS="-luser32" + case "${target}" in + *cygwin*) WIN32LIBS="$WIN32LIBS -limagehlp" + ;; + esac +fi - if test x"${ac_cv_c_tclconfig}" = x ; then - TCL_BIN_DIR="# no Tcl configs found" - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Can't find Tcl configuration definitions" >&5 -$as_echo "$as_me: WARNING: Can't find Tcl configuration definitions" >&2;} - else - no_tcl= - TCL_BIN_DIR=${ac_cv_c_tclconfig} - { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5 -$as_echo "found ${TCL_BIN_DIR}/tclConfig.sh" >&6; } - fi - fi +# The ser-tcp.c module requires sockets. +# Note that WIN32APILIBS is set by GDB_AC_COMMON. +WIN32LIBS="$WIN32LIBS $WIN32APILIBS" +# Add ELF support to GDB, but only if BFD includes ELF support. - # If $no_tk is nonempty, then we can't do Tk, and there is no - # point to doing Tcl. + OLD_CFLAGS=$CFLAGS + OLD_LDFLAGS=$LDFLAGS + OLD_LIBS=$LIBS + OLD_CC=$CC + # Put the old CFLAGS/LDFLAGS last, in case the user's (C|LD)FLAGS + # points somewhere with bfd, with -I/foo/lib and -L/foo/lib. We + # always want our bfd. + CFLAGS="-I${srcdir}/../include -I../bfd -I${srcdir}/../bfd $CFLAGS" + LDFLAGS="-L../bfd -L../libiberty" + intl=`echo $LIBINTL | sed 's,${top_builddir}/,,g'` + LIBS="-lbfd -liberty $intl $LIBS" + CC="./libtool --quiet --mode=link $CC" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ELF support in BFD" >&5 +$as_echo_n "checking for ELF support in BFD... " >&6; } +if ${gdb_cv_var_elf+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + #include "bfd.h" + #include "elf-bfd.h" +int +main () +{ +return bfd_get_elf_phdr_upper_bound (NULL); - # - # Ok, lets find the tk configuration - # First, look for one uninstalled. - # the alternative search directory is invoked by --with-tk - # + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + gdb_cv_var_elf=yes +else + gdb_cv_var_elf=no - if test x"${no_tk}" = x ; then - # we reset no_tk in case something fails here - no_tk=true +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext -# Check whether --with-tk was given. -if test "${with_tk+set}" = set; then : - withval=$with_tk; with_tkconfig=${withval} fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_var_elf" >&5 +$as_echo "$gdb_cv_var_elf" >&6; } + CC=$OLD_CC + CFLAGS=$OLD_CFLAGS + LDFLAGS=$OLD_LDFLAGS + LIBS=$OLD_LIBS +if test "$gdb_cv_var_elf" = yes; then + CONFIG_OBS="$CONFIG_OBS elfread.o stap-probe.o dtrace-probe.o \ + gcore-elf.o elf-none-tdep.o" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tk configuration" >&5 -$as_echo_n "checking for Tk configuration... " >&6; } - if ${ac_cv_c_tkconfig+:} false; then : +$as_echo "#define HAVE_ELF 1" >>confdefs.h + + # -ldl is provided by bfd/Makfile.am (LIBDL) . + if test "$plugins" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 +$as_echo_n "checking for library containing dlopen... " >&6; } +if ${ac_cv_search_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dl; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_dlopen=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_dlopen+:} false; then : + break +fi +done +if ${ac_cv_search_dlopen+:} false; then : + +else + ac_cv_search_dlopen=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 +$as_echo "$ac_cv_search_dlopen" >&6; } +ac_res=$ac_cv_search_dlopen +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" +fi - # First check to see if --with-tkconfig was specified. - if test x"${with_tkconfig}" != x ; then - if test -f "${with_tkconfig}/tkConfig.sh" ; then - ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)` - else - as_fn_error $? "${with_tkconfig} directory doesn't contain tkConfig.sh" "$LINENO" 5 - fi - fi + fi +fi - # then check for a private Tk library - case "${host}" in - *-*-cygwin*) platDir="win" ;; - *) platDir="unix" ;; - esac - if test x"${ac_cv_c_tkconfig}" = x ; then - for i in \ - ../tk \ - `ls -dr ../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ - `ls -dr ../tk[8-9].[0-9] 2>/dev/null` \ - `ls -dr ../tk[8-9].[0-9]* 2>/dev/null` \ - ../../tk \ - `ls -dr ../../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ - `ls -dr ../../tk[8-9].[0-9] 2>/dev/null` \ - `ls -dr ../../tk[8-9].[0-9]* 2>/dev/null` \ - ../../../tk \ - `ls -dr ../../../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ - `ls -dr ../../../tk[8-9].[0-9] 2>/dev/null` \ - `ls -dr ../../../tk[8-9].[0-9]* 2>/dev/null` ; do - if test -f "$i/$platDir/tkConfig.sh" ; then - ac_cv_c_tkconfig=`(cd $i/$platDir; pwd)` - break - fi - done - fi +# Add macho support to GDB, but only if BFD includes it. - # on Darwin, check in Framework installation locations - if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then - for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ - `ls -d /Library/Frameworks 2>/dev/null` \ - `ls -d /Network/Library/Frameworks 2>/dev/null` \ - `ls -d /System/Library/Frameworks 2>/dev/null` \ - ; do - if test -f "$i/Tk.framework/tkConfig.sh" ; then - ac_cv_c_tkconfig=`(cd $i/Tk.framework; pwd)` - break - fi - done - fi + OLD_CFLAGS=$CFLAGS + OLD_LDFLAGS=$LDFLAGS + OLD_LIBS=$LIBS + OLD_CC=$CC + # Put the old CFLAGS/LDFLAGS last, in case the user's (C|LD)FLAGS + # points somewhere with bfd, with -I/foo/lib and -L/foo/lib. We + # always want our bfd. + CFLAGS="-I${srcdir}/../include -I../bfd -I${srcdir}/../bfd $CFLAGS" + LDFLAGS="-L../bfd -L../libiberty" + intl=`echo $LIBINTL | sed 's,${top_builddir}/,,g'` + LIBS="-lbfd -liberty $intl $LIBS" + CC="./libtool --quiet --mode=link $CC" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Mach-O support in BFD" >&5 +$as_echo_n "checking for Mach-O support in BFD... " >&6; } +if ${gdb_cv_var_macho+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + #include "bfd.h" + #include "mach-o.h" +int +main () +{ +return bfd_mach_o_lookup_command (NULL, 0, NULL); - # check in a few common install locations - if test x"${ac_cv_c_tkconfig}" = x ; then - for i in `ls -d ${libdir} 2>/dev/null` \ - `ls -d ${exec_prefix}/lib 2>/dev/null` \ - `ls -d ${prefix}/lib 2>/dev/null` \ - `ls -d /usr/local/lib 2>/dev/null` \ - `ls -d /usr/contrib/lib 2>/dev/null` \ - `ls -d /usr/lib 2>/dev/null` \ - ; do - if test -f "$i/tkConfig.sh" ; then - ac_cv_c_tkconfig=`(cd $i; pwd)` - break - fi - done - fi - # check in a few other private locations - if test x"${ac_cv_c_tkconfig}" = x ; then - for i in \ - ${srcdir}/../tk \ - `ls -dr ${srcdir}/../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ - `ls -dr ${srcdir}/../tk[8-9].[0-9] 2>/dev/null` \ - `ls -dr ${srcdir}/../tk[8-9].[0-9]* 2>/dev/null` ; do - if test -f "$i/$platDir/tkConfig.sh" ; then - ac_cv_c_tkconfig=`(cd $i/$platDir; pwd)` - break - fi - done - fi + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + gdb_cv_var_macho=yes +else + gdb_cv_var_macho=no fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_var_macho" >&5 +$as_echo "$gdb_cv_var_macho" >&6; } + CC=$OLD_CC + CFLAGS=$OLD_CFLAGS + LDFLAGS=$OLD_LDFLAGS + LIBS=$OLD_LIBS +if test "$gdb_cv_var_macho" = yes; then + CONFIG_OBS="$CONFIG_OBS machoread.o" +fi - if test x"${ac_cv_c_tkconfig}" = x ; then - TK_BIN_DIR="# no Tk configs found" - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Can't find Tk configuration definitions" >&5 -$as_echo "$as_me: WARNING: Can't find Tk configuration definitions" >&2;} - else - no_tk= - TK_BIN_DIR=${ac_cv_c_tkconfig} - { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${TK_BIN_DIR}/tkConfig.sh" >&5 -$as_echo "found ${TK_BIN_DIR}/tkConfig.sh" >&6; } - fi - fi - +# Add any host-specific objects to GDB. +CONFIG_OBS="${CONFIG_OBS} ${gdb_host_obs}" - if test -z "${no_tcl}" -a -z "${no_tk}"; then +# If building on ELF, look for lzma support for embedded compressed debug info. +if test "$gdb_cv_var_elf" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of ${TCL_BIN_DIR}/tclConfig.sh" >&5 -$as_echo_n "checking for existence of ${TCL_BIN_DIR}/tclConfig.sh... " >&6; } +# Check whether --with-lzma was given. +if test "${with_lzma+set}" = set; then : + withval=$with_lzma; +else + with_lzma=auto +fi - if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5 -$as_echo "loading" >&6; } - . ${TCL_BIN_DIR}/tclConfig.sh - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: could not find ${TCL_BIN_DIR}/tclConfig.sh" >&5 -$as_echo "could not find ${TCL_BIN_DIR}/tclConfig.sh" >&6; } - fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use lzma" >&5 +$as_echo_n "checking whether to use lzma... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_lzma" >&5 +$as_echo "$with_lzma" >&6; } - # eval is required to do the TCL_DBGX substitution - eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" - eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" + if test "${with_lzma}" != no; then - # If the TCL_BIN_DIR is the build directory (not the install directory), - # then set the common variable name to the value of the build variables. - # For example, the variable TCL_LIB_SPEC will be set to the value - # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC - # instead of TCL_BUILD_LIB_SPEC since it will work with both an - # installed and uninstalled version of Tcl. - if test -f "${TCL_BIN_DIR}/Makefile" ; then - TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC} - TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC} - TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH} - elif test "`uname -s`" = "Darwin"; then - # If Tcl was built as a framework, attempt to use the libraries - # from the framework at the given location so that linking works - # against Tcl.framework installed in an arbitrary location. - case ${TCL_DEFS} in - *TCL_FRAMEWORK*) - if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then - for i in "`cd ${TCL_BIN_DIR}; pwd`" \ - "`cd ${TCL_BIN_DIR}/../..; pwd`"; do - if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then - TCL_LIB_SPEC="-F`dirname "$i"` -framework ${TCL_LIB_FILE}" - break - fi - done - fi - if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then - TCL_STUB_LIB_SPEC="-L${TCL_BIN_DIR} ${TCL_STUB_LIB_FLAG}" - TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}" - fi - ;; - esac - fi - # eval is required to do the TCL_DBGX substitution - eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" - eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" - eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\"" - eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\"" + use_additional=yes + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" +# Check whether --with-liblzma-prefix was given. +if test "${with_liblzma_prefix+set}" = set; then : + withval=$with_liblzma_prefix; + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" - # Check for in-tree tcl - here=`pwd` - cd ${srcdir}/.. - topdir=`pwd` - cd ${here} + else + additional_includedir="$withval/include" + additional_libdir="$withval/lib" + fi + fi - intree="no" - if test "${TCL_SRC_DIR}" = "${topdir}/tcl"; then - intree="yes" - fi +fi - # Find Tcl private headers - if test x"${intree}" = xno; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl private headers" >&5 -$as_echo_n "checking for Tcl private headers... " >&6; } - private_dir="" - dir=`echo ${TCL_INCLUDE_SPEC}/tcl-private/generic | sed -e s/-I//` - if test -f ${dir}/tclInt.h ; then - private_dir=${dir} - fi +# Check whether --with-liblzma-type was given. +if test "${with_liblzma_type+set}" = set; then : + withval=$with_liblzma_type; with_liblzma_type=$withval +else + with_liblzma_type=auto +fi - if test x"${private_dir}" = x; then - as_fn_error $? "could not find private Tcl headers" "$LINENO" 5 - else - TCL_PRIVATE_INCLUDE="-I${private_dir}" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${private_dir}" >&5 -$as_echo "${private_dir}" >&6; } - fi + lib_type=`eval echo \$with_liblzma_type` - TCL_INCLUDE="${TCL_INCLUDE_SPEC} ${TCL_PRIVATE_INCLUDE}" - TCL_LIBRARY="${TCL_LIB_SPEC}" - TCL_DEPS="" - else - # If building tcl in the same src tree, private headers - # are not needed, but we need to be sure to use the right - # headers library - TCL_INCLUDE="-I${TCL_SRC_DIR}/generic" - TCL_LIBRARY="${TCL_BUILD_LIB_SPEC}" - TCL_DEPS="../tcl/${configdir}${TCL_LIB_FILE}" + LIBLZMA= + LTLIBLZMA= + INCLZMA= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='lzma ' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIBLZMA="${LTLIBLZMA}${LTLIBLZMA:+ }$value" + else + : + fi + else + found_dir= + found_la= + found_so= + found_a= + if test $use_additional = yes; then + if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext" && test x$lib_type != xstatic; then + found_dir="$additional_libdir" + found_so="$additional_libdir/lib$name.$shlibext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + elif test x$lib_type != xshared; then + if test -f "$additional_libdir/lib$name.$libext"; then + found_dir="$additional_libdir" + found_a="$additional_libdir/lib$name.$libext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIBLZMA; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext" && test x$lib_type != xstatic; then + found_dir="$dir" + found_so="$dir/lib$name.$shlibext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + elif test x$lib_type != xshared; then + if test -f "$dir/lib$name.$libext"; then + found_dir="$dir" + found_a="$dir/lib$name.$libext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + LTLIBLZMA="${LTLIBLZMA}${LTLIBLZMA:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then + LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$found_so" + else + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + if test "$hardcode_direct" = yes; then + LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$found_so" + else + if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then + LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$found_so" + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + haveit= + for x in $LDFLAGS $LIBLZMA; do + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIBLZMA="${LIBLZMA}${LIBLZMA:+ }-L$found_dir" + fi + if test "$hardcode_minus_L" != no; then + LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$found_so" + else + LIBLZMA="${LIBLZMA}${LIBLZMA:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$found_a" + else + LIBLZMA="${LIBLZMA}${LIBLZMA:+ }-L$found_dir -l$name" + fi + fi + additional_includedir= + case "$found_dir" in + */lib | */lib/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INCLZMA; do + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + INCLZMA="${INCLZMA}${INCLZMA:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + if test -n "$found_la"; then + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + if test "X$additional_libdir" != "X/usr/lib"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/lib"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIBLZMA; do - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of ${TK_BIN_DIR}/tkConfig.sh" >&5 -$as_echo_n "checking for existence of ${TK_BIN_DIR}/tkConfig.sh... " >&6; } + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" - if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5 -$as_echo "loading" >&6; } - . ${TK_BIN_DIR}/tkConfig.sh - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: could not find ${TK_BIN_DIR}/tkConfig.sh" >&5 -$as_echo "could not find ${TK_BIN_DIR}/tkConfig.sh" >&6; } - fi + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + LIBLZMA="${LIBLZMA}${LIBLZMA:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIBLZMA; do - # eval is required to do the TK_DBGX substitution - eval "TK_LIB_FILE=\"${TK_LIB_FILE}\"" - eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\"" + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" - # If the TK_BIN_DIR is the build directory (not the install directory), - # then set the common variable name to the value of the build variables. - # For example, the variable TK_LIB_SPEC will be set to the value - # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC - # instead of TK_BUILD_LIB_SPEC since it will work with both an - # installed and uninstalled version of Tcl. - if test -f "${TK_BIN_DIR}/Makefile" ; then - TK_LIB_SPEC=${TK_BUILD_LIB_SPEC} - TK_STUB_LIB_SPEC=${TK_BUILD_STUB_LIB_SPEC} - TK_STUB_LIB_PATH=${TK_BUILD_STUB_LIB_PATH} - elif test "`uname -s`" = "Darwin"; then - # If Tk was built as a framework, attempt to use the libraries - # from the framework at the given location so that linking works - # against Tk.framework installed in an arbitrary location. - case ${TK_DEFS} in - *TK_FRAMEWORK*) - if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then - for i in "`cd ${TK_BIN_DIR}; pwd`" \ - "`cd ${TK_BIN_DIR}/../..; pwd`"; do - if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then - TK_LIB_SPEC="-F`dirname "$i"` -framework ${TK_LIB_FILE}" - break - fi - done - fi - if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then - TK_STUB_LIB_SPEC="-L${TK_BIN_DIR} ${TK_STUB_LIB_FLAG}" - TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}" - fi - ;; - esac + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + LTLIBLZMA="${LTLIBLZMA}${LTLIBLZMA:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$dep" + LTLIBLZMA="${LTLIBLZMA}${LTLIBLZMA:+ }$dep" + ;; + esac + done + fi + else + if test "x$lib_type" = "xauto" || test "x$lib_type" = "xshared"; then + LIBLZMA="${LIBLZMA}${LIBLZMA:+ }-l$name" + LTLIBLZMA="${LTLIBLZMA}${LTLIBLZMA:+ }-l$name" + else + LIBLZMA="${LIBLZMA}${LIBLZMA:+ }-l:lib$name.$libext" + LTLIBLZMA="${LTLIBLZMA}${LTLIBLZMA:+ }-l:lib$name.$libext" + fi + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$hardcode_libdir_separator"; then + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$flag" + else + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBLZMA="${LIBLZMA}${LIBLZMA:+ }$flag" + done fi - - # eval is required to do the TK_DBGX substitution - eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\"" - eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\"" - eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\"" - eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\"" - - - - - - + fi + if test "X$ltrpathdirs" != "X"; then + for found_dir in $ltrpathdirs; do + LTLIBLZMA="${LTLIBLZMA}${LTLIBLZMA:+ }-R$found_dir" + done + fi + ac_save_CPPFLAGS="$CPPFLAGS" + for element in $INCLZMA; do + haveit= + for x in $CPPFLAGS; do + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblzma" >&5 +$as_echo_n "checking for liblzma... " >&6; } +if ${ac_cv_liblzma+:} false; then : + $as_echo_n "(cached) " >&6 +else - # Check for in-tree Tk - intree="no" - if test "${TK_SRC_DIR}" = "${topdir}/tk"; then - intree="yes" - fi + ac_save_LIBS="$LIBS" + LIBS="$LIBS $LIBLZMA" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include "lzma.h" +int +main () +{ +lzma_index_iter iter; + lzma_index_iter_init (&iter, 0); + lzma_mf_is_supported (LZMA_MF_HC3); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_liblzma=yes +else + ac_cv_liblzma=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$ac_save_LIBS" - # Find Tk private headers - if test x"${intree}" = xno; then +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_liblzma" >&5 +$as_echo "$ac_cv_liblzma" >&6; } + if test "$ac_cv_liblzma" = yes; then + HAVE_LIBLZMA=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tk private headers" >&5 -$as_echo_n "checking for Tk private headers... " >&6; } - private_dir="" - dir=`echo ${TK_INCLUDE_SPEC}/tk-private/generic | sed -e s/-I//` - if test -f ${dir}/tkInt.h; then - private_dir=${dir} - fi +$as_echo "#define HAVE_LIBLZMA 1" >>confdefs.h - if test x"${private_dir}" = x; then - as_fn_error $? "could not find Tk private headers" "$LINENO" 5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with liblzma" >&5 +$as_echo_n "checking how to link with liblzma... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBLZMA" >&5 +$as_echo "$LIBLZMA" >&6; } else - TK_PRIVATE_INCLUDE="-I${private_dir}" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${private_dir}" >&5 -$as_echo "${private_dir}" >&6; } + HAVE_LIBLZMA=no + CPPFLAGS="$ac_save_CPPFLAGS" + LIBLZMA= + LTLIBLZMA= fi - TK_INCLUDE="${TK_INCLUDE_SPEC} ${TK_PRIVATE_INCLUDE}" - TK_LIBRARY=${TK_LIB_SPEC} - TK_DEPS="" - else - TK_INCLUDE="-I${TK_SRC_DIR}/generic" - TK_LIBRARY="${TK_BUILD_LIB_SPEC}" - TK_DEPS="../tk/${configdir}/${TK_LIB_FILE}" - fi - - - - - - ENABLE_CFLAGS="${ENABLE_CFLAGS} \$(SUBDIR_GDBTK_CFLAGS)" - # Include some libraries that Tcl and Tk want. - TCL_LIBS='$(LIBGUI) $(TK) $(TCL) $(X11_LDFLAGS) $(X11_LIBS)' - # Yes, the ordering seems wrong here. But it isn't. - # TK_LIBS is the list of libraries that need to be linked - # after Tcl/Tk. Note that this isn't put into LIBS. If it - # were in LIBS then any link tests after this point would - # try to include things like `$(LIBGUI)', which wouldn't work. - GDBTKLIBS="${TCL_LIBS} ${TK_LIBS}" - CONFIG_OBS="${CONFIG_OBS} \$(SUBDIR_GDBTK_OBS)" - CONFIG_DEPS="${CONFIG_DEPS} \$(SUBDIR_GDBTK_DEPS)" - CONFIG_SRCS="${CONFIG_SRCS} \$(SUBDIR_GDBTK_SRCS)" - CONFIG_ALL="${CONFIG_ALL} all-gdbtk" - CONFIG_CLEAN="${CONFIG_CLEAN} clean-gdbtk" - CONFIG_INSTALL="${CONFIG_INSTALL} install-gdbtk" - CONFIG_UNINSTALL="${CONFIG_UNINSTALL} uninstall-gdbtk" - if test x"$gdb_cv_os_cygwin" = xyes; then - WIN32LIBS="${WIN32LIBS} -lshell32 -lgdi32 -lcomdlg32 -ladvapi32" - WIN32LDAPP="-Wl,--subsystem,console" - CONFIG_OBS="${CONFIG_OBS} gdbres.o" - fi - subdirs="$subdirs gdbtk" + if test "$HAVE_LIBLZMA" != yes; then + if test "$with_lzma" = yes; then + as_fn_error $? "missing liblzma for --with-lzma" "$LINENO" 5 + fi fi + fi fi +LIBGUI="../libgui/src/libgui.a" +GUI_CFLAGS_X="-I${srcdir}/../libgui/src" +WIN32LDAPP= +case "${host}" in +*-*-cygwin* | *-*-mingw* ) + configdir="win" + ;; +*) + configdir="unix" + ;; +esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5 -$as_echo_n "checking for X... " >&6; } +GDBTKLIBS= +if test "${enable_gdbtk}" = "yes"; then + # Gdbtk must have an absolute path to srcdir in order to run + # properly when not installed. + here=`pwd` + cd ${srcdir} + GDBTK_SRC_DIR=`pwd` + cd $here -# Check whether --with-x was given. -if test "${with_x+set}" = set; then : - withval=$with_x; -fi -# $have_x is `yes', `no', `disabled', or empty when we do not yet know. -if test "x$with_x" = xno; then - # The user explicitly disabled X. - have_x=disabled -else - case $x_includes,$x_libraries in #( - *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( - *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : - $as_echo_n "(cached) " >&6 -else - # One or both of the vars are not set, and there is no cached value. -ac_x_includes=no ac_x_libraries=no -rm -f -r conftest.dir -if mkdir conftest.dir; then - cd conftest.dir - cat >Imakefile <<'_ACEOF' -incroot: - @echo incroot='${INCROOT}' -usrlibdir: - @echo usrlibdir='${USRLIBDIR}' -libdir: - @echo libdir='${LIBDIR}' -_ACEOF - if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then - # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. - for ac_var in incroot usrlibdir libdir; do - eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`" - done - # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. - for ac_extension in a so sl dylib la dll; do - if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" && - test -f "$ac_im_libdir/libX11.$ac_extension"; then - ac_im_usrlibdir=$ac_im_libdir; break - fi - done - # Screen out bogus values from the imake configuration. They are - # bogus both because they are the default anyway, and because - # using them would break gcc on systems where it needs fixed includes. - case $ac_im_incroot in - /usr/include) ac_x_includes= ;; - *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; - esac - case $ac_im_usrlibdir in - /usr/lib | /usr/lib64 | /lib | /lib64) ;; - *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; - esac - fi - cd .. - rm -f -r conftest.dir -fi + # + # Ok, lets find the tcl configuration + # First, look for one uninstalled. + # the alternative search directory is invoked by --with-tcl + # -# Standard set of common directories for X headers. -# Check X11 before X11Rn because it is often a symlink to the current release. -ac_x_header_dirs=' -/usr/X11/include -/usr/X11R7/include -/usr/X11R6/include -/usr/X11R5/include -/usr/X11R4/include + if test x"${no_tcl}" = x ; then + # we reset no_tcl in case something fails here + no_tcl=true + +# Check whether --with-tcl was given. +if test "${with_tcl+set}" = set; then : + withval=$with_tcl; with_tclconfig=${withval} +fi -/usr/include/X11 -/usr/include/X11R7 -/usr/include/X11R6 -/usr/include/X11R5 -/usr/include/X11R4 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl configuration" >&5 +$as_echo_n "checking for Tcl configuration... " >&6; } + if ${ac_cv_c_tclconfig+:} false; then : + $as_echo_n "(cached) " >&6 +else -/usr/local/X11/include -/usr/local/X11R7/include -/usr/local/X11R6/include -/usr/local/X11R5/include -/usr/local/X11R4/include -/usr/local/include/X11 -/usr/local/include/X11R7 -/usr/local/include/X11R6 -/usr/local/include/X11R5 -/usr/local/include/X11R4 + # First check to see if --with-tcl was specified. + case "${host}" in + *-*-cygwin*) platDir="win" ;; + *) platDir="unix" ;; + esac + if test x"${with_tclconfig}" != x ; then + if test -f "${with_tclconfig}/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` + else + as_fn_error $? "${with_tclconfig} directory doesn't contain tclConfig.sh" "$LINENO" 5 + fi + fi -/usr/X386/include -/usr/x386/include -/usr/XFree86/include/X11 + # then check for a private Tcl installation + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in \ + ../tcl \ + `ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \ + `ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \ + ../../tcl \ + `ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \ + `ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \ + ../../../tcl \ + `ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \ + `ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` ; do + if test -f "$i/$platDir/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd $i/$platDir; pwd)` + break + fi + done + fi -/usr/include -/usr/local/include -/usr/unsupported/include -/usr/athena/include -/usr/local/x11r5/include -/usr/lpp/Xamples/include + # on Darwin, check in Framework installation locations + if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then + for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ + `ls -d /Library/Frameworks 2>/dev/null` \ + `ls -d /Network/Library/Frameworks 2>/dev/null` \ + `ls -d /System/Library/Frameworks 2>/dev/null` \ + ; do + if test -f "$i/Tcl.framework/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd $i/Tcl.framework; pwd)` + break + fi + done + fi -/usr/openwin/include -/usr/openwin/share/include' + # check in a few common install locations + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in `ls -d ${libdir} 2>/dev/null` \ + `ls -d ${exec_prefix}/lib 2>/dev/null` \ + `ls -d ${prefix}/lib 2>/dev/null` \ + `ls -d /usr/local/lib 2>/dev/null` \ + `ls -d /usr/contrib/lib 2>/dev/null` \ + `ls -d /usr/lib 2>/dev/null` \ + ; do + if test -f "$i/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd $i; pwd)` + break + fi + done + fi + + # check in a few other private locations + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in \ + ${srcdir}/../tcl \ + `ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \ + `ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do + if test -f "$i/$platDir/tclConfig.sh" ; then + ac_cv_c_tclconfig=`(cd $i/$platDir; pwd)` + break + fi + done + fi -if test "$ac_x_includes" = no; then - # Guess where to find include files, by looking for Xlib.h. - # First, try using that file with no special directory specified. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # We can compile using X headers with no special include directory. -ac_x_includes= -else - for ac_dir in $ac_x_header_dirs; do - if test -r "$ac_dir/X11/Xlib.h"; then - ac_x_includes=$ac_dir - break - fi -done fi -rm -f conftest.err conftest.i conftest.$ac_ext -fi # $ac_x_includes = no -if test "$ac_x_libraries" = no; then - # Check for the libraries. - # See if we find them without any special options. - # Don't add to $LIBS permanently. - ac_save_LIBS=$LIBS - LIBS="-lX11 $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -XrmInitialize () - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - LIBS=$ac_save_LIBS -# We can link X programs with no special library path. -ac_x_libraries= -else - LIBS=$ac_save_LIBS -for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` -do - # Don't even attempt the hair of trying to link an X program! - for ac_extension in a so sl dylib la dll; do - if test -r "$ac_dir/libX11.$ac_extension"; then - ac_x_libraries=$ac_dir - break 2 + + if test x"${ac_cv_c_tclconfig}" = x ; then + TCL_BIN_DIR="# no Tcl configs found" + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Can't find Tcl configuration definitions" >&5 +$as_echo "$as_me: WARNING: Can't find Tcl configuration definitions" >&2;} + else + no_tcl= + TCL_BIN_DIR=${ac_cv_c_tclconfig} + { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5 +$as_echo "found ${TCL_BIN_DIR}/tclConfig.sh" >&6; } + fi fi - done -done -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi # $ac_x_libraries = no -case $ac_x_includes,$ac_x_libraries in #( - no,* | *,no | *\'*) - # Didn't find X, or a directory has "'" in its name. - ac_cv_have_x="have_x=no";; #( - *) - # Record where we found X for the cache. - ac_cv_have_x="have_x=yes\ - ac_x_includes='$ac_x_includes'\ - ac_x_libraries='$ac_x_libraries'" -esac -fi -;; #( - *) have_x=yes;; - esac - eval "$ac_cv_have_x" -fi # $with_x != no -if test "$have_x" != yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5 -$as_echo "$have_x" >&6; } - no_x=yes -else - # If each of the values was on the command line, it overrides each guess. - test "x$x_includes" = xNONE && x_includes=$ac_x_includes - test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries - # Update the cache value to reflect the command line values. - ac_cv_have_x="have_x=yes\ - ac_x_includes='$x_includes'\ - ac_x_libraries='$x_libraries'" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5 -$as_echo "libraries $x_libraries, headers $x_includes" >&6; } -fi + # If $no_tk is nonempty, then we can't do Tk, and there is no + # point to doing Tcl. + # + # Ok, lets find the tk configuration + # First, look for one uninstalled. + # the alternative search directory is invoked by --with-tk + # -# Unlike the sim directory, whether a simulator is linked is controlled by -# presence of a gdb_sim definition in the target configure.tgt entry. -# This code just checks for a few cases where we'd like to ignore those -# definitions, even when they're present in the '.mt' file. These cases -# are when --disable-sim is specified, or if the simulator directory is -# not part of the source tree. -# -# Check whether --enable-sim was given. -if test "${enable_sim+set}" = set; then : - enableval=$enable_sim; echo "enable_sim = $enable_sim"; - echo "enableval = ${enableval}"; - case "${enableval}" in - yes) ignore_sim=false ;; - no) ignore_sim=true ;; - *) ignore_sim=false ;; - esac -else - ignore_sim=false + if test x"${no_tk}" = x ; then + # we reset no_tk in case something fails here + no_tk=true + +# Check whether --with-tk was given. +if test "${with_tk+set}" = set; then : + withval=$with_tk; with_tkconfig=${withval} fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tk configuration" >&5 +$as_echo_n "checking for Tk configuration... " >&6; } + if ${ac_cv_c_tkconfig+:} false; then : + $as_echo_n "(cached) " >&6 +else -if test ! -d "${srcdir}/../sim"; then - ignore_sim=true -fi -SIM= -SIM_OBS= -if test "${ignore_sim}" = "false"; then - if test x"${gdb_sim}" != x ; then - SIM="${gdb_sim}" - SIM_OBS="remote-sim.o" + # First check to see if --with-tkconfig was specified. + if test x"${with_tkconfig}" != x ; then + if test -f "${with_tkconfig}/tkConfig.sh" ; then + ac_cv_c_tkconfig=`(cd ${with_tkconfig}; pwd)` + else + as_fn_error $? "${with_tkconfig} directory doesn't contain tkConfig.sh" "$LINENO" 5 + fi + fi - # Some tdep code should only be compiled in when the ppc sim is - # built. PR sim/13418. - case $target in - powerpc*-*-*) + # then check for a private Tk library + case "${host}" in + *-*-cygwin*) platDir="win" ;; + *) platDir="unix" ;; + esac + if test x"${ac_cv_c_tkconfig}" = x ; then + for i in \ + ../tk \ + `ls -dr ../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ../tk[8-9].[0-9] 2>/dev/null` \ + `ls -dr ../tk[8-9].[0-9]* 2>/dev/null` \ + ../../tk \ + `ls -dr ../../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ../../tk[8-9].[0-9] 2>/dev/null` \ + `ls -dr ../../tk[8-9].[0-9]* 2>/dev/null` \ + ../../../tk \ + `ls -dr ../../../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ../../../tk[8-9].[0-9] 2>/dev/null` \ + `ls -dr ../../../tk[8-9].[0-9]* 2>/dev/null` ; do + if test -f "$i/$platDir/tkConfig.sh" ; then + ac_cv_c_tkconfig=`(cd $i/$platDir; pwd)` + break + fi + done + fi -$as_echo "#define WITH_PPC_SIM 1" >>confdefs.h + # on Darwin, check in Framework installation locations + if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then + for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ + `ls -d /Library/Frameworks 2>/dev/null` \ + `ls -d /Network/Library/Frameworks 2>/dev/null` \ + `ls -d /System/Library/Frameworks 2>/dev/null` \ + ; do + if test -f "$i/Tk.framework/tkConfig.sh" ; then + ac_cv_c_tkconfig=`(cd $i/Tk.framework; pwd)` + break + fi + done + fi + + # check in a few common install locations + if test x"${ac_cv_c_tkconfig}" = x ; then + for i in `ls -d ${libdir} 2>/dev/null` \ + `ls -d ${exec_prefix}/lib 2>/dev/null` \ + `ls -d ${prefix}/lib 2>/dev/null` \ + `ls -d /usr/local/lib 2>/dev/null` \ + `ls -d /usr/contrib/lib 2>/dev/null` \ + `ls -d /usr/lib 2>/dev/null` \ + ; do + if test -f "$i/tkConfig.sh" ; then + ac_cv_c_tkconfig=`(cd $i; pwd)` + break + fi + done + fi + # check in a few other private locations + if test x"${ac_cv_c_tkconfig}" = x ; then + for i in \ + ${srcdir}/../tk \ + `ls -dr ${srcdir}/../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ${srcdir}/../tk[8-9].[0-9] 2>/dev/null` \ + `ls -dr ${srcdir}/../tk[8-9].[0-9]* 2>/dev/null` ; do + if test -f "$i/$platDir/tkConfig.sh" ; then + ac_cv_c_tkconfig=`(cd $i/$platDir; pwd)` + break + fi + done + fi - ;; - esac - fi fi + if test x"${ac_cv_c_tkconfig}" = x ; then + TK_BIN_DIR="# no Tk configs found" + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Can't find Tk configuration definitions" >&5 +$as_echo "$as_me: WARNING: Can't find Tk configuration definitions" >&2;} + else + no_tk= + TK_BIN_DIR=${ac_cv_c_tkconfig} + { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${TK_BIN_DIR}/tkConfig.sh" >&5 +$as_echo "found ${TK_BIN_DIR}/tkConfig.sh" >&6; } + fi + fi + if test -z "${no_tcl}" -a -z "${no_tk}"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of ${TCL_BIN_DIR}/tclConfig.sh" >&5 +$as_echo_n "checking for existence of ${TCL_BIN_DIR}/tclConfig.sh... " >&6; } + if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5 +$as_echo "loading" >&6; } + . ${TCL_BIN_DIR}/tclConfig.sh + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: could not find ${TCL_BIN_DIR}/tclConfig.sh" >&5 +$as_echo "could not find ${TCL_BIN_DIR}/tclConfig.sh" >&6; } + fi + # eval is required to do the TCL_DBGX substitution + eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" + eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" + # If the TCL_BIN_DIR is the build directory (not the install directory), + # then set the common variable name to the value of the build variables. + # For example, the variable TCL_LIB_SPEC will be set to the value + # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC + # instead of TCL_BUILD_LIB_SPEC since it will work with both an + # installed and uninstalled version of Tcl. + if test -f "${TCL_BIN_DIR}/Makefile" ; then + TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC} + TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC} + TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH} + elif test "`uname -s`" = "Darwin"; then + # If Tcl was built as a framework, attempt to use the libraries + # from the framework at the given location so that linking works + # against Tcl.framework installed in an arbitrary location. + case ${TCL_DEFS} in + *TCL_FRAMEWORK*) + if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then + for i in "`cd ${TCL_BIN_DIR}; pwd`" \ + "`cd ${TCL_BIN_DIR}/../..; pwd`"; do + if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then + TCL_LIB_SPEC="-F`dirname "$i"` -framework ${TCL_LIB_FILE}" + break + fi + done + fi + if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then + TCL_STUB_LIB_SPEC="-L${TCL_BIN_DIR} ${TCL_STUB_LIB_FLAG}" + TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}" + fi + ;; + esac + fi + # eval is required to do the TCL_DBGX substitution + eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" + eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" + eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\"" + eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\"" -# List of host floatformats. -cat >>confdefs.h <<_ACEOF -#define GDB_HOST_FLOAT_FORMAT $gdb_host_float_format -_ACEOF -cat >>confdefs.h <<_ACEOF -#define GDB_HOST_DOUBLE_FORMAT $gdb_host_double_format -_ACEOF -cat >>confdefs.h <<_ACEOF -#define GDB_HOST_LONG_DOUBLE_FORMAT $gdb_host_long_double_format -_ACEOF -# target_subdir is used by the testsuite to find the target libraries. -target_subdir= -if test "${host}" != "${target}"; then - target_subdir="${target_alias}/" -fi -# Import nat definitions. -nat_makefile_frag=/dev/null -if test "${gdb_native}" = "yes"; then - . ${srcdir}/configure.nat - nativefile=$NAT_FILE -fi + # Check for in-tree tcl + here=`pwd` + cd ${srcdir}/.. + topdir=`pwd` + cd ${here} + intree="no" + if test "${TCL_SRC_DIR}" = "${topdir}/tcl"; then + intree="yes" + fi + # Find Tcl private headers + if test x"${intree}" = xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl private headers" >&5 +$as_echo_n "checking for Tcl private headers... " >&6; } + private_dir="" + dir=`echo ${TCL_INCLUDE_SPEC}/tcl-private/generic | sed -e s/-I//` + if test -f ${dir}/tclInt.h ; then + private_dir=${dir} + fi + if test x"${private_dir}" = x; then + as_fn_error $? "could not find private Tcl headers" "$LINENO" 5 + else + TCL_PRIVATE_INCLUDE="-I${private_dir}" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${private_dir}" >&5 +$as_echo "${private_dir}" >&6; } + fi + TCL_INCLUDE="${TCL_INCLUDE_SPEC} ${TCL_PRIVATE_INCLUDE}" + TCL_LIBRARY="${TCL_LIB_SPEC}" + TCL_DEPS="" + else + # If building tcl in the same src tree, private headers + # are not needed, but we need to be sure to use the right + # headers library + TCL_INCLUDE="-I${TCL_SRC_DIR}/generic" + TCL_LIBRARY="${TCL_BUILD_LIB_SPEC}" + TCL_DEPS="../tcl/${configdir}${TCL_LIB_FILE}" + fi -if test x"${gdb_osabi}" != x ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of ${TK_BIN_DIR}/tkConfig.sh" >&5 +$as_echo_n "checking for existence of ${TK_BIN_DIR}/tkConfig.sh... " >&6; } -cat >>confdefs.h <<_ACEOF -#define GDB_OSABI_DEFAULT $gdb_osabi -_ACEOF + if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5 +$as_echo "loading" >&6; } + . ${TK_BIN_DIR}/tkConfig.sh + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: could not find ${TK_BIN_DIR}/tkConfig.sh" >&5 +$as_echo "could not find ${TK_BIN_DIR}/tkConfig.sh" >&6; } + fi -fi + # eval is required to do the TK_DBGX substitution + eval "TK_LIB_FILE=\"${TK_LIB_FILE}\"" + eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\"" -# Setup possible use of libbacktrace. -# Check whether --enable-libbacktrace was given. -if test "${enable_libbacktrace+set}" = set; then : - enableval=$enable_libbacktrace; - case $enableval in - yes | no) - ;; - *) - as_fn_error $? "bad value $enableval for --enable-libbacktrace" "$LINENO" 5 - ;; - esac + # If the TK_BIN_DIR is the build directory (not the install directory), + # then set the common variable name to the value of the build variables. + # For example, the variable TK_LIB_SPEC will be set to the value + # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC + # instead of TK_BUILD_LIB_SPEC since it will work with both an + # installed and uninstalled version of Tcl. + if test -f "${TK_BIN_DIR}/Makefile" ; then + TK_LIB_SPEC=${TK_BUILD_LIB_SPEC} + TK_STUB_LIB_SPEC=${TK_BUILD_STUB_LIB_SPEC} + TK_STUB_LIB_PATH=${TK_BUILD_STUB_LIB_PATH} + elif test "`uname -s`" = "Darwin"; then + # If Tk was built as a framework, attempt to use the libraries + # from the framework at the given location so that linking works + # against Tk.framework installed in an arbitrary location. + case ${TK_DEFS} in + *TK_FRAMEWORK*) + if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then + for i in "`cd ${TK_BIN_DIR}; pwd`" \ + "`cd ${TK_BIN_DIR}/../..; pwd`"; do + if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then + TK_LIB_SPEC="-F`dirname "$i"` -framework ${TK_LIB_FILE}" + break + fi + done + fi + if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then + TK_STUB_LIB_SPEC="-L${TK_BIN_DIR} ${TK_STUB_LIB_FLAG}" + TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}" + fi + ;; + esac + fi -else - enable_libbacktrace=yes -fi + # eval is required to do the TK_DBGX substitution + eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\"" + eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\"" + eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\"" + eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\"" -if test "${enable_libbacktrace}" = "yes"; then - LIBBACKTRACE_INC="-I$srcdir/../libbacktrace/ -I../libbacktrace/" - LIBBACKTRACE_LIB=../libbacktrace/libbacktrace.la -$as_echo "#define HAVE_LIBBACKTRACE 1" >>confdefs.h -else - LIBBACKTRACE_INC= - LIBBACKTRACE_LIB= -fi -# Check for babeltrace and babeltrace-ctf -# Check whether --with-babeltrace was given. -if test "${with_babeltrace+set}" = set; then : - withval=$with_babeltrace; -else - with_babeltrace=auto -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use babeltrace" >&5 -$as_echo_n "checking whether to use babeltrace... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_babeltrace" >&5 -$as_echo "$with_babeltrace" >&6; } -if test "x$with_babeltrace" = "xno"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: babletrace support disabled; GDB is unable to read CTF data." >&5 -$as_echo "$as_me: WARNING: babletrace support disabled; GDB is unable to read CTF data." >&2;} -else - # Append -Werror to CFLAGS so that configure can catch the warning - # "assignment from incompatible pointer type", which is related to - # the babeltrace change from 1.0.3 to 1.1.0. Babeltrace 1.1.0 works - # in GDB, while babeltrace 1.0.3 is broken. - # AC_LIB_HAVE_LINKFLAGS may modify CPPFLAGS in it, so it should be - # safe to save and restore CFLAGS here. - saved_CFLAGS=$CFLAGS - CFLAGS="$CFLAGS -Werror" + # Check for in-tree Tk + intree="no" + if test "${TK_SRC_DIR}" = "${topdir}/tk"; then + intree="yes" + fi + # Find Tk private headers + if test x"${intree}" = xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tk private headers" >&5 +$as_echo_n "checking for Tk private headers... " >&6; } + private_dir="" + dir=`echo ${TK_INCLUDE_SPEC}/tk-private/generic | sed -e s/-I//` + if test -f ${dir}/tkInt.h; then + private_dir=${dir} + fi + if test x"${private_dir}" = x; then + as_fn_error $? "could not find Tk private headers" "$LINENO" 5 + else + TK_PRIVATE_INCLUDE="-I${private_dir}" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${private_dir}" >&5 +$as_echo "${private_dir}" >&6; } + fi + TK_INCLUDE="${TK_INCLUDE_SPEC} ${TK_PRIVATE_INCLUDE}" + TK_LIBRARY=${TK_LIB_SPEC} + TK_DEPS="" + else + TK_INCLUDE="-I${TK_SRC_DIR}/generic" + TK_LIBRARY="${TK_BUILD_LIB_SPEC}" + TK_DEPS="../tk/${configdir}/${TK_LIB_FILE}" + fi - use_additional=yes - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" + ENABLE_CFLAGS="${ENABLE_CFLAGS} \$(SUBDIR_GDBTK_CFLAGS)" -# Check whether --with-libbabeltrace-prefix was given. -if test "${with_libbabeltrace_prefix+set}" = set; then : - withval=$with_libbabeltrace_prefix; - if test "X$withval" = "Xno"; then - use_additional=no - else - if test "X$withval" = "X"; then + # Include some libraries that Tcl and Tk want. + TCL_LIBS='$(LIBGUI) $(TK) $(TCL) $(X11_LDFLAGS) $(X11_LIBS)' + # Yes, the ordering seems wrong here. But it isn't. + # TK_LIBS is the list of libraries that need to be linked + # after Tcl/Tk. Note that this isn't put into LIBS. If it + # were in LIBS then any link tests after this point would + # try to include things like `$(LIBGUI)', which wouldn't work. + GDBTKLIBS="${TCL_LIBS} ${TK_LIBS}" - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" + CONFIG_OBS="${CONFIG_OBS} \$(SUBDIR_GDBTK_OBS)" + CONFIG_DEPS="${CONFIG_DEPS} \$(SUBDIR_GDBTK_DEPS)" + CONFIG_SRCS="${CONFIG_SRCS} \$(SUBDIR_GDBTK_SRCS)" + CONFIG_ALL="${CONFIG_ALL} all-gdbtk" + CONFIG_CLEAN="${CONFIG_CLEAN} clean-gdbtk" + CONFIG_INSTALL="${CONFIG_INSTALL} install-gdbtk" + CONFIG_UNINSTALL="${CONFIG_UNINSTALL} uninstall-gdbtk" - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" + if test x"$gdb_cv_os_cygwin" = xyes; then + WIN32LIBS="${WIN32LIBS} -lshell32 -lgdi32 -lcomdlg32 -ladvapi32" + WIN32LDAPP="-Wl,--subsystem,console" + CONFIG_OBS="${CONFIG_OBS} gdbres.o" + fi - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" + subdirs="$subdirs gdbtk" - else - additional_includedir="$withval/include" - additional_libdir="$withval/lib" - fi fi - -fi - - -# Check whether --with-libbabeltrace-type was given. -if test "${with_libbabeltrace_type+set}" = set; then : - withval=$with_libbabeltrace_type; with_libbabeltrace_type=$withval -else - with_libbabeltrace_type=auto fi - lib_type=`eval echo \$with_libbabeltrace_type` - - LIBBABELTRACE= - LTLIBBABELTRACE= - INCBABELTRACE= - rpathdirs= - ltrpathdirs= - names_already_handled= - names_next_round='babeltrace babeltrace-ctf' - while test -n "$names_next_round"; do - names_this_round="$names_next_round" - names_next_round= - for name in $names_this_round; do - already_handled= - for n in $names_already_handled; do - if test "$n" = "$name"; then - already_handled=yes - break - fi - done - if test -z "$already_handled"; then - names_already_handled="$names_already_handled $name" - uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` - eval value=\"\$HAVE_LIB$uppername\" - if test -n "$value"; then - if test "$value" = yes; then - eval value=\"\$LIB$uppername\" - test -z "$value" || LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }$value" - eval value=\"\$LTLIB$uppername\" - test -z "$value" || LTLIBBABELTRACE="${LTLIBBABELTRACE}${LTLIBBABELTRACE:+ }$value" - else - : - fi - else - found_dir= - found_la= - found_so= - found_a= - if test $use_additional = yes; then - if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext" && test x$lib_type != xstatic; then - found_dir="$additional_libdir" - found_so="$additional_libdir/lib$name.$shlibext" - if test -f "$additional_libdir/lib$name.la"; then - found_la="$additional_libdir/lib$name.la" - fi - elif test x$lib_type != xshared; then - if test -f "$additional_libdir/lib$name.$libext"; then - found_dir="$additional_libdir" - found_a="$additional_libdir/lib$name.$libext" - if test -f "$additional_libdir/lib$name.la"; then - found_la="$additional_libdir/lib$name.la" - fi - fi - fi - fi - if test "X$found_dir" = "X"; then - for x in $LDFLAGS $LTLIBBABELTRACE; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - case "$x" in - -L*) - dir=`echo "X$x" | sed -e 's/^X-L//'` - if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext" && test x$lib_type != xstatic; then - found_dir="$dir" - found_so="$dir/lib$name.$shlibext" - if test -f "$dir/lib$name.la"; then - found_la="$dir/lib$name.la" - fi - elif test x$lib_type != xshared; then - if test -f "$dir/lib$name.$libext"; then - found_dir="$dir" - found_a="$dir/lib$name.$libext" - if test -f "$dir/lib$name.la"; then - found_la="$dir/lib$name.la" - fi - fi - fi - ;; - esac - if test "X$found_dir" != "X"; then - break - fi - done - fi - if test "X$found_dir" != "X"; then - LTLIBBABELTRACE="${LTLIBBABELTRACE}${LTLIBBABELTRACE:+ }-L$found_dir -l$name" - if test "X$found_so" != "X"; then - if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then - LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }$found_so" - else - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $found_dir" - fi - if test "$hardcode_direct" = yes; then - LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }$found_so" - else - if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then - LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }$found_so" - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $found_dir" - fi - else - haveit= - for x in $LDFLAGS $LIBBABELTRACE; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - if test "X$x" = "X-L$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }-L$found_dir" - fi - if test "$hardcode_minus_L" != no; then - LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }$found_so" - else - LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }-l$name" - fi - fi - fi - fi - else - if test "X$found_a" != "X"; then - LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }$found_a" - else - LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }-L$found_dir -l$name" - fi - fi - additional_includedir= - case "$found_dir" in - */lib | */lib/) - basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` - additional_includedir="$basedir/include" - ;; - esac - if test "X$additional_includedir" != "X"; then - if test "X$additional_includedir" != "X/usr/include"; then - haveit= - if test "X$additional_includedir" = "X/usr/local/include"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - for x in $CPPFLAGS $INCBABELTRACE; do - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - if test "X$x" = "X-I$additional_includedir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_includedir"; then - INCBABELTRACE="${INCBABELTRACE}${INCBABELTRACE:+ }-I$additional_includedir" - fi - fi - fi - fi - fi - if test -n "$found_la"; then - save_libdir="$libdir" - case "$found_la" in - */* | *\\*) . "$found_la" ;; - *) . "./$found_la" ;; - esac - libdir="$save_libdir" - for dep in $dependency_libs; do - case "$dep" in - -L*) - additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` - if test "X$additional_libdir" != "X/usr/lib"; then - haveit= - if test "X$additional_libdir" = "X/usr/local/lib"; then - if test -n "$GCC"; then - case $host_os in - linux*) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - haveit= - for x in $LDFLAGS $LIBBABELTRACE; do - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }-L$additional_libdir" - fi - fi - haveit= - for x in $LDFLAGS $LTLIBBABELTRACE; do - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - LTLIBBABELTRACE="${LTLIBBABELTRACE}${LTLIBBABELTRACE:+ }-L$additional_libdir" - fi - fi - fi - fi - ;; - -R*) - dir=`echo "X$dep" | sed -e 's/^X-R//'` - if test "$enable_rpath" != no; then - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $dir" - fi - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $dir" - fi - fi - ;; - -l*) - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` - ;; - *.la) - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` - ;; - *) - LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }$dep" - LTLIBBABELTRACE="${LTLIBBABELTRACE}${LTLIBBABELTRACE:+ }$dep" - ;; - esac - done - fi - else - if test "x$lib_type" = "xauto" || test "x$lib_type" = "xshared"; then - LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }-l$name" - LTLIBBABELTRACE="${LTLIBBABELTRACE}${LTLIBBABELTRACE:+ }-l$name" - else - LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }-l:lib$name.$libext" - LTLIBBABELTRACE="${LTLIBBABELTRACE}${LTLIBBABELTRACE:+ }-l:lib$name.$libext" - fi - fi - fi - fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5 +$as_echo_n "checking for X... " >&6; } + + +# Check whether --with-x was given. +if test "${with_x+set}" = set; then : + withval=$with_x; +fi + +# $have_x is `yes', `no', `disabled', or empty when we do not yet know. +if test "x$with_x" = xno; then + # The user explicitly disabled X. + have_x=disabled +else + case $x_includes,$x_libraries in #( + *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( + *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : + $as_echo_n "(cached) " >&6 +else + # One or both of the vars are not set, and there is no cached value. +ac_x_includes=no ac_x_libraries=no +rm -f -r conftest.dir +if mkdir conftest.dir; then + cd conftest.dir + cat >Imakefile <<'_ACEOF' +incroot: + @echo incroot='${INCROOT}' +usrlibdir: + @echo usrlibdir='${USRLIBDIR}' +libdir: + @echo libdir='${LIBDIR}' +_ACEOF + if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then + # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. + for ac_var in incroot usrlibdir libdir; do + eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`" done - done - if test "X$rpathdirs" != "X"; then - if test -n "$hardcode_libdir_separator"; then - alldirs= - for found_dir in $rpathdirs; do - alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" - done - acl_save_libdir="$libdir" - libdir="$alldirs" - eval flag=\"$hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }$flag" - else - for found_dir in $rpathdirs; do - acl_save_libdir="$libdir" - libdir="$found_dir" - eval flag=\"$hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }$flag" - done - fi - fi - if test "X$ltrpathdirs" != "X"; then - for found_dir in $ltrpathdirs; do - LTLIBBABELTRACE="${LTLIBBABELTRACE}${LTLIBBABELTRACE:+ }-R$found_dir" + # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. + for ac_extension in a so sl dylib la dll; do + if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" && + test -f "$ac_im_libdir/libX11.$ac_extension"; then + ac_im_usrlibdir=$ac_im_libdir; break + fi done + # Screen out bogus values from the imake configuration. They are + # bogus both because they are the default anyway, and because + # using them would break gcc on systems where it needs fixed includes. + case $ac_im_incroot in + /usr/include) ac_x_includes= ;; + *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; + esac + case $ac_im_usrlibdir in + /usr/lib | /usr/lib64 | /lib | /lib64) ;; + *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; + esac fi + cd .. + rm -f -r conftest.dir +fi +# Standard set of common directories for X headers. +# Check X11 before X11Rn because it is often a symlink to the current release. +ac_x_header_dirs=' +/usr/X11/include +/usr/X11R7/include +/usr/X11R6/include +/usr/X11R5/include +/usr/X11R4/include - ac_save_CPPFLAGS="$CPPFLAGS" +/usr/include/X11 +/usr/include/X11R7 +/usr/include/X11R6 +/usr/include/X11R5 +/usr/include/X11R4 - for element in $INCBABELTRACE; do - haveit= - for x in $CPPFLAGS; do +/usr/local/X11/include +/usr/local/X11R7/include +/usr/local/X11R6/include +/usr/local/X11R5/include +/usr/local/X11R4/include - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" +/usr/local/include/X11 +/usr/local/include/X11R7 +/usr/local/include/X11R6 +/usr/local/include/X11R5 +/usr/local/include/X11R4 - if test "X$x" = "X$element"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" - fi - done +/usr/X386/include +/usr/x386/include +/usr/XFree86/include/X11 + +/usr/include +/usr/local/include +/usr/unsupported/include +/usr/athena/include +/usr/local/x11r5/include +/usr/lpp/Xamples/include +/usr/openwin/include +/usr/openwin/share/include' - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libbabeltrace" >&5 -$as_echo_n "checking for libbabeltrace... " >&6; } -if ${ac_cv_libbabeltrace+:} false; then : - $as_echo_n "(cached) " >&6 +if test "$ac_x_includes" = no; then + # Guess where to find include files, by looking for Xlib.h. + # First, try using that file with no special directory specified. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # We can compile using X headers with no special include directory. +ac_x_includes= else + for ac_dir in $ac_x_header_dirs; do + if test -r "$ac_dir/X11/Xlib.h"; then + ac_x_includes=$ac_dir + break + fi +done +fi +rm -f conftest.err conftest.i conftest.$ac_ext +fi # $ac_x_includes = no - ac_save_LIBS="$LIBS" - LIBS="$LIBS $LIBBABELTRACE" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +if test "$ac_x_libraries" = no; then + # Check for the libraries. + # See if we find them without any special options. + # Don't add to $LIBS permanently. + ac_save_LIBS=$LIBS + LIBS="-lX11 $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include - #include - #include +#include int main () { -struct bt_iter_pos *pos = bt_iter_get_pos (bt_ctf_get_iter (NULL)); - struct bt_ctf_event *event = NULL; - const struct bt_definition *scope; - - pos->type = BT_SEEK_BEGIN; - bt_iter_set_pos (bt_ctf_get_iter (NULL), pos); - scope = bt_ctf_get_top_level_scope (event, - BT_STREAM_EVENT_HEADER); - bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "id")); - +XrmInitialize () ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_libbabeltrace=yes + LIBS=$ac_save_LIBS +# We can link X programs with no special library path. +ac_x_libraries= else - ac_cv_libbabeltrace=no + LIBS=$ac_save_LIBS +for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` +do + # Don't even attempt the hair of trying to link an X program! + for ac_extension in a so sl dylib la dll; do + if test -r "$ac_dir/libX11.$ac_extension"; then + ac_x_libraries=$ac_dir + break 2 + fi + done +done fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext - LIBS="$ac_save_LIBS" +fi # $ac_x_libraries = no + +case $ac_x_includes,$ac_x_libraries in #( + no,* | *,no | *\'*) + # Didn't find X, or a directory has "'" in its name. + ac_cv_have_x="have_x=no";; #( + *) + # Record where we found X for the cache. + ac_cv_have_x="have_x=yes\ + ac_x_includes='$ac_x_includes'\ + ac_x_libraries='$ac_x_libraries'" +esac +fi +;; #( + *) have_x=yes;; + esac + eval "$ac_cv_have_x" +fi # $with_x != no +if test "$have_x" != yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5 +$as_echo "$have_x" >&6; } + no_x=yes +else + # If each of the values was on the command line, it overrides each guess. + test "x$x_includes" = xNONE && x_includes=$ac_x_includes + test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries + # Update the cache value to reflect the command line values. + ac_cv_have_x="have_x=yes\ + ac_x_includes='$x_includes'\ + ac_x_libraries='$x_libraries'" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5 +$as_echo "libraries $x_libraries, headers $x_includes" >&6; } fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libbabeltrace" >&5 -$as_echo "$ac_cv_libbabeltrace" >&6; } - if test "$ac_cv_libbabeltrace" = yes; then - HAVE_LIBBABELTRACE=yes -$as_echo "#define HAVE_LIBBABELTRACE 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libbabeltrace" >&5 -$as_echo_n "checking how to link with libbabeltrace... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBBABELTRACE" >&5 -$as_echo "$LIBBABELTRACE" >&6; } - else - HAVE_LIBBABELTRACE=no - CPPFLAGS="$ac_save_CPPFLAGS" - LIBBABELTRACE= - LTLIBBABELTRACE= +# Unlike the sim directory, whether a simulator is linked is controlled by +# presence of a gdb_sim definition in the target configure.tgt entry. +# This code just checks for a few cases where we'd like to ignore those +# definitions, even when they're present in the '.mt' file. These cases +# are when --disable-sim is specified, or if the simulator directory is +# not part of the source tree. +# +# Check whether --enable-sim was given. +if test "${enable_sim+set}" = set; then : + enableval=$enable_sim; echo "enable_sim = $enable_sim"; + echo "enableval = ${enableval}"; + case "${enableval}" in + yes) ignore_sim=false ;; + no) ignore_sim=true ;; + *) ignore_sim=false ;; + esac +else + ignore_sim=false +fi + + +if test ! -d "${srcdir}/../sim"; then + ignore_sim=true +fi + +SIM= +SIM_OBS= +if test "${ignore_sim}" = "false"; then + if test x"${gdb_sim}" != x ; then + SIM="${gdb_sim}" + SIM_OBS="remote-sim.o" + + # Some tdep code should only be compiled in when the ppc sim is + # built. PR sim/13418. + case $target in + powerpc*-*-*) + +$as_echo "#define WITH_PPC_SIM 1" >>confdefs.h + + ;; + esac fi +fi + + + + + + + + + + + + + + +# List of host floatformats. + +cat >>confdefs.h <<_ACEOF +#define GDB_HOST_FLOAT_FORMAT $gdb_host_float_format +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define GDB_HOST_DOUBLE_FORMAT $gdb_host_double_format +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define GDB_HOST_LONG_DOUBLE_FORMAT $gdb_host_long_double_format +_ACEOF + + +# target_subdir is used by the testsuite to find the target libraries. +target_subdir= +if test "${host}" != "${target}"; then + target_subdir="${target_alias}/" +fi + + +# Import nat definitions. +nat_makefile_frag=/dev/null +if test "${gdb_native}" = "yes"; then + . ${srcdir}/configure.nat + nativefile=$NAT_FILE +fi - CFLAGS=$saved_CFLAGS - if test "$HAVE_LIBBABELTRACE" != yes; then - if test "$with_babeltrace" = yes; then - as_fn_error $? "babeltrace is missing or unusable" "$LINENO" 5 - else - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: babeltrace is missing or unusable; GDB is unable to read CTF data." >&5 -$as_echo "$as_me: WARNING: babeltrace is missing or unusable; GDB is unable to read CTF data." >&2;} - fi - fi + + + + +if test x"${gdb_osabi}" != x ; then + +cat >>confdefs.h <<_ACEOF +#define GDB_OSABI_DEFAULT $gdb_osabi +_ACEOF + fi -# Check for xxhash +# Setup possible use of libbacktrace. +# Check whether --enable-libbacktrace was given. +if test "${enable_libbacktrace+set}" = set; then : + enableval=$enable_libbacktrace; + case $enableval in + yes | no) + ;; + *) + as_fn_error $? "bad value $enableval for --enable-libbacktrace" "$LINENO" 5 + ;; + esac -# Check whether --with-xxhash was given. -if test "${with_xxhash+set}" = set; then : - withval=$with_xxhash; else - with_xxhash=auto + enable_libbacktrace=yes fi - # Check whether --enable-libctf was given. -if test "${enable_libctf+set}" = set; then : - enableval=$enable_libctf; - case "$enableval" in - yes|no) ;; - *) as_fn_error $? "Argument to enable/disable libctf must be yes or no" "$LINENO" 5 ;; - esac +if test "${enable_libbacktrace}" = "yes"; then + LIBBACKTRACE_INC="-I$srcdir/../libbacktrace/ -I../libbacktrace/" + LIBBACKTRACE_LIB=../libbacktrace/libbacktrace.la + +$as_echo "#define HAVE_LIBBACKTRACE 1" >>confdefs.h else - enable_libctf=yes + LIBBACKTRACE_INC= + LIBBACKTRACE_LIB= fi -if test "${enable_libctf}" = yes; then -$as_echo "#define ENABLE_LIBCTF 1" >>confdefs.h - LIBCTF="../libctf/libctf.la" - CTF_DEPS="../libctf/libctf.la" +# Check for babeltrace and babeltrace-ctf + +# Check whether --with-babeltrace was given. +if test "${with_babeltrace+set}" = set; then : + withval=$with_babeltrace; else - LIBCTF= - CTF_DEPS= + with_babeltrace=auto fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use babeltrace" >&5 +$as_echo_n "checking whether to use babeltrace... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_babeltrace" >&5 +$as_echo "$with_babeltrace" >&6; } - -# If nativefile (NAT_FILE) is not set in configure.nat, we link to an -# empty version. - -if test "x$with_xxhash" != "xno"; then +if test "x$with_babeltrace" = "xno"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: babletrace support disabled; GDB is unable to read CTF data." >&5 +$as_echo "$as_me: WARNING: babletrace support disabled; GDB is unable to read CTF data." >&2;} +else + # Append -Werror to CFLAGS so that configure can catch the warning + # "assignment from incompatible pointer type", which is related to + # the babeltrace change from 1.0.3 to 1.1.0. Babeltrace 1.1.0 works + # in GDB, while babeltrace 1.0.3 is broken. + # AC_LIB_HAVE_LINKFLAGS may modify CPPFLAGS in it, so it should be + # safe to save and restore CFLAGS here. + saved_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -Werror" @@ -30658,9 +30622,9 @@ if test "x$with_xxhash" != "xno"; then prefix="$acl_save_prefix" -# Check whether --with-libxxhash-prefix was given. -if test "${with_libxxhash_prefix+set}" = set; then : - withval=$with_libxxhash_prefix; +# Check whether --with-libbabeltrace-prefix was given. +if test "${with_libbabeltrace_prefix+set}" = set; then : + withval=$with_libbabeltrace_prefix; if test "X$withval" = "Xno"; then use_additional=no else @@ -30686,22 +30650,22 @@ if test "${with_libxxhash_prefix+set}" = set; then : fi -# Check whether --with-libxxhash-type was given. -if test "${with_libxxhash_type+set}" = set; then : - withval=$with_libxxhash_type; with_libxxhash_type=$withval +# Check whether --with-libbabeltrace-type was given. +if test "${with_libbabeltrace_type+set}" = set; then : + withval=$with_libbabeltrace_type; with_libbabeltrace_type=$withval else - with_libxxhash_type=auto + with_libbabeltrace_type=auto fi - lib_type=`eval echo \$with_libxxhash_type` + lib_type=`eval echo \$with_libbabeltrace_type` - LIBXXHASH= - LTLIBXXHASH= - INCXXHASH= + LIBBABELTRACE= + LTLIBBABELTRACE= + INCBABELTRACE= rpathdirs= ltrpathdirs= names_already_handled= - names_next_round='xxhash ' + names_next_round='babeltrace babeltrace-ctf' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= @@ -30720,9 +30684,9 @@ fi if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" - test -z "$value" || LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$value" + test -z "$value" || LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }$value" eval value=\"\$LTLIB$uppername\" - test -z "$value" || LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }$value" + test -z "$value" || LTLIBBABELTRACE="${LTLIBBABELTRACE}${LTLIBBABELTRACE:+ }$value" else : fi @@ -30749,7 +30713,7 @@ fi fi fi if test "X$found_dir" = "X"; then - for x in $LDFLAGS $LTLIBXXHASH; do + for x in $LDFLAGS $LTLIBBABELTRACE; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" @@ -30785,10 +30749,10 @@ fi done fi if test "X$found_dir" != "X"; then - LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }-L$found_dir -l$name" + LTLIBBABELTRACE="${LTLIBBABELTRACE}${LTLIBBABELTRACE:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then - LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$found_so" + LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }$found_so" else haveit= for x in $ltrpathdirs; do @@ -30801,10 +30765,10 @@ fi ltrpathdirs="$ltrpathdirs $found_dir" fi if test "$hardcode_direct" = yes; then - LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$found_so" + LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }$found_so" else if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then - LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$found_so" + LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }$found_so" haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then @@ -30817,7 +30781,7 @@ fi fi else haveit= - for x in $LDFLAGS $LIBXXHASH; do + for x in $LDFLAGS $LIBBABELTRACE; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" @@ -30833,21 +30797,21 @@ fi fi done if test -z "$haveit"; then - LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-L$found_dir" + LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }-L$found_dir" fi if test "$hardcode_minus_L" != no; then - LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$found_so" + LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }$found_so" else - LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-l$name" + LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then - LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$found_a" + LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }$found_a" else - LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-L$found_dir -l$name" + LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }-L$found_dir -l$name" fi fi additional_includedir= @@ -30868,7 +30832,7 @@ fi fi fi if test -z "$haveit"; then - for x in $CPPFLAGS $INCXXHASH; do + for x in $CPPFLAGS $INCBABELTRACE; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" @@ -30885,7 +30849,7 @@ fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then - INCXXHASH="${INCXXHASH}${INCXXHASH:+ }-I$additional_includedir" + INCBABELTRACE="${INCBABELTRACE}${INCBABELTRACE:+ }-I$additional_includedir" fi fi fi @@ -30913,7 +30877,7 @@ fi fi if test -z "$haveit"; then haveit= - for x in $LDFLAGS $LIBXXHASH; do + for x in $LDFLAGS $LIBBABELTRACE; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" @@ -30930,11 +30894,11 @@ fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then - LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-L$additional_libdir" + LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }-L$additional_libdir" fi fi haveit= - for x in $LDFLAGS $LTLIBXXHASH; do + for x in $LDFLAGS $LTLIBBABELTRACE; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" @@ -30951,7 +30915,7 @@ fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then - LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }-L$additional_libdir" + LTLIBBABELTRACE="${LTLIBBABELTRACE}${LTLIBBABELTRACE:+ }-L$additional_libdir" fi fi fi @@ -30989,19 +30953,19 @@ fi names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) - LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$dep" - LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }$dep" + LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }$dep" + LTLIBBABELTRACE="${LTLIBBABELTRACE}${LTLIBBABELTRACE:+ }$dep" ;; esac done fi else if test "x$lib_type" = "xauto" || test "x$lib_type" = "xshared"; then - LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-l$name" - LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }-l$name" + LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }-l$name" + LTLIBBABELTRACE="${LTLIBBABELTRACE}${LTLIBBABELTRACE:+ }-l$name" else - LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-l:lib$name.$libext" - LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }-l:lib$name.$libext" + LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }-l:lib$name.$libext" + LTLIBBABELTRACE="${LTLIBBABELTRACE}${LTLIBBABELTRACE:+ }-l:lib$name.$libext" fi fi fi @@ -31018,27 +30982,27 @@ fi libdir="$alldirs" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" - LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$flag" + LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }$flag" else for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" - LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$flag" + LIBBABELTRACE="${LIBBABELTRACE}${LIBBABELTRACE:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then for found_dir in $ltrpathdirs; do - LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }-R$found_dir" + LTLIBBABELTRACE="${LTLIBBABELTRACE}${LTLIBBABELTRACE:+ }-R$found_dir" done fi ac_save_CPPFLAGS="$CPPFLAGS" - for element in $INCXXHASH; do + for element in $INCBABELTRACE; do haveit= for x in $CPPFLAGS; do @@ -31061,52 +31025,62 @@ fi done - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libxxhash" >&5 -$as_echo_n "checking for libxxhash... " >&6; } -if ${ac_cv_libxxhash+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libbabeltrace" >&5 +$as_echo_n "checking for libbabeltrace... " >&6; } +if ${ac_cv_libbabeltrace+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_LIBS="$LIBS" - LIBS="$LIBS $LIBXXHASH" + LIBS="$LIBS $LIBBABELTRACE" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include +#include + #include + #include int main () { -XXH32("foo", 3, 0); +struct bt_iter_pos *pos = bt_iter_get_pos (bt_ctf_get_iter (NULL)); + struct bt_ctf_event *event = NULL; + const struct bt_definition *scope; + + pos->type = BT_SEEK_BEGIN; + bt_iter_set_pos (bt_ctf_get_iter (NULL), pos); + scope = bt_ctf_get_top_level_scope (event, + BT_STREAM_EVENT_HEADER); + bt_ctf_get_uint64 (bt_ctf_get_field (event, scope, "id")); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_libxxhash=yes + ac_cv_libbabeltrace=yes else - ac_cv_libxxhash=no + ac_cv_libbabeltrace=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$ac_save_LIBS" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libxxhash" >&5 -$as_echo "$ac_cv_libxxhash" >&6; } - if test "$ac_cv_libxxhash" = yes; then - HAVE_LIBXXHASH=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libbabeltrace" >&5 +$as_echo "$ac_cv_libbabeltrace" >&6; } + if test "$ac_cv_libbabeltrace" = yes; then + HAVE_LIBBABELTRACE=yes -$as_echo "#define HAVE_LIBXXHASH 1" >>confdefs.h +$as_echo "#define HAVE_LIBBABELTRACE 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libxxhash" >&5 -$as_echo_n "checking how to link with libxxhash... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBXXHASH" >&5 -$as_echo "$LIBXXHASH" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libbabeltrace" >&5 +$as_echo_n "checking how to link with libbabeltrace... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBBABELTRACE" >&5 +$as_echo "$LIBBABELTRACE" >&6; } else - HAVE_LIBXXHASH=no + HAVE_LIBBABELTRACE=no CPPFLAGS="$ac_save_CPPFLAGS" - LIBXXHASH= - LTLIBXXHASH= + LIBBABELTRACE= + LTLIBBABELTRACE= fi @@ -31114,20 +31088,46 @@ $as_echo "$LIBXXHASH" >&6; } - if test "$HAVE_LIBXXHASH" != yes; then - if test "$with_xxhash" = yes; then - as_fn_error $? "xxhash is missing or unusable" "$LINENO" 5 - fi - fi - if test "x$with_xxhash" = "xauto"; then - with_xxhash="$HAVE_LIBXXHASH" + CFLAGS=$saved_CFLAGS + + if test "$HAVE_LIBBABELTRACE" != yes; then + if test "$with_babeltrace" = yes; then + as_fn_error $? "babeltrace is missing or unusable" "$LINENO" 5 + else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: babeltrace is missing or unusable; GDB is unable to read CTF data." >&5 +$as_echo "$as_me: WARNING: babeltrace is missing or unusable; GDB is unable to read CTF data." >&2;} + fi fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use xxhash" >&5 -$as_echo_n "checking whether to use xxhash... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_xxhash" >&5 -$as_echo "$with_xxhash" >&6; } + # Check whether --enable-libctf was given. +if test "${enable_libctf+set}" = set; then : + enableval=$enable_libctf; + case "$enableval" in + yes|no) ;; + *) as_fn_error $? "Argument to enable/disable libctf must be yes or no" "$LINENO" 5 ;; + esac + +else + enable_libctf=yes +fi + + +if test "${enable_libctf}" = yes; then + +$as_echo "#define ENABLE_LIBCTF 1" >>confdefs.h + + LIBCTF="../libctf/libctf.la" + CTF_DEPS="../libctf/libctf.la" +else + LIBCTF= + CTF_DEPS= +fi + + + +# If nativefile (NAT_FILE) is not set in configure.nat, we link to an +# empty version. NM_H= rm -f nm.h diff --git a/gdb/configure.ac b/gdb/configure.ac index d0c54ad3c02..cecf4a46bec 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -2152,11 +2152,6 @@ else fi fi -# Check for xxhash -AC_ARG_WITH(xxhash, - AS_HELP_STRING([--with-xxhash], [use libxxhash for hashing (faster) (auto/yes/no)]), - [], [with_xxhash=auto]) - GCC_ENABLE([libctf], [yes], [], [Handle .ctf type-info sections]) if test "${enable_libctf}" = yes; then AC_DEFINE(ENABLE_LIBCTF, 1, [Handle .ctf type-info sections]) @@ -2172,24 +2167,6 @@ AC_SUBST(CTF_DEPS) # If nativefile (NAT_FILE) is not set in configure.nat, we link to an # empty version. -if test "x$with_xxhash" != "xno"; then - AC_LIB_HAVE_LINKFLAGS([xxhash], [], - [#include ], - [XXH32("foo", 3, 0); - ]) - if test "$HAVE_LIBXXHASH" != yes; then - if test "$with_xxhash" = yes; then - AC_MSG_ERROR([xxhash is missing or unusable]) - fi - fi - if test "x$with_xxhash" = "xauto"; then - with_xxhash="$HAVE_LIBXXHASH" - fi -fi - -AC_MSG_CHECKING([whether to use xxhash]) -AC_MSG_RESULT([$with_xxhash]) - NM_H= rm -f nm.h if test "${nativefile}" != ""; then diff --git a/gdbserver/config.in b/gdbserver/config.in index 39ddc7c0edb..63876afcf85 100644 --- a/gdbserver/config.in +++ b/gdbserver/config.in @@ -143,6 +143,9 @@ /* Define if you have the ipt library. */ #undef HAVE_LIBIPT +/* Define if you have the xxhash library. */ +#undef HAVE_LIBXXHASH + /* Define if the target supports branch tracing. */ #undef HAVE_LINUX_BTRACE diff --git a/gdbserver/configure b/gdbserver/configure index 050264ed7da..e5e0cb14d03 100755 --- a/gdbserver/configure +++ b/gdbserver/configure @@ -656,6 +656,9 @@ am__leading_dot host_noncanonical target_noncanonical WIN32APILIBS +LTLIBXXHASH +LIBXXHASH +HAVE_LIBXXHASH LTLIBIPT LIBIPT HAVE_LIBIPT @@ -752,6 +755,9 @@ with_gnu_ld enable_rpath with_libipt_prefix with_libipt_type +with_xxhash +with_libxxhash_prefix +with_libxxhash_type enable_unit_tests with_ust with_ust_include @@ -1418,6 +1424,10 @@ Optional Packages: --with-libipt-prefix[=DIR] search for libipt in DIR/include and DIR/lib --without-libipt-prefix don't search for libipt in includedir and libdir --with-libipt-type=TYPE type of library to search for (auto/static/shared) + --with-xxhash use libxxhash for hashing (faster) (auto/yes/no) + --with-libxxhash-prefix[=DIR] search for libxxhash in DIR/include and DIR/lib + --without-libxxhash-prefix don't search for libxxhash in includedir and libdir + --with-libxxhash-type=TYPE type of library to search for (auto/static/shared) --with-ust=PATH Specify prefix directory for the installed UST package Equivalent to --with-ust-include=PATH/include plus --with-ust-lib=PATH/lib @@ -8947,6 +8957,510 @@ $as_echo "$bfd_cv_have_sys_procfs_type_elf_fpregset_t" >&6; } fi + # Check for xxhash + +# Check whether --with-xxhash was given. +if test "${with_xxhash+set}" = set; then : + withval=$with_xxhash; +else + with_xxhash=auto +fi + + + if test "x$with_xxhash" != "xno"; then + + + + + + + + + use_additional=yes + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + +# Check whether --with-libxxhash-prefix was given. +if test "${with_libxxhash_prefix+set}" = set; then : + withval=$with_libxxhash_prefix; + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + else + additional_includedir="$withval/include" + additional_libdir="$withval/lib" + fi + fi + +fi + + +# Check whether --with-libxxhash-type was given. +if test "${with_libxxhash_type+set}" = set; then : + withval=$with_libxxhash_type; with_libxxhash_type=$withval +else + with_libxxhash_type=auto +fi + + lib_type=`eval echo \$with_libxxhash_type` + + LIBXXHASH= + LTLIBXXHASH= + INCXXHASH= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='xxhash ' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }$value" + else + : + fi + else + found_dir= + found_la= + found_so= + found_a= + if test $use_additional = yes; then + if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext" && test x$lib_type != xstatic; then + found_dir="$additional_libdir" + found_so="$additional_libdir/lib$name.$shlibext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + elif test x$lib_type != xshared; then + if test -f "$additional_libdir/lib$name.$libext"; then + found_dir="$additional_libdir" + found_a="$additional_libdir/lib$name.$libext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIBXXHASH; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext" && test x$lib_type != xstatic; then + found_dir="$dir" + found_so="$dir/lib$name.$shlibext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + elif test x$lib_type != xshared; then + if test -f "$dir/lib$name.$libext"; then + found_dir="$dir" + found_a="$dir/lib$name.$libext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$found_so" + else + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + if test "$hardcode_direct" = yes; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$found_so" + else + if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$found_so" + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + haveit= + for x in $LDFLAGS $LIBXXHASH; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-L$found_dir" + fi + if test "$hardcode_minus_L" != no; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$found_so" + else + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$found_a" + else + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-L$found_dir -l$name" + fi + fi + additional_includedir= + case "$found_dir" in + */lib | */lib/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INCXXHASH; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + INCXXHASH="${INCXXHASH}${INCXXHASH:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + if test -n "$found_la"; then + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + if test "X$additional_libdir" != "X/usr/lib"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/lib"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIBXXHASH; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIBXXHASH; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$dep" + LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }$dep" + ;; + esac + done + fi + else + if test "x$lib_type" = "xauto" || test "x$lib_type" = "xshared"; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-l$name" + LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }-l$name" + else + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-l:lib$name.$libext" + LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }-l:lib$name.$libext" + fi + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$hardcode_libdir_separator"; then + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$flag" + else + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + for found_dir in $ltrpathdirs; do + LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }-R$found_dir" + done + fi + + + ac_save_CPPFLAGS="$CPPFLAGS" + + for element in $INCXXHASH; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libxxhash" >&5 +$as_echo_n "checking for libxxhash... " >&6; } +if ${ac_cv_libxxhash+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_LIBS="$LIBS" + LIBS="$LIBS $LIBXXHASH" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +XXH32("foo", 3, 0); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_libxxhash=yes +else + ac_cv_libxxhash=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$ac_save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libxxhash" >&5 +$as_echo "$ac_cv_libxxhash" >&6; } + if test "$ac_cv_libxxhash" = yes; then + HAVE_LIBXXHASH=yes + +$as_echo "#define HAVE_LIBXXHASH 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libxxhash" >&5 +$as_echo_n "checking how to link with libxxhash... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBXXHASH" >&5 +$as_echo "$LIBXXHASH" >&6; } + else + HAVE_LIBXXHASH=no + CPPFLAGS="$ac_save_CPPFLAGS" + LIBXXHASH= + LTLIBXXHASH= + fi + + + + + + + if test "$HAVE_LIBXXHASH" != yes; then + if test "$with_xxhash" = yes; then + as_fn_error $? "xxhash is missing or unusable" "$LINENO" 5 + fi + fi + if test "x$with_xxhash" = "xauto"; then + with_xxhash="$HAVE_LIBXXHASH" + fi + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use xxhash" >&5 +$as_echo_n "checking whether to use xxhash... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_xxhash" >&5 +$as_echo "$with_xxhash" >&6; } + # This is set by GDB_AC_COMMON. diff --git a/gdbsupport/Makefile.in b/gdbsupport/Makefile.in index 6aadae41031..6db76447d81 100644 --- a/gdbsupport/Makefile.in +++ b/gdbsupport/Makefile.in @@ -254,6 +254,7 @@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ HAVE_CXX11 = @HAVE_CXX11@ HAVE_LIBIPT = @HAVE_LIBIPT@ +HAVE_LIBXXHASH = @HAVE_LIBXXHASH@ INCINTL = @INCINTL@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ @@ -268,8 +269,10 @@ LIBINTL_DEP = @LIBINTL_DEP@ LIBIPT = @LIBIPT@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ +LIBXXHASH = @LIBXXHASH@ LTLIBIPT = @LTLIBIPT@ LTLIBOBJS = @LTLIBOBJS@ +LTLIBXXHASH = @LTLIBXXHASH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ diff --git a/gdbsupport/common.m4 b/gdbsupport/common.m4 index 0fed186ae1d..a08255da3e3 100644 --- a/gdbsupport/common.m4 +++ b/gdbsupport/common.m4 @@ -215,6 +215,30 @@ AC_DEFUN([GDB_AC_COMMON], [ BFD_HAVE_SYS_PROCFS_TYPE(psaddr_t) BFD_HAVE_SYS_PROCFS_TYPE(elf_fpregset_t) fi + + dnl xxhash support + # Check for xxhash + AC_ARG_WITH(xxhash, + AS_HELP_STRING([--with-xxhash], [use libxxhash for hashing (faster) (auto/yes/no)]), + [], [with_xxhash=auto]) + + if test "x$with_xxhash" != "xno"; then + AC_LIB_HAVE_LINKFLAGS([xxhash], [], + [#include ], + [XXH32("foo", 3, 0); + ]) + if test "$HAVE_LIBXXHASH" != yes; then + if test "$with_xxhash" = yes; then + AC_MSG_ERROR([xxhash is missing or unusable]) + fi + fi + if test "x$with_xxhash" = "xauto"; then + with_xxhash="$HAVE_LIBXXHASH" + fi + fi + + AC_MSG_CHECKING([whether to use xxhash]) + AC_MSG_RESULT([$with_xxhash]) ]) dnl Check that the provided value ($1) is either "yes" or "no". If not, diff --git a/gdbsupport/config.in b/gdbsupport/config.in index 577866c97b3..2cdc1fbde61 100644 --- a/gdbsupport/config.in +++ b/gdbsupport/config.in @@ -124,6 +124,9 @@ /* Define if you have the ipt library. */ #undef HAVE_LIBIPT +/* Define if you have the xxhash library. */ +#undef HAVE_LIBXXHASH + /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_ELF_H diff --git a/gdbsupport/configure b/gdbsupport/configure index 38541e87c15..a0e4a3f94a4 100755 --- a/gdbsupport/configure +++ b/gdbsupport/configure @@ -631,6 +631,9 @@ HAVE_PIPE_OR_PIPE2_FALSE HAVE_PIPE_OR_PIPE2_TRUE SELFTEST_FALSE SELFTEST_TRUE +LTLIBXXHASH +LIBXXHASH +HAVE_LIBXXHASH LTLIBIPT LIBIPT HAVE_LIBIPT @@ -776,6 +779,9 @@ with_gnu_ld enable_rpath with_libipt_prefix with_libipt_type +with_xxhash +with_libxxhash_prefix +with_libxxhash_type enable_unit_tests enable_werror enable_build_warnings @@ -1442,6 +1448,10 @@ Optional Packages: --with-libipt-prefix[=DIR] search for libipt in DIR/include and DIR/lib --without-libipt-prefix don't search for libipt in includedir and libdir --with-libipt-type=TYPE type of library to search for (auto/static/shared) + --with-xxhash use libxxhash for hashing (faster) (auto/yes/no) + --with-libxxhash-prefix[=DIR] search for libxxhash in DIR/include and DIR/lib + --without-libxxhash-prefix don't search for libxxhash in includedir and libdir + --with-libxxhash-type=TYPE type of library to search for (auto/static/shared) Some influential environment variables: CC C compiler command @@ -9963,6 +9973,510 @@ $as_echo "$bfd_cv_have_sys_procfs_type_elf_fpregset_t" >&6; } fi + # Check for xxhash + +# Check whether --with-xxhash was given. +if test "${with_xxhash+set}" = set; then : + withval=$with_xxhash; +else + with_xxhash=auto +fi + + + if test "x$with_xxhash" != "xno"; then + + + + + + + + + use_additional=yes + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + +# Check whether --with-libxxhash-prefix was given. +if test "${with_libxxhash_prefix+set}" = set; then : + withval=$with_libxxhash_prefix; + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + else + additional_includedir="$withval/include" + additional_libdir="$withval/lib" + fi + fi + +fi + + +# Check whether --with-libxxhash-type was given. +if test "${with_libxxhash_type+set}" = set; then : + withval=$with_libxxhash_type; with_libxxhash_type=$withval +else + with_libxxhash_type=auto +fi + + lib_type=`eval echo \$with_libxxhash_type` + + LIBXXHASH= + LTLIBXXHASH= + INCXXHASH= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='xxhash ' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }$value" + else + : + fi + else + found_dir= + found_la= + found_so= + found_a= + if test $use_additional = yes; then + if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext" && test x$lib_type != xstatic; then + found_dir="$additional_libdir" + found_so="$additional_libdir/lib$name.$shlibext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + elif test x$lib_type != xshared; then + if test -f "$additional_libdir/lib$name.$libext"; then + found_dir="$additional_libdir" + found_a="$additional_libdir/lib$name.$libext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIBXXHASH; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext" && test x$lib_type != xstatic; then + found_dir="$dir" + found_so="$dir/lib$name.$shlibext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + elif test x$lib_type != xshared; then + if test -f "$dir/lib$name.$libext"; then + found_dir="$dir" + found_a="$dir/lib$name.$libext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$found_so" + else + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + if test "$hardcode_direct" = yes; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$found_so" + else + if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$found_so" + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + haveit= + for x in $LDFLAGS $LIBXXHASH; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-L$found_dir" + fi + if test "$hardcode_minus_L" != no; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$found_so" + else + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$found_a" + else + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-L$found_dir -l$name" + fi + fi + additional_includedir= + case "$found_dir" in + */lib | */lib/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INCXXHASH; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + INCXXHASH="${INCXXHASH}${INCXXHASH:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + if test -n "$found_la"; then + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + if test "X$additional_libdir" != "X/usr/lib"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/lib"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIBXXHASH; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIBXXHASH; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$dep" + LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }$dep" + ;; + esac + done + fi + else + if test "x$lib_type" = "xauto" || test "x$lib_type" = "xshared"; then + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-l$name" + LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }-l$name" + else + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }-l:lib$name.$libext" + LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }-l:lib$name.$libext" + fi + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$hardcode_libdir_separator"; then + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$flag" + else + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBXXHASH="${LIBXXHASH}${LIBXXHASH:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + for found_dir in $ltrpathdirs; do + LTLIBXXHASH="${LTLIBXXHASH}${LTLIBXXHASH:+ }-R$found_dir" + done + fi + + + ac_save_CPPFLAGS="$CPPFLAGS" + + for element in $INCXXHASH; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libxxhash" >&5 +$as_echo_n "checking for libxxhash... " >&6; } +if ${ac_cv_libxxhash+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_save_LIBS="$LIBS" + LIBS="$LIBS $LIBXXHASH" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +XXH32("foo", 3, 0); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_libxxhash=yes +else + ac_cv_libxxhash=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$ac_save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libxxhash" >&5 +$as_echo "$ac_cv_libxxhash" >&6; } + if test "$ac_cv_libxxhash" = yes; then + HAVE_LIBXXHASH=yes + +$as_echo "#define HAVE_LIBXXHASH 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libxxhash" >&5 +$as_echo_n "checking how to link with libxxhash... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBXXHASH" >&5 +$as_echo "$LIBXXHASH" >&6; } + else + HAVE_LIBXXHASH=no + CPPFLAGS="$ac_save_CPPFLAGS" + LIBXXHASH= + LTLIBXXHASH= + fi + + + + + + + if test "$HAVE_LIBXXHASH" != yes; then + if test "$with_xxhash" = yes; then + as_fn_error $? "xxhash is missing or unusable" "$LINENO" 5 + fi + fi + if test "x$with_xxhash" = "xauto"; then + with_xxhash="$HAVE_LIBXXHASH" + fi + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use xxhash" >&5 +$as_echo_n "checking whether to use xxhash... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_xxhash" >&5 +$as_echo "$with_xxhash" >&6; } + # Check whether we will enable the inclusion of unit tests when # compiling GDB. From patchwork Tue Dec 6 13:57:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 61558 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id EE99F3848E3C for ; Tue, 6 Dec 2022 14:00:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EE99F3848E3C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1670335205; bh=HD9Gks682L+7fwmyV1JmnJMro6WJIYPvmOXawtu1wrw=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=GYYBm9q67xCBecJQLwpUz8FEN6OdnhM+0Rse5ZEd1QwTXuDUa6ADbFeVRTh8c/omy nwlT4bD8pvHTctI2GmkW2ABBlcnIaxLO+43TMZCCuvC81W2IflOdBQ4CvSmB5lyURr 5Xki0CiBcU+NVQEnGnmRHuMLGKr06wrgay6eh+aI= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id 2A2AC3864A3C for ; Tue, 6 Dec 2022 13:57:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2A2AC3864A3C X-ASG-Debug-ID: 1670335052-0c856e762a1bb00001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id pDLI5TdZYobDkJA8 (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO); Tue, 06 Dec 2022 08:57:33 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@efficios.com X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from epycamd.internal.efficios.com (192-222-180-24.qc.cable.ebox.net [192.222.180.24]) by smtp.ebox.ca (Postfix) with ESMTP id E7551441B21; Tue, 6 Dec 2022 08:57:32 -0500 (EST) X-Barracuda-RBL-IP: 192.222.180.24 X-Barracuda-Effective-Source-IP: 192-222-180-24.qc.cable.ebox.net[192.222.180.24] X-Barracuda-Apparent-Source-IP: 192.222.180.24 To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 08/12] gdbsupport: move fast_hash to gdbsupport/common-utils.h Date: Tue, 6 Dec 2022 08:57:25 -0500 X-ASG-Orig-Subj: [PATCH 08/12] gdbsupport: move fast_hash to gdbsupport/common-utils.h Message-Id: <20221206135729.3937767-9-simon.marchi@efficios.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221206135729.3937767-1-simon.marchi@efficios.com> References: <20221206135729.3937767-1-simon.marchi@efficios.com> MIME-Version: 1.0 X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1670335053 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 2641 X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=5.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.102644 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Spam-Status: No, score=-3498.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_SOFTFAIL, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" The following patch adds a hash type for gdb::string_view in gdbsupport, which will use the fast_hash function. Move the latter to gdbsupport. Change-Id: Id74510e17801e775bd5ffa5f443713d79adf14ad --- gdb/utils.h | 19 ------------------- gdbsupport/common-utils.h | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/gdb/utils.h b/gdb/utils.h index d2acf899ba2..65080a9b9ce 100644 --- a/gdb/utils.h +++ b/gdb/utils.h @@ -26,10 +26,6 @@ #include "gdbsupport/scoped_restore.h" #include -#ifdef HAVE_LIBXXHASH -#include -#endif - struct completion_match_for_lcd; class compiled_regex; @@ -365,19 +361,4 @@ extern void copy_bitwise (gdb_byte *dest, ULONGEST dest_offset, const gdb_byte *source, ULONGEST source_offset, ULONGEST nbits, int bits_big_endian); -/* A fast hashing function. This can be used to hash data in a fast way - when the length is known. If no fast hashing library is available, falls - back to iterative_hash from libiberty. START_VALUE can be set to - continue hashing from a previous value. */ - -static inline unsigned int -fast_hash (const void *ptr, size_t len, unsigned int start_value = 0) -{ -#ifdef HAVE_LIBXXHASH - return XXH64 (ptr, len, start_value); -#else - return iterative_hash (ptr, len, start_value); -#endif -} - #endif /* UTILS_H */ diff --git a/gdbsupport/common-utils.h b/gdbsupport/common-utils.h index 8a9448a638b..fae77640666 100644 --- a/gdbsupport/common-utils.h +++ b/gdbsupport/common-utils.h @@ -27,6 +27,12 @@ #include "poison.h" #include "gdb_string_view.h" +#if defined HAVE_LIBXXHASH +# include +#else +# include "hashtab.h" +#endif + /* xmalloc(), xrealloc() and xcalloc() have already been declared in "libiberty.h". */ @@ -172,4 +178,19 @@ extern int hex2bin (const char *hex, gdb_byte *bin, int count); /* Like the above, but return a gdb::byte_vector. */ gdb::byte_vector hex2bin (const char *hex); +/* A fast hashing function. This can be used to hash data in a fast way + when the length is known. If no fast hashing library is available, falls + back to iterative_hash from libiberty. START_VALUE can be set to + continue hashing from a previous value. */ + +static inline unsigned int +fast_hash (const void *ptr, size_t len, unsigned int start_value = 0) +{ +#if defined HAVE_LIBXXHASH + return XXH64 (ptr, len, start_value); +#else + return iterative_hash (ptr, len, start_value); +#endif +} + #endif /* COMMON_COMMON_UTILS_H */ From patchwork Tue Dec 6 13:57:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 61557 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id BA4FC384699E for ; Tue, 6 Dec 2022 13:59:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BA4FC384699E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1670335177; bh=uYBW1yUdu2aecU/6Gu0fOFB83UYo3jpgFs4x1p6rIP8=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=q5PlFuvexJE1ME3i23ckv4OJzmIHByXdSqgYFxrT3kUySY24Nicjrod2aJ7H8Dkcr 6bKAJ2R25XmHVQLY7Kg4Yo3magbkQvwnHRsbu/HZcxLmsyx3OyiGsWeYsHqtLiXkCK O7KjPDBsuuk+nsldomwtPBmsoZb+OGqqBC/2OaUA= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id 2A2D03864A3F for ; Tue, 6 Dec 2022 13:57:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2A2D03864A3F X-ASG-Debug-ID: 1670335053-0c856e762b1bb30001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id AMoEWahDg77g7HSc (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO); Tue, 06 Dec 2022 08:57:33 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@efficios.com X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from epycamd.internal.efficios.com (192-222-180-24.qc.cable.ebox.net [192.222.180.24]) by smtp.ebox.ca (Postfix) with ESMTP id 0C196441D64; Tue, 6 Dec 2022 08:57:33 -0500 (EST) X-Barracuda-RBL-IP: 192.222.180.24 X-Barracuda-Effective-Source-IP: 192-222-180-24.qc.cable.ebox.net[192.222.180.24] X-Barracuda-Apparent-Source-IP: 192.222.180.24 To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 09/12] gdbsupport: add gdb::string_view_hash Date: Tue, 6 Dec 2022 08:57:26 -0500 X-ASG-Orig-Subj: [PATCH 09/12] gdbsupport: add gdb::string_view_hash Message-Id: <20221206135729.3937767-10-simon.marchi@efficios.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221206135729.3937767-1-simon.marchi@efficios.com> References: <20221206135729.3937767-1-simon.marchi@efficios.com> MIME-Version: 1.0 X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1670335053 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 1590 X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=5.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.102644 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Spam-Status: No, score=-3498.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_SOFTFAIL, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" Add the string_view_hash type, which will be useful to be able to use gdb::string_view as std::unordered_map keys. Use it in gdb/symtab.c, to exercise it. Change-Id: Id69a466ab19a9f6620b5df8a2dd29b5cddd94c00 --- gdb/symtab.c | 2 +- gdbsupport/common-utils.h | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/gdb/symtab.c b/gdb/symtab.c index 0d342f765f2..f6ddd8e3c41 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -812,7 +812,7 @@ hash_demangled_name_entry (const void *data) const struct demangled_name_entry *e = (const struct demangled_name_entry *) data; - return fast_hash (e->mangled.data (), e->mangled.length ()); + return gdb::string_view_hash () (e->mangled); } /* Equality function for the demangled name hash. */ diff --git a/gdbsupport/common-utils.h b/gdbsupport/common-utils.h index fae77640666..2525d287c87 100644 --- a/gdbsupport/common-utils.h +++ b/gdbsupport/common-utils.h @@ -193,4 +193,21 @@ fast_hash (const void *ptr, size_t len, unsigned int start_value = 0) #endif } +namespace gdb +{ + +/* Hash type for gdb::string_view. + + Even after we switch to C++17 and dump our string_view implementation, we + might want to keep this hash implementation if it's faster than std::hash + for std::string_view. */ + +struct string_view_hash +{ + std::size_t operator() (gdb::string_view view) const + { return fast_hash (view.data (), view.length ()); } +}; + +} /* namespace gdb */ + #endif /* COMMON_COMMON_UTILS_H */ From patchwork Tue Dec 6 13:57:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 61560 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 60D8438469B2 for ; Tue, 6 Dec 2022 14:00:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 60D8438469B2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1670335236; bh=oFy9+R+yWvPjjgET9ndvYfItLGWDIM+Cd9lxDoJmhJg=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=lxx0I2mQ7EZnPcB4q88EDkdTtRmBIz9zLjImfNIonBl+v6XgNeYv7DAS+RlddI9MP D7qUDaDNhTx46sqRBf3tfc9jtS68XTGHpjKhaARXn0cPj2HHhB8cW59VNmzN3gb9vq Dbwz0qZHv7wod5Csqx0tWGe9Bu4YjKh2hHNjyB/k= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id 1E2F53848E30 for ; Tue, 6 Dec 2022 13:58:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1E2F53848E30 X-ASG-Debug-ID: 1670335113-0c856e762a1bc10001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id unqNKzZsBL9jQ45T (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO); Tue, 06 Dec 2022 08:58:33 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@efficios.com X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from epycamd.internal.efficios.com (192-222-180-24.qc.cable.ebox.net [192.222.180.24]) by smtp.ebox.ca (Postfix) with ESMTP id 32147441B21; Tue, 6 Dec 2022 08:58:33 -0500 (EST) X-Barracuda-RBL-IP: 192.222.180.24 X-Barracuda-Effective-Source-IP: 192-222-180-24.qc.cable.ebox.net[192.222.180.24] X-Barracuda-Apparent-Source-IP: 192.222.180.24 To: gdb-patches@sourceware.org Cc: Simon Marchi , Lancelot SIX Subject: [PATCH 10/12] gdb/solib-svr4: don't disable probes interface if probe not found Date: Tue, 6 Dec 2022 08:57:27 -0500 X-ASG-Orig-Subj: [PATCH 10/12] gdb/solib-svr4: don't disable probes interface if probe not found Message-Id: <20221206135729.3937767-11-simon.marchi@efficios.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221206135729.3937767-1-simon.marchi@efficios.com> References: <20221206135729.3937767-1-simon.marchi@efficios.com> MIME-Version: 1.0 X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1670335113 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 2844 X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=5.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.102645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Spam-Status: No, score=-3498.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_SOFTFAIL, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" In ROCm-GDB, we install an solib provider for the GPU code objects on top of the svr4 provider for the host, in order to add solibs representing the GPU code objects to the solib list containing the host process' shared libraries. We override the target_so_ops::handle_event function pointer with our own, in which we call svr4_so_ops.handle_event (which contains svr4_handle_solib_event) manually. When the host (un)loads a library, the ROCm part of handle_event is a no-op. When the GPU (un)loads a code object, we want the host side (svr4) to be a no-op. The problem is that when handle_event is called because of a GPU event, svr4_handle_solib_event gets called while not stopped at an svr4 probe. It then assumes this means there's a problem with the probes interface and disables it through the following sequence of events: - solib_event_probe_at return nullptr - svr4_handle_solib_event returns early - the make_scope_exit callback calls disable_probes_interface We could fix that by making the ROCm handle_event callback check if an svr4 probe is that the stop address, and only call svr4_so_ops.handle_event if so. However, it doesn't feel right to include some svr4 implementation detail in the ROCm event handler. Instead, this patch changes svr4_handle_solib_event to not assume it is an error if called while not at an svr4 probe location, and therefore not disable the probes interface. That just means moving the make_scope_exit call below where we lookup the probe by pc. Change-Id: Ie8ddf5beffa2e92b8ebfdd016454546252519244 Co-Authored-By: Lancelot SIX --- gdb/solib-svr4.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 63baaf80921..9fc68c11a0e 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -1977,6 +1977,16 @@ svr4_handle_solib_event (void) if (info->probes_table == NULL) return; + pc = regcache_read_pc (get_current_regcache ()); + pa = solib_event_probe_at (info, pc); + if (pa == nullptr) + { + /* When some solib ops sits above us, it can respond to a solib event + by calling in here. This is done assuming that if the current event + is not an SVR4 solib event, calling here should be a no-op. */ + return; + } + /* If anything goes wrong we revert to the original linker interface. */ auto cleanup = make_scope_exit ([info] () @@ -1984,11 +1994,6 @@ svr4_handle_solib_event (void) disable_probes_interface (info); }); - pc = regcache_read_pc (get_current_regcache ()); - pa = solib_event_probe_at (info, pc); - if (pa == NULL) - return; - action = solib_event_probe_action (pa); if (action == PROBES_INTERFACE_FAILED) return; From patchwork Tue Dec 6 13:57:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 61559 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 054C2384231B for ; Tue, 6 Dec 2022 14:00:17 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 054C2384231B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1670335217; bh=8T37WLmRrUg37gS0zwAO0PU29P7FzJ18XksJLuZk1k0=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=oU9C026uisd9rjzTRRXBXgu7p5RlV5PzjTxa39pAiOEeZUy0dcxqppsPTqCqYnver V5A7nTx6kYSwdlRG5j3ILDQT7YHgG/eOhc1OvHyrEHN7SXhE9zd6Xq/oAeSkgM7i9q 0oQvOalJmgvwD+C4YusaU9NqgRenQsjFjbkcjA9c= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id B9A6938469BA for ; Tue, 6 Dec 2022 13:58:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B9A6938469BA X-ASG-Debug-ID: 1670335113-0c856e762b1bc40001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id RacmOdscdx3Gj9Z6 (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO); Tue, 06 Dec 2022 08:58:33 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@efficios.com X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from epycamd.internal.efficios.com (192-222-180-24.qc.cable.ebox.net [192.222.180.24]) by smtp.ebox.ca (Postfix) with ESMTP id 4AFE2441D64; Tue, 6 Dec 2022 08:58:33 -0500 (EST) X-Barracuda-RBL-IP: 192.222.180.24 X-Barracuda-Effective-Source-IP: 192-222-180-24.qc.cable.ebox.net[192.222.180.24] X-Barracuda-Apparent-Source-IP: 192.222.180.24 To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 11/12] gdb: make gdb_printing_disassembler::stream public Date: Tue, 6 Dec 2022 08:57:28 -0500 X-ASG-Orig-Subj: [PATCH 11/12] gdb: make gdb_printing_disassembler::stream public Message-Id: <20221206135729.3937767-12-simon.marchi@efficios.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221206135729.3937767-1-simon.marchi@efficios.com> References: <20221206135729.3937767-1-simon.marchi@efficios.com> MIME-Version: 1.0 X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1670335113 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 1093 X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=5.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.102645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Spam-Status: No, score=-3498.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_SOFTFAIL, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" In the ROCm port, we need to access the underlying stream of a gdb_printing_disassembler, so make it public. The reason we need to access it is to know whether it supports style escape code. We then pass that information to a temporary string_file we use while symbolizing addresses. Change-Id: Ib95755a4a45b8f6478787993e9f904df60dd8dc1 --- gdb/disasm.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gdb/disasm.h b/gdb/disasm.h index d6aec9a4705..b78374dd63f 100644 --- a/gdb/disasm.h +++ b/gdb/disasm.h @@ -123,12 +123,12 @@ struct gdb_printing_disassembler : public gdb_disassemble_info { DISABLE_COPY_AND_ASSIGN (gdb_printing_disassembler); -protected: - /* The stream that disassembler output is being written too. */ struct ui_file *stream () { return m_stream; } +protected: + /* Constructor. All the arguments are just passed to the parent class. We also add the two print functions to the arguments passed to the parent. See gdb_disassemble_info for a description of how the From patchwork Tue Dec 6 13:57:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 61561 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 49CF8384C932 for ; Tue, 6 Dec 2022 14:01:26 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 49CF8384C932 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1670335286; bh=Y6y2zG5tc3Cfd9lVKqWq+u4hRY0AXmvywhuYU+N/euk=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=C39FbrByVXQ2slTS1GaC/61BfoxOoPMqHkOQCiRRtp957iry9AAwcoAeuHICCXmQf imQBxYaGyra6xgQk57OSWd0n6ueRGGhrKeQX4WI/LF7K2dPYkYii+P7fmLH2n52asm zlb8fen+6tc71L06LlaTxmYz7xIPQUi7LPvpxGyY= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id B6C2D38469B9 for ; Tue, 6 Dec 2022 13:58:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B6C2D38469B9 X-ASG-Debug-ID: 1670335113-0c856e762a1bc20001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id 2KpttucKoHL324uk (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO); Tue, 06 Dec 2022 08:58:33 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@efficios.com X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from epycamd.internal.efficios.com (192-222-180-24.qc.cable.ebox.net [192.222.180.24]) by smtp.ebox.ca (Postfix) with ESMTP id 725E2441B21; Tue, 6 Dec 2022 08:58:33 -0500 (EST) X-Barracuda-RBL-IP: 192.222.180.24 X-Barracuda-Effective-Source-IP: 192-222-180-24.qc.cable.ebox.net[192.222.180.24] X-Barracuda-Apparent-Source-IP: 192.222.180.24 To: gdb-patches@sourceware.org Cc: Simon Marchi , Zoran Zaric , Laurent Morichetti , Tony Tye , Lancelot SIX , Pedro Alves Subject: [PATCH 12/12] gdb: initial support for ROCm platform (AMDGPU) debugging Date: Tue, 6 Dec 2022 08:57:29 -0500 X-ASG-Orig-Subj: [PATCH 12/12] gdb: initial support for ROCm platform (AMDGPU) debugging Message-Id: <20221206135729.3937767-13-simon.marchi@efficios.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221206135729.3937767-1-simon.marchi@efficios.com> References: <20221206135729.3937767-1-simon.marchi@efficios.com> MIME-Version: 1.0 X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1670335113 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 218806 X-Barracuda-Spam-Score: -1001.00 X-Barracuda-Spam-Status: No, SCORE=-1001.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=5.0 X-Spam-Status: No, score=-3497.7 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, KAM_LINEPADDING, KAM_SHORT, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_SOFTFAIL, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Simon Marchi via Gdb-patches From: Simon Marchi Reply-To: Simon Marchi Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" This patch adds the foundation for GDB to be able to debug programs offloaded to AMD GPUs using the AMD ROCm platform [1]. The latest public release of the ROCm release at the time of writing is 5.4, so this is what this patch targets. The ROCm platform allows host programs to schedule bits of code for execution on GPUs or similar accelerators. The programs running on GPUs are typically referred to as `kernels` (not related to operating system kernels). Programs offloaded with the AMD ROCm platform can be written in the HIP language [2], OpenCL and OpenMP, but we're going to focus on HIP here. The HIP language consists of a C++ Runtime API and kernel language. Here's an example of a very simple HIP program: #include "hip/hip_runtime.h" #include __global__ void do_an_addition (int a, int b, int *out) { *out = a + b; } int main () { int *result_ptr, result; /* Allocate memory for the device to write the result to. */ hipError_t error = hipMalloc (&result_ptr, sizeof (int)); assert (error == hipSuccess); /* Run `do_an_addition` on one workgroup containing one work item. */ do_an_addition<<>> (1, 2, result_ptr); /* Copy result from device to host. Note that this acts as a synchronization point, waiting for the kernel dispatch to complete. */ error = hipMemcpyDtoH (&result, result_ptr, sizeof (int)); assert (error == hipSuccess); printf ("result is %d\n", result); assert (result == 3); return 0; } This program can be compiled with: $ hipcc simple.cpp -g -O0 -o simple ... where `hipcc` is the HIP compiler, shipped with ROCm releases. This generates an ELF binary for the host architecture, containing another ELF binary with the device code. The ELF for the device can be inspected with: $ roc-obj-ls simple 1 host-x86_64-unknown-linux file://simple#offset=8192&size=0 1 hipv4-amdgcn-amd-amdhsa--gfx906 file://simple#offset=8192&size=34216 $ roc-obj-extract 'file://simple#offset=8192&size=34216' $ file simple-offset8192-size34216.co simple-offset8192-size34216.co: ELF 64-bit LSB shared object, *unknown arch 0xe0* version 1, dynamically linked, with debug_info, not stripped ^ amcgcn architecture that my `file` doesn't know about ----´ Running the program gives the very unimpressive result: $ ./simple result is 3 While running, this host program has copied the device program into the GPU's memory and spawned an execution thread on it. The goal of this GDB port is to let the user debug host threads and these GPU threads simultaneously. Here's a sample session using a GDB with this patch applied: $ ./gdb -q -nx --data-directory=data-directory ./simple Reading symbols from ./simple... (gdb) break do_an_addition Function "do_an_addition" not defined. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 1 (do_an_addition) pending. (gdb) r Starting program: /home/smarchi/build/binutils-gdb-amdgpu/gdb/simple [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". [New Thread 0x7ffff5db7640 (LWP 1082911)] [New Thread 0x7ffef53ff640 (LWP 1082913)] [Thread 0x7ffef53ff640 (LWP 1082913) exited] [New Thread 0x7ffdecb53640 (LWP 1083185)] [New Thread 0x7ffff54bf640 (LWP 1083186)] [Thread 0x7ffdecb53640 (LWP 1083185) exited] [Switching to AMDGPU Wave 2:2:1:1 (0,0,0)/0] Thread 6 hit Breakpoint 1, do_an_addition (a=, b=, out=) at simple.cpp:24 24 *out = a + b; (gdb) info inferiors Num Description Connection Executable * 1 process 1082907 1 (native) /home/smarchi/build/binutils-gdb-amdgpu/gdb/simple (gdb) info threads Id Target Id Frame 1 Thread 0x7ffff5dc9240 (LWP 1082907) "simple" 0x00007ffff5e9410b in ?? () from /opt/rocm-5.4.0/lib/libhsa-runtime64.so.1 2 Thread 0x7ffff5db7640 (LWP 1082911) "simple" __GI___ioctl (fd=3, request=3222817548) at ../sysdeps/unix/sysv/linux/ioctl.c:36 5 Thread 0x7ffff54bf640 (LWP 1083186) "simple" __GI___ioctl (fd=3, request=3222817548) at ../sysdeps/unix/sysv/linux/ioctl.c:36 * 6 AMDGPU Wave 2:2:1:1 (0,0,0)/0 do_an_addition ( a=, b=, out=) at simple.cpp:24 (gdb) bt Python Exception : Unhandled dwarf expression opcode 0xe1 #0 do_an_addition (a=, b=, out=) at simple.cpp:24 (gdb) continue Continuing. result is 3 warning: Temporarily disabling breakpoints for unloaded shared library "file:///home/smarchi/build/binutils-gdb-amdgpu/gdb/simple#offset=8192&size=67208" [Thread 0x7ffff54bf640 (LWP 1083186) exited] [Thread 0x7ffff5db7640 (LWP 1082911) exited] [Inferior 1 (process 1082907) exited normally] One thing to notice is the host and GPU threads appearing under the same inferior. This is a design goal for us, as programmers tend to think of the threads running on the GPU as part of the same program as the host threads, so showing them in the same inferior in GDB seems natural. Also, the host and GPU threads share a global memory space, which fits the inferior model. Another thing to notice is the error messages when trying to read variables or printing a backtrace. This is expected for the moment, since the AMD GPU compiler produces some DWARF that uses some non-standard extensions: https://llvm.org/docs/AMDGPUDwarfExtensionsForHeterogeneousDebugging.html There were already some patches posted by Zoran Zaric earlier to make GDB support these extensions: https://inbox.sourceware.org/gdb-patches/20211105113849.118800-1-zoran.zaric@amd.com/ We think it's better to get the basic support for AMD GPU in first, which will then give a better justification for GDB to support these extensions. GPU threads are named `AMDGPU Wave`: a wave is essentially a hardware thread using the SIMT (single-instruction, multiple-threads) [3] execution model. GDB uses the amd-dbgapi library [4], included in the ROCm platform, for a few things related to AMD GPU threads debugging. Different components talk to the library, as show on the following diagram: +---------------------------+ +-------------+ +------------------+ | GDB | amd-dbgapi target | <-> | AMD | | Linux kernel | | +-------------------+ | Debugger | +--------+ | | | amdgcn gdbarch | <-> | API | <=> | AMDGPU | | | +-------------------+ | | | driver | | | | solib-rocm | <-> | (dbgapi.so) | +--------+---------+ +---------------------------+ +-------------+ - The amd-dbgapi target is a target_ops implementation used to control execution of GPU threads. While the debugging of host threads works by using the ptrace / wait Linux kernel interface (as usual), control of GPU threads is done through a special interface (dubbed `kfd`) exposed by the `amdgpu` Linux kernel module. GDB doesn't interact directly with `kfd`, but instead goes through the amd-dbgapi library (AMD Debugger API on the diagram). Since it provides execution control, the amd-dbgapi target should normally be a process_stratum_target, not just a target_ops. More on that later. - The amdgcn gdbarch (describing the hardware architecture of the GPU execution units) offloads some requests to the amd-dbgapi library, so that knowledge about the various architectures doesn't need to be duplicated and baked in GDB. This is for example for things like the list of registers. - The solib-rocm component is an solib provider that fetches the list of code objects loaded on the device from the amd-dbgapi library, and makes GDB read their symbols. This is very similar to other solib providers that handle shared libraries, except that here the shared libraries are the pieces of code loaded on the device. Given that Linux host threads are managed by the linux-nat target, and the GPU threads are managed by the amd-dbgapi target, having all threads appear in the same inferior requires the two targets to be in that inferior's target stack. However, there can only be one process_stratum_target in a given target stack, since there can be only one target per slot. To achieve it, we therefore resort the hack^W solution of placing the amd-dbgapi target in the arch_stratum slot of the target stack, on top of the linux-nat target. Doing so allows the amd-dbgapi target to intercept target calls and handle them if they concern GPU threads, and offload to beneath otherwise. See amd_dbgapi_target::fetch_registers for a simple example: void amd_dbgapi_target::fetch_registers (struct regcache *regcache, int regno) { if (!ptid_is_gpu (regcache->ptid ())) { beneath ()->fetch_registers (regcache, regno); return; } // handle it } ptids of GPU threads are crafted with the following pattern: (pid, 1, wave id) Where pid is the inferior's pid and "wave id" is the wave handle handed to us by the amd-dbgapi library (in practice, a monotonically incrementing integer). The idea is that on Linux systems, the combination (pid != 1, lwp == 1) is not possible. lwp == 1 would always belong to the init process, which would also have pid == 1 (and it's improbable for the init process to offload work to the GPU and much less for the user to debug it). We can therefore differentiate GPU and non-GPU ptids this way. See ptid_is_gpu for more details. Note that we believe that this scheme could break down in the context of containers, where the initial process executed in a container has pid 1 (in its own pid namespace). For instance, if you were to execute a ROCm program in a container, then spawn a GDB in that container and attach to the process, it will likely not work. This is a known limitation. A workaround for this is to have a dummy process (like a shell) fork and execute the program of interest. The amd-dbgapi target watches native inferiors, and "attaches" to them using amd_dbgapi_process_attach, which gives it a notifier fd that is registered in the event loop (see enable_amd_dbgapi). Note that this isn't the same "attach" as in PTRACE_ATTACH, but being ptrace-attached is a precondition for amd_dbgapi_process_attach to work. When the debugged process enables the ROCm runtime, the amd-dbgapi target gets notified through that fd, and pushes itself on the target stack of the inferior. The amd-dbgapi target is then able to intercept target_ops calls. If the debugged process disables the ROCm runtime, the amd-dbgapi target unpushes itself from the target stack. This way, the amd-dbgapi target's footprint stays minimal when debugging a process that doesn't use the AMD ROCm platform, it does not intercept target calls. The amd-dbgapi library is found using pkg-config. Since enabling support for the amdgpu architecture (amdgpu-tdep.c) depends on the amd-dbgapi library being present, we have the following logic for the interaction with --target and --enable-targets: - if the user explicitly asks for amdgcn support with --target=amdgcn-*-* or --enable-targets=amdgcn-*-*, we probe for the amd-dbgapi and fail if not found - if the user uses --enable-targets=all, we probe for amd-dbgapi, enable amdgcn support if found, disable amdgcn support if not found - if the user uses --enable-targets=all and --with-amd-dbgapi=yes, we probe for amd-dbgapi, enable amdgcn if found and fail if not found - if the user uses --enable-targets=all and --with-amd-dbgapi=no, we do not probe for amd-dbgapi, disable amdgcn support - otherwise, amd-dbgapi is not probed for and support for amdgcn is not enabled Finally, a simple test is included. It only tests hitting a breakpoint in device code and resuming execution, pretty much like the example shown above. [1] https://docs.amd.com/category/ROCm_v5.4 [2] https://docs.amd.com/bundle/HIP-Programming-Guide-v5.4 [3] https://en.wikipedia.org/wiki/Single_instruction,_multiple_threads [4] https://docs.amd.com/bundle/ROCDebugger-API-Guide-v5.4 Change-Id: I591edca98b8927b1e49e4b0abe4e304765fed9ee Co-Authored-By: Zoran Zaric Co-Authored-By: Laurent Morichetti Co-Authored-By: Tony Tye Co-Authored-By: Lancelot SIX Co-Authored-By: Pedro Alves --- gdb/Makefile.in | 17 +- gdb/NEWS | 7 + gdb/README | 15 + gdb/amd-dbgapi-target.c | 1966 +++++++++++++++++++++++++++++ gdb/amd-dbgapi-target.h | 116 ++ gdb/amdgpu-tdep.c | 1367 ++++++++++++++++++++ gdb/amdgpu-tdep.h | 93 ++ gdb/configure | 425 +++++-- gdb/configure.ac | 52 + gdb/configure.tgt | 23 +- gdb/doc/gdb.texinfo | 758 +++++++++++ gdb/regcache.c | 3 +- gdb/solib-rocm.c | 679 ++++++++++ gdb/testsuite/gdb.rocm/simple.cpp | 48 + gdb/testsuite/gdb.rocm/simple.exp | 52 + gdb/testsuite/lib/future.exp | 38 + gdb/testsuite/lib/gdb.exp | 7 + gdb/testsuite/lib/rocm.exp | 94 ++ 18 files changed, 5622 insertions(+), 138 deletions(-) create mode 100644 gdb/amd-dbgapi-target.c create mode 100644 gdb/amd-dbgapi-target.h create mode 100644 gdb/amdgpu-tdep.c create mode 100644 gdb/amdgpu-tdep.h create mode 100644 gdb/solib-rocm.c create mode 100644 gdb/testsuite/gdb.rocm/simple.cpp create mode 100644 gdb/testsuite/gdb.rocm/simple.exp create mode 100644 gdb/testsuite/lib/rocm.exp diff --git a/gdb/Makefile.in b/gdb/Makefile.in index fb4d42c7baa..f4e498c98c5 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -229,6 +229,9 @@ PTHREAD_LIBS = @PTHREAD_LIBS@ DEBUGINFOD_CFLAGS = @DEBUGINFOD_CFLAGS@ DEBUGINFOD_LIBS = @DEBUGINFOD_LIBS@ +AMD_DBGAPI_CFLAGS = @AMD_DBGAPI_CFLAGS@ +AMD_DBGAPI_LIBS = @AMD_DBGAPI_LIBS@ + RDYNAMIC = @RDYNAMIC@ # Where is the INTL library? Typically in ../intl. @@ -633,7 +636,8 @@ INTERNAL_CFLAGS_BASE = \ $(ZSTD_CFLAGS) $(BFD_CFLAGS) $(INCLUDE_CFLAGS) $(LIBDECNUMBER_CFLAGS) \ $(INTL_CFLAGS) $(INCGNU) $(INCSUPPORT) $(LIBBACKTRACE_INC) \ $(ENABLE_CFLAGS) $(INTERNAL_CPPFLAGS) $(SRCHIGH_CFLAGS) \ - $(TOP_CFLAGS) $(PTHREAD_CFLAGS) $(DEBUGINFOD_CFLAGS) + $(TOP_CFLAGS) $(PTHREAD_CFLAGS) $(DEBUGINFOD_CFLAGS) \ + $(AMD_DBGAPI_CFLAGS) INTERNAL_WARN_CFLAGS = $(INTERNAL_CFLAGS_BASE) $(GDB_WARN_CFLAGS) INTERNAL_CFLAGS = $(INTERNAL_WARN_CFLAGS) $(GDB_WERROR_CFLAGS) @@ -655,7 +659,7 @@ INTERNAL_LDFLAGS = \ CLIBS = $(SIM) $(READLINE) $(OPCODES) $(LIBCTF) $(BFD) $(ZLIB) $(ZSTD_LIBS) \ $(LIBSUPPORT) $(INTL) $(LIBIBERTY) $(LIBDECNUMBER) \ $(XM_CLIBS) $(GDBTKLIBS) $(LIBBACKTRACE_LIB) \ - @LIBS@ @GUILE_LIBS@ @PYTHON_LIBS@ \ + @LIBS@ @GUILE_LIBS@ @PYTHON_LIBS@ $(AMD_DBGAPI_LIBS) \ $(LIBEXPAT) $(LIBLZMA) $(LIBBABELTRACE) $(LIBIPT) \ $(WIN32LIBS) $(LIBGNU) $(LIBGNU_EXTRA_LIBS) $(LIBICONV) \ $(LIBMPFR) $(LIBGMP) $(SRCHIGH_LIBS) $(LIBXXHASH) $(PTHREAD_LIBS) \ @@ -693,6 +697,12 @@ SIM_OBS = @SIM_OBS@ # Target-dependent object files. TARGET_OBS = @TARGET_OBS@ +# All target-dependent object files that require the amd-dbgapi +# target to be available (used with --enable-targets=all). +ALL_AMD_DBGAPI_TARGET_OBS = \ + amdgpu-tdep.o \ + solib-rocm.o + # All target-dependent objects files that require 64-bit CORE_ADDR # (used with --enable-targets=all --enable-64-bit-bfd). ALL_64_TARGET_OBS = \ @@ -1638,6 +1648,7 @@ ALLDEPFILES = \ alpha-netbsd-tdep.c \ alpha-obsd-tdep.c \ alpha-tdep.c \ + amd-dbgapi-target.c \ amd64-bsd-nat.c \ amd64-darwin-tdep.c \ amd64-dicos-tdep.c \ @@ -1653,6 +1664,7 @@ ALLDEPFILES = \ amd64-ravenscar-thread.c \ amd64-sol2-tdep.c \ amd64-tdep.c \ + amdgpu-tdep.c \ arc-linux-nat.c \ arc-tdep.c \ arm-bsd-tdep.c \ @@ -1794,6 +1806,7 @@ ALLDEPFILES = \ sh-tdep.c \ sol2-tdep.c \ solib-aix.c \ + solib-rocm.c \ solib-svr4.c \ sparc-linux-nat.c \ sparc-linux-tdep.c \ diff --git a/gdb/NEWS b/gdb/NEWS index c4ccfcc9e32..12acd0c3800 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -184,6 +184,8 @@ GNU/Linux/LoongArch (gdbserver) loongarch*-*-linux* GNU/Linux/CSKY (gdbserver) csky*-*linux* +AMDGPU amdgcn-*-* + * MI changes ** The async record stating the stopped reason 'breakpoint-hit' now @@ -278,6 +280,11 @@ GNU/Linux/CSKY (gdbserver) csky*-*linux* GDB now supports floating-point on LoongArch GNU/Linux. +* AMD GPU ROCm debugging support + +GDB now supports debugging programs offloaded to AMD GPUs using the ROCm +platform. + *** Changes in GDB 12 * DBX mode is deprecated, and will be removed in GDB 13 diff --git a/gdb/README b/gdb/README index 406df046053..514093e3bc8 100644 --- a/gdb/README +++ b/gdb/README @@ -531,6 +531,21 @@ more obscure GDB `configure' options are not listed here. speeds up various GDB operations such as symbol loading. Enabled by default if libxxhash is found. +`--with-amd-dbgapi=[auto,yes,no]' + Whether to use the amd-dbgapi library to support local debugging of + AMD GCN architecture GPUs. + + When explicitly requesting support for an AMD GCN architecture through + `--enable-targets' or `--target', there is no need to use + `--with-amd-dbgapi': `configure' will automatically look for the + amd-dbgapi library and fail if not found. + + When using --enable-targets=all, support for the AMD GCN architecture will + only be included if the amd-dbgapi is found. `--with-amd-dbgapi=yes' can + be used to make it a failure if the amd-dbgapi library is not found. + `--with-amd-dbgapi=no' can be used to prevent looking for the amd-dbgapi + library altogether. + `--without-included-regex' Don't use the regex library included with GDB (as part of the libiberty library). This is the default on hosts with version 2 diff --git a/gdb/amd-dbgapi-target.c b/gdb/amd-dbgapi-target.c new file mode 100644 index 00000000000..abd8b4b3a3f --- /dev/null +++ b/gdb/amd-dbgapi-target.c @@ -0,0 +1,1966 @@ +/* Target used to communicate with the AMD Debugger API. + + Copyright (C) 2019-2022 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 . */ + +#include "defs.h" + +#include "amd-dbgapi-target.h" +#include "amdgpu-tdep.h" +#include "async-event.h" +#include "cli/cli-cmds.h" +#include "cli/cli-style.h" +#include "inf-loop.h" +#include "inferior.h" +#include "objfiles.h" +#include "observable.h" +#include "registry.h" +#include "solib.h" +#include "target.h" + +/* When true, print debug messages relating to the amd-dbgapi target. */ + +static bool debug_amd_dbgapi = false; + +/* Make a copy of S styled in green. */ + +static std::string +make_green (const char *s) +{ + cli_style_option style (nullptr, ui_file_style::GREEN); + string_file sf (true); + gdb_printf (&sf, "%ps", styled_string (style.style(), s)); + return sf.release (); +} + +/* Debug module names. "amd-dbgapi" is for the target debug messages (this + file), whereas "amd-dbgapi-lib" is for logging messages output by the + amd-dbgapi library. */ + +static const char *amd_dbgapi_debug_module_unstyled = "amd-dbgapi"; +static const char *amd_dbgapi_lib_debug_module_unstyled + = "amd-dbgapi-lib"; + +/* Styled variants of the above. */ + +static const std::string amd_dbgapi_debug_module_styled + = make_green (amd_dbgapi_debug_module_unstyled); +static const std::string amd_dbgapi_lib_debug_module_styled + = make_green (amd_dbgapi_lib_debug_module_unstyled); + +/* Return the styled or unstyled variant of the amd-dbgapi module name, + depending on whether gdb_stdlog can emit colors. */ + +static const char * +amd_dbgapi_debug_module () +{ + if (gdb_stdlog->can_emit_style_escape ()) + return amd_dbgapi_debug_module_styled.c_str (); + else + return amd_dbgapi_debug_module_unstyled; +} + +/* Same as the above, but for the amd-dbgapi-lib module name. */ + +static const char * +amd_dbgapi_lib_debug_module () +{ + if (gdb_stdlog->can_emit_style_escape ()) + return amd_dbgapi_lib_debug_module_styled.c_str (); + else + return amd_dbgapi_lib_debug_module_unstyled; +} + +/* Print an amd-dbgapi debug statement. */ + +#define amd_dbgapi_debug_printf(fmt, ...) \ + debug_prefixed_printf_cond (debug_amd_dbgapi, \ + amd_dbgapi_debug_module (), \ + fmt, ##__VA_ARGS__) + +/* Print amd-dbgapi start/end debug statements. */ + +#define AMD_DBGAPI_SCOPED_DEBUG_START_END(fmt, ...) \ + scoped_debug_start_end (debug_infrun, amd_dbgapi_debug_module (), \ + fmt, ##__VA_ARGS__) + +/* inferior_created observer token. */ + +static gdb::observers::token amd_dbgapi_target_inferior_created_observer_token; + +const gdb::observers::token & +get_amd_dbgapi_target_inferior_created_observer_token () +{ + return amd_dbgapi_target_inferior_created_observer_token; +} + + +/* Big enough to hold the size of the largest register in bytes. */ +#define AMDGPU_MAX_REGISTER_SIZE 256 + +/* amd-dbgapi-specific inferior data. */ + +struct amd_dbgapi_inferior_info +{ + explicit amd_dbgapi_inferior_info (inferior *inf) + : inf (inf) + {} + + /* Backlink to inferior. */ + inferior *inf; + + /* The amd_dbgapi_process_id for this inferior. */ + amd_dbgapi_process_id_t process_id = AMD_DBGAPI_PROCESS_NONE; + + /* The amd_dbgapi_notifier_t for this inferior. */ + amd_dbgapi_notifier_t notifier = -1; + + /* The status of the inferior's runtime support. */ + amd_dbgapi_runtime_state_t runtime_state = AMD_DBGAPI_RUNTIME_STATE_UNLOADED; + + /* This value mirrors the current "forward progress needed" value for this + process in amd-dbgapi. It is used to avoid unnecessary calls to + amd_dbgapi_process_set_progress, to reduce the noise in the logs. + + Initialized to true, since that's the default in amd-dbgapi too. */ + bool forward_progress_required = true; + + std::unordered_map + breakpoint_map; + + /* List of pending events the amd-dbgapi target retrieved from the dbgapi. */ + std::list> wave_events; +}; + +static amd_dbgapi_event_id_t process_event_queue + (amd_dbgapi_process_id_t process_id = AMD_DBGAPI_PROCESS_NONE, + amd_dbgapi_event_kind_t until_event_kind = AMD_DBGAPI_EVENT_KIND_NONE); + +static const target_info amd_dbgapi_target_info = { + "amd-dbgapi", + N_("AMD Debugger API"), + N_("GPU debugging using the AMD Debugger API") +}; + +static amd_dbgapi_log_level_t get_debug_amd_dbgapi_lib_log_level (); + +struct amd_dbgapi_target final : public target_ops +{ + const target_info & + info () const override + { + return amd_dbgapi_target_info; + } + strata + stratum () const override + { + return arch_stratum; + } + + void close () override; + void mourn_inferior () override; + void detach (inferior *inf, int from_tty) override; + + void async (bool enable) override; + + bool has_pending_events () override; + ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override; + void resume (ptid_t, int, enum gdb_signal) override; + void commit_resumed () override; + void stop (ptid_t ptid) override; + + void fetch_registers (struct regcache *, int) override; + void store_registers (struct regcache *, int) override; + + void update_thread_list () override; + + struct gdbarch *thread_architecture (ptid_t) override; + + void thread_events (int enable) override; + + std::string pid_to_str (ptid_t ptid) override; + + const char *thread_name (thread_info *tp) override; + + const char *extra_thread_info (thread_info *tp) override; + + bool thread_alive (ptid_t ptid) override; + + enum target_xfer_status xfer_partial (enum target_object object, + const char *annex, gdb_byte *readbuf, + const gdb_byte *writebuf, + ULONGEST offset, ULONGEST len, + ULONGEST *xfered_len) override; + + bool stopped_by_watchpoint () override; + + bool stopped_by_sw_breakpoint () override; + bool stopped_by_hw_breakpoint () override; + +private: + /* True if we must report thread events. */ + bool m_report_thread_events = false; + + /* Cache for the last value returned by thread_architecture. */ + gdbarch *m_cached_arch = nullptr; + ptid_t::tid_type m_cached_arch_tid = 0; +}; + +static struct amd_dbgapi_target the_amd_dbgapi_target; + +/* Per-inferior data key. */ + +static const registry::key + amd_dbgapi_inferior_data; + +/* The async event handler registered with the event loop, indicating that we + might have events to report to the core and that we'd like our wait method + to be called. + + This is nullptr when async is disabled and non-nullptr when async is + enabled. + + It is marked when a notifier fd tells us there's an event available. The + callback triggers handle_inferior_event in order to pull the event from + amd-dbgapi and handle it. */ + +static async_event_handler *amd_dbgapi_async_event_handler = nullptr; + +/* Return the target id string for a given wave. */ + +static std::string +wave_target_id_string (amd_dbgapi_wave_id_t wave_id) +{ + amd_dbgapi_dispatch_id_t dispatch_id; + amd_dbgapi_queue_id_t queue_id; + amd_dbgapi_agent_id_t agent_id; + uint32_t group_ids[3], wave_in_group; + std::string str = "AMDGPU Wave"; + + amd_dbgapi_status_t status + = amd_dbgapi_wave_get_info (wave_id, AMD_DBGAPI_WAVE_INFO_AGENT, + sizeof (agent_id), &agent_id); + str += (status == AMD_DBGAPI_STATUS_SUCCESS + ? string_printf (" %ld", agent_id.handle) + : " ?"); + + status = amd_dbgapi_wave_get_info (wave_id, AMD_DBGAPI_WAVE_INFO_QUEUE, + sizeof (queue_id), &queue_id); + str += (status == AMD_DBGAPI_STATUS_SUCCESS + ? string_printf (":%ld", queue_id.handle) + : ":?"); + + status = amd_dbgapi_wave_get_info (wave_id, AMD_DBGAPI_WAVE_INFO_DISPATCH, + sizeof (dispatch_id), &dispatch_id); + str += (status == AMD_DBGAPI_STATUS_SUCCESS + ? string_printf (":%ld", dispatch_id.handle) + : ":?"); + + str += string_printf (":%ld", wave_id.handle); + + status = amd_dbgapi_wave_get_info (wave_id, + AMD_DBGAPI_WAVE_INFO_WORKGROUP_COORD, + sizeof (group_ids), &group_ids); + str += (status == AMD_DBGAPI_STATUS_SUCCESS + ? string_printf (" (%d,%d,%d)", group_ids[0], group_ids[1], + group_ids[2]) + : " (?,?,?)"); + + status = amd_dbgapi_wave_get_info + (wave_id, AMD_DBGAPI_WAVE_INFO_WAVE_NUMBER_IN_WORKGROUP, + sizeof (wave_in_group), &wave_in_group); + str += (status == AMD_DBGAPI_STATUS_SUCCESS + ? string_printf ("/%d", wave_in_group) + : "/?"); + + return str; +} + +/* Clear our async event handler. */ + +static void +async_event_handler_clear () +{ + gdb_assert (amd_dbgapi_async_event_handler != nullptr); + clear_async_event_handler (amd_dbgapi_async_event_handler); +} + +/* Mark our async event handler. */ + +static void +async_event_handler_mark () +{ + gdb_assert (amd_dbgapi_async_event_handler != nullptr); + mark_async_event_handler (amd_dbgapi_async_event_handler); +} + +/* Fetch the amd_dbgapi_inferior_info data for the given inferior. */ + +static struct amd_dbgapi_inferior_info * +get_amd_dbgapi_inferior_info (struct inferior *inferior) +{ + amd_dbgapi_inferior_info *info = amd_dbgapi_inferior_data.get (inferior); + + if (info == nullptr) + info = amd_dbgapi_inferior_data.emplace (inferior, inferior); + + return info; +} + +/* Set forward progress requirement to REQUIRE for all processes of PROC_TARGET + matching PTID. */ + +static void +require_forward_progress (ptid_t ptid, process_stratum_target *proc_target, + bool require) +{ + for (inferior *inf : all_inferiors (proc_target)) + { + if (ptid != minus_one_ptid && inf->pid != ptid.pid ()) + continue; + + amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf); + + if (info->process_id == AMD_DBGAPI_PROCESS_NONE) + continue; + + /* Don't do unnecessary calls to amd-dbgapi to avoid polluting the logs. */ + if (info->forward_progress_required == require) + continue; + + amd_dbgapi_status_t status + = amd_dbgapi_process_set_progress + (info->process_id, (require + ? AMD_DBGAPI_PROGRESS_NORMAL + : AMD_DBGAPI_PROGRESS_NO_FORWARD)); + gdb_assert (status == AMD_DBGAPI_STATUS_SUCCESS); + + info->forward_progress_required = require; + + /* If ptid targets a single inferior and we have found it, no need to + continue. */ + if (ptid != minus_one_ptid) + break; + } +} + +/* See amd-dbgapi-target.h. */ + +amd_dbgapi_process_id_t +get_amd_dbgapi_process_id (inferior *inf) +{ + return get_amd_dbgapi_inferior_info (inf)->process_id; +} + +/* A breakpoint dbgapi wants us to insert, to handle shared library + loading/unloading. */ + +struct amd_dbgapi_target_breakpoint : public code_breakpoint +{ + amd_dbgapi_target_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address) + : code_breakpoint (gdbarch, bp_breakpoint) + { + symtab_and_line sal; + sal.pc = address; + sal.section = find_pc_overlay (sal.pc); + sal.pspace = current_program_space; + add_location (sal); + + pspace = current_program_space; + disposition = disp_donttouch; + } + + void re_set () override; + void check_status (struct bpstat *bs) override; +}; + +void +amd_dbgapi_target_breakpoint::re_set () +{ + /* Nothing. */ +} + +void +amd_dbgapi_target_breakpoint::check_status (struct bpstat *bs) +{ + inferior *inf = current_inferior (); + amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf); + amd_dbgapi_status_t status; + + bs->stop = 0; + bs->print_it = print_it_noop; + + /* Find the address the breakpoint is set at. */ + auto match_breakpoint + = [bs] (const decltype (info->breakpoint_map)::value_type &value) + { return value.second == bs->breakpoint_at; }; + auto it + = std::find_if (info->breakpoint_map.begin (), info->breakpoint_map.end (), + match_breakpoint); + + if (it == info->breakpoint_map.end ()) + error (_("Could not find breakpoint_id for breakpoint at %s"), + paddress (inf->gdbarch, bs->bp_location_at->address)); + + amd_dbgapi_breakpoint_id_t breakpoint_id { it->first }; + amd_dbgapi_breakpoint_action_t action; + + status = amd_dbgapi_report_breakpoint_hit + (breakpoint_id, + reinterpret_cast (inferior_thread ()), + &action); + + if (status != AMD_DBGAPI_STATUS_SUCCESS) + error (_("amd_dbgapi_report_breakpoint_hit failed for breakpoint %ld " + "at %s (%s)"), + breakpoint_id.handle, paddress (inf->gdbarch, bs->bp_location_at->address), + get_status_string (status)); + + if (action == AMD_DBGAPI_BREAKPOINT_ACTION_RESUME) + return; + + /* If the action is AMD_DBGAPI_BREAKPOINT_ACTION_HALT, we need to wait until + a breakpoint resume event for this breakpoint_id is seen. */ + amd_dbgapi_event_id_t resume_event_id + = process_event_queue (info->process_id, + AMD_DBGAPI_EVENT_KIND_BREAKPOINT_RESUME); + + /* We should always get a breakpoint_resume event after processing all + events generated by reporting the breakpoint hit. */ + gdb_assert (resume_event_id != AMD_DBGAPI_EVENT_NONE); + + amd_dbgapi_breakpoint_id_t resume_breakpoint_id; + status = amd_dbgapi_event_get_info (resume_event_id, + AMD_DBGAPI_EVENT_INFO_BREAKPOINT, + sizeof (resume_breakpoint_id), + &resume_breakpoint_id); + + if (status != AMD_DBGAPI_STATUS_SUCCESS) + error (_("amd_dbgapi_event_get_info failed (%s)"), get_status_string (status)); + + /* The debugger API guarantees that [breakpoint_hit...resume_breakpoint] + sequences cannot interleave, so this breakpoint resume event must be + for our breakpoint_id. */ + if (resume_breakpoint_id != breakpoint_id) + error (_("breakpoint resume event is not for this breakpoint. " + "Expected breakpoint_%ld, got breakpoint_%ld"), + breakpoint_id.handle, resume_breakpoint_id.handle); + + amd_dbgapi_event_processed (resume_event_id); +} + +bool +amd_dbgapi_target::thread_alive (ptid_t ptid) +{ + if (!ptid_is_gpu (ptid)) + return beneath ()->thread_alive (ptid); + + /* Check that the wave_id is valid. */ + + amd_dbgapi_wave_state_t state; + amd_dbgapi_status_t status + = amd_dbgapi_wave_get_info (get_amd_dbgapi_wave_id (ptid), + AMD_DBGAPI_WAVE_INFO_STATE, sizeof (state), + &state); + return status == AMD_DBGAPI_STATUS_SUCCESS; +} + +const char * +amd_dbgapi_target::thread_name (thread_info *tp) +{ + if (!ptid_is_gpu (tp->ptid)) + return beneath ()->thread_name (tp); + + return nullptr; +} + +std::string +amd_dbgapi_target::pid_to_str (ptid_t ptid) +{ + if (!ptid_is_gpu (ptid)) + return beneath ()->pid_to_str (ptid); + + return wave_target_id_string (get_amd_dbgapi_wave_id (ptid)); +} + +const char * +amd_dbgapi_target::extra_thread_info (thread_info *tp) +{ + if (!ptid_is_gpu (tp->ptid)) + beneath ()->extra_thread_info (tp); + + return nullptr; +} + +target_xfer_status +amd_dbgapi_target::xfer_partial (enum target_object object, const char *annex, + gdb_byte *readbuf, const gdb_byte *writebuf, + ULONGEST offset, ULONGEST requested_len, + ULONGEST *xfered_len) +{ + gdb::optional maybe_restore_thread; + + if (!ptid_is_gpu (inferior_ptid)) + return beneath ()->xfer_partial (object, annex, readbuf, writebuf, offset, + requested_len, xfered_len); + + gdb_assert (requested_len > 0); + gdb_assert (xfered_len != nullptr); + + if (object != TARGET_OBJECT_MEMORY) + return TARGET_XFER_E_IO; + + amd_dbgapi_process_id_t process_id + = get_amd_dbgapi_process_id (current_inferior ()); + amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (inferior_ptid); + + size_t len = requested_len; + amd_dbgapi_status_t status; + + if (readbuf != nullptr) + status = amd_dbgapi_read_memory (process_id, wave_id, 0, + AMD_DBGAPI_ADDRESS_SPACE_GLOBAL, + offset, &len, readbuf); + else + status = amd_dbgapi_write_memory (process_id, wave_id, 0, + AMD_DBGAPI_ADDRESS_SPACE_GLOBAL, + offset, &len, writebuf); + + if (status != AMD_DBGAPI_STATUS_SUCCESS) + return TARGET_XFER_E_IO; + + *xfered_len = len; + return TARGET_XFER_OK; +} + +bool +amd_dbgapi_target::stopped_by_watchpoint () +{ + if (!ptid_is_gpu (inferior_ptid)) + return beneath ()->stopped_by_watchpoint (); + + return false; +} + +void +amd_dbgapi_target::resume (ptid_t scope_ptid, int step, enum gdb_signal signo) +{ + amd_dbgapi_debug_printf ("scope_ptid = %s", scope_ptid.to_string ().c_str ()); + + /* The amd_dbgapi_exceptions_t matching SIGNO will only be used if the + thread which is the target of the signal SIGNO is a GPU thread. If so, + make sure that there is a corresponding amd_dbgapi_exceptions_t for SIGNO + before we try to resume any thread. */ + amd_dbgapi_exceptions_t exception = AMD_DBGAPI_EXCEPTION_NONE; + if (ptid_is_gpu (inferior_ptid)) + { + switch (signo) + { + case GDB_SIGNAL_BUS: + exception = AMD_DBGAPI_EXCEPTION_WAVE_APERTURE_VIOLATION; + break; + case GDB_SIGNAL_SEGV: + exception = AMD_DBGAPI_EXCEPTION_WAVE_MEMORY_VIOLATION; + break; + case GDB_SIGNAL_ILL: + exception = AMD_DBGAPI_EXCEPTION_WAVE_ILLEGAL_INSTRUCTION; + break; + case GDB_SIGNAL_FPE: + exception = AMD_DBGAPI_EXCEPTION_WAVE_MATH_ERROR; + break; + case GDB_SIGNAL_ABRT: + exception = AMD_DBGAPI_EXCEPTION_WAVE_ABORT; + break; + case GDB_SIGNAL_TRAP: + exception = AMD_DBGAPI_EXCEPTION_WAVE_TRAP; + break; + case GDB_SIGNAL_0: + exception = AMD_DBGAPI_EXCEPTION_NONE; + break; + default: + error (_("Resuming with signal %s is not supported by this agent."), + gdb_signal_to_name (signo)); + } + } + + if (!ptid_is_gpu (inferior_ptid) || scope_ptid != inferior_ptid) + { + beneath ()->resume (scope_ptid, step, signo); + + /* If the request is for a single thread, we are done. */ + if (scope_ptid == inferior_ptid) + return; + } + + process_stratum_target *proc_target = current_inferior ()->process_target (); + + /* Disable forward progress requirement. */ + require_forward_progress (scope_ptid, proc_target, false); + + for (thread_info *thread : all_non_exited_threads (proc_target, scope_ptid)) + { + if (!ptid_is_gpu (thread->ptid)) + continue; + + amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (thread->ptid); + amd_dbgapi_status_t status; + if (thread->ptid == inferior_ptid) + status = amd_dbgapi_wave_resume (wave_id, + (step + ? AMD_DBGAPI_RESUME_MODE_SINGLE_STEP + : AMD_DBGAPI_RESUME_MODE_NORMAL), + exception); + else + status = amd_dbgapi_wave_resume (wave_id, AMD_DBGAPI_RESUME_MODE_NORMAL, + AMD_DBGAPI_EXCEPTION_NONE); + + if (status != AMD_DBGAPI_STATUS_SUCCESS + /* Ignore the error that wave is no longer valid as that could + indicate that the process has exited. GDB treats resuming a + thread that no longer exists as being successful. */ + && status != AMD_DBGAPI_STATUS_ERROR_INVALID_WAVE_ID) + error (_("wave_resume for wave_%ld failed (%s)"), wave_id.handle, + get_status_string (status)); + } +} + +void +amd_dbgapi_target::commit_resumed () +{ + amd_dbgapi_debug_printf ("called"); + + beneath ()->commit_resumed (); + + process_stratum_target *proc_target = current_inferior ()->process_target (); + require_forward_progress (minus_one_ptid, proc_target, true); +} + +void +amd_dbgapi_target::stop (ptid_t ptid) +{ + amd_dbgapi_debug_printf ("ptid = %s", ptid.to_string ().c_str ()); + + bool many_threads = ptid == minus_one_ptid || ptid.is_pid (); + + if (!ptid_is_gpu (ptid) || many_threads) + { + beneath ()->stop (ptid); + + /* The request is for a single thread, we are done. */ + if (!many_threads) + return; + } + + auto stop_one_thread = [this] (thread_info *thread) + { + gdb_assert (thread != nullptr); + + amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (thread->ptid); + amd_dbgapi_wave_state_t state; + amd_dbgapi_status_t status + = amd_dbgapi_wave_get_info (wave_id, AMD_DBGAPI_WAVE_INFO_STATE, + sizeof (state), &state); + if (status == AMD_DBGAPI_STATUS_SUCCESS) + { + /* If the wave is already known to be stopped then do nothing. */ + if (state == AMD_DBGAPI_WAVE_STATE_STOP) + return; + + status = amd_dbgapi_wave_stop (wave_id); + if (status == AMD_DBGAPI_STATUS_SUCCESS) + return; + + if (status != AMD_DBGAPI_STATUS_ERROR_INVALID_WAVE_ID) + error (_("wave_stop for wave_%ld failed (%s)"), wave_id.handle, + get_status_string (status)); + } + else if (status != AMD_DBGAPI_STATUS_ERROR_INVALID_WAVE_ID) + error (_("wave_get_info for wave_%ld failed (%s)"), wave_id.handle, + get_status_string (status)); + + /* The status is AMD_DBGAPI_STATUS_ERROR_INVALID_WAVE_ID. The wave + could have terminated since the last time the wave list was + refreshed. */ + + if (m_report_thread_events) + { + get_amd_dbgapi_inferior_info (thread->inf)->wave_events.emplace_back + (thread->ptid, target_waitstatus ().set_thread_exited (0)); + + if (target_is_async_p ()) + async_event_handler_mark (); + } + + delete_thread_silent (thread); + }; + + process_stratum_target *proc_target = current_inferior ()->process_target (); + + /* Disable forward progress requirement. */ + require_forward_progress (ptid, proc_target, false); + + if (!many_threads) + { + /* No need to iterate all non-exited threads if the request is to stop a + specific thread. */ + stop_one_thread (find_thread_ptid (proc_target, ptid)); + return; + } + + for (auto *inf : all_inferiors (proc_target)) + /* Use the threads_safe iterator since stop_one_thread may delete the + thread if it has exited. */ + for (auto *thread : inf->threads_safe ()) + if (thread->state != THREAD_EXITED && thread->ptid.matches (ptid) + && ptid_is_gpu (thread->ptid)) + stop_one_thread (thread); +} + +/* Callback for our async event handler. */ + +static void +handle_target_event (gdb_client_data client_data) +{ + inferior_event_handler (INF_REG_EVENT); +} + +struct scoped_amd_dbgapi_event_processed +{ + scoped_amd_dbgapi_event_processed (amd_dbgapi_event_id_t event_id) + : m_event_id (event_id) + { + gdb_assert (event_id != AMD_DBGAPI_EVENT_NONE); + } + + ~scoped_amd_dbgapi_event_processed () + { + amd_dbgapi_status_t status = amd_dbgapi_event_processed (m_event_id); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + warning (_("Failed to acknowledge amd-dbgapi event %" PRIu64), + m_event_id.handle); + } + + DISABLE_COPY_AND_ASSIGN (scoped_amd_dbgapi_event_processed); + +private: + amd_dbgapi_event_id_t m_event_id; +}; + +/* Called when a dbgapi notifier fd is readable. CLIENT_DATA is the + amd_dbgapi_inferior_info object corresponding to the notifier. */ + +static void +dbgapi_notifier_handler (int err, gdb_client_data client_data) +{ + amd_dbgapi_inferior_info *info = (amd_dbgapi_inferior_info *) client_data; + int ret; + + /* Drain the notifier pipe. */ + do + { + char buf; + ret = read (info->notifier, &buf, 1); + } + while (ret >= 0 || (ret == -1 && errno == EINTR)); + + if (info->inf->target_is_pushed (&the_amd_dbgapi_target)) + { + /* The amd-dbgapi target is pushed: signal our async handler, the event + will be consumed through our wait method. */ + + async_event_handler_mark (); + } + else + { + /* The amd-dbgapi target is not pushed: if there's an event, the only + expected one is one of the RUNTIME kind. If the event tells us the + inferior as activated the ROCm runtime, push the amd-dbgapi + target. */ + + amd_dbgapi_event_id_t event_id; + amd_dbgapi_event_kind_t event_kind; + amd_dbgapi_status_t status + = amd_dbgapi_process_next_pending_event (info->process_id, &event_id, + &event_kind); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + error (_("next_pending_event failed (%s)"), get_status_string (status)); + + if (event_id == AMD_DBGAPI_EVENT_NONE) + return; + + gdb_assert (event_kind == AMD_DBGAPI_EVENT_KIND_RUNTIME); + + scoped_amd_dbgapi_event_processed mark_event_processed (event_id); + + amd_dbgapi_runtime_state_t runtime_state; + status = amd_dbgapi_event_get_info (event_id, + AMD_DBGAPI_EVENT_INFO_RUNTIME_STATE, + sizeof (runtime_state), + &runtime_state); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + error (_("event_get_info for event_%ld failed (%s)"), + event_id.handle, get_status_string (status)); + + switch (runtime_state) + { + case AMD_DBGAPI_RUNTIME_STATE_LOADED_SUCCESS: + gdb_assert (info->runtime_state == AMD_DBGAPI_RUNTIME_STATE_UNLOADED); + info->runtime_state = runtime_state; + amd_dbgapi_debug_printf ("pushing amd-dbgapi target"); + info->inf->push_target (&the_amd_dbgapi_target); + + /* The underlying target will already be async if we are running, but not if + we are attaching. */ + if (info->inf->process_target ()->is_async_p ()) + { + scoped_restore_current_thread restore_thread; + switch_to_inferior_no_thread (info->inf); + + /* Make sure our async event handler is created. */ + target_async (true); + } + break; + + case AMD_DBGAPI_RUNTIME_STATE_UNLOADED: + gdb_assert (info->runtime_state + == AMD_DBGAPI_RUNTIME_STATE_LOADED_ERROR_RESTRICTION); + info->runtime_state = runtime_state; + break; + + case AMD_DBGAPI_RUNTIME_STATE_LOADED_ERROR_RESTRICTION: + gdb_assert (info->runtime_state == AMD_DBGAPI_RUNTIME_STATE_UNLOADED); + info->runtime_state = runtime_state; + warning (_("amd-dbgapi: unable to enable GPU debugging " + "due to a restriction error")); + break; + } + } +} + +void +amd_dbgapi_target::async (bool enable) +{ + beneath ()->async (enable); + + if (enable) + { + if (amd_dbgapi_async_event_handler != nullptr) + { + /* Already enabled. */ + return; + } + + /* The library gives us one notifier file descriptor per inferior (even + the ones that have not yet loaded their runtime). Register them + all with the event loop. */ + process_stratum_target *proc_target + = current_inferior ()->process_target (); + + for (inferior *inf : all_non_exited_inferiors (proc_target)) + { + amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf); + + if (info->notifier != -1) + add_file_handler (info->notifier, dbgapi_notifier_handler, info, + string_printf ("amd-dbgapi notifier for pid %d", + inf->pid)); + } + + amd_dbgapi_async_event_handler + = create_async_event_handler (handle_target_event, nullptr, + "amd-dbgapi"); + + /* There may be pending events to handle. Tell the event loop to poll + them. */ + async_event_handler_mark (); + } + else + { + if (amd_dbgapi_async_event_handler == nullptr) + return; + + for (inferior *inf : all_inferiors ()) + { + amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf); + + if (info->notifier != -1) + delete_file_handler (info->notifier); + } + + delete_async_event_handler (&amd_dbgapi_async_event_handler); + } +} + +/* Make a ptid for a GPU wave. See comment on ptid_is_gpu for more details. */ + +static ptid_t +make_gpu_ptid (ptid_t::pid_type pid, amd_dbgapi_wave_id_t wave_id) +{ + return ptid_t (pid, 1, wave_id.handle); +} + +/* Process an event that was just pulled out of the amd-dbgapi library. */ + +static void +process_one_event (amd_dbgapi_event_id_t event_id, + amd_dbgapi_event_kind_t event_kind) +{ + /* Automatically mark this event processed when going out of scope. */ + scoped_amd_dbgapi_event_processed mark_event_processed (event_id); + + amd_dbgapi_process_id_t process_id; + amd_dbgapi_status_t status + = amd_dbgapi_event_get_info (event_id, AMD_DBGAPI_EVENT_INFO_PROCESS, + sizeof (process_id), &process_id); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + error (_("event_get_info for event_%ld failed (%s)"), event_id.handle, + get_status_string (status)); + + amd_dbgapi_os_process_id_t pid; + status = amd_dbgapi_process_get_info (process_id, + AMD_DBGAPI_PROCESS_INFO_OS_ID, + sizeof (pid), &pid); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + error (_("process_get_info for process_%ld failed (%s)"), + process_id.handle, get_status_string (status)); + + auto *proc_target = current_inferior ()->process_target (); + inferior *inf = find_inferior_pid (proc_target, pid); + gdb_assert (inf != nullptr); + amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf); + + switch (event_kind) + { + case AMD_DBGAPI_EVENT_KIND_WAVE_COMMAND_TERMINATED: + case AMD_DBGAPI_EVENT_KIND_WAVE_STOP: + { + amd_dbgapi_wave_id_t wave_id; + status + = amd_dbgapi_event_get_info (event_id, AMD_DBGAPI_EVENT_INFO_WAVE, + sizeof (wave_id), &wave_id); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + error (_("event_get_info for event_%ld failed (%s)"), + event_id.handle, get_status_string (status)); + + ptid_t event_ptid = make_gpu_ptid (pid, wave_id); + target_waitstatus ws; + + amd_dbgapi_wave_stop_reasons_t stop_reason; + status = amd_dbgapi_wave_get_info (wave_id, + AMD_DBGAPI_WAVE_INFO_STOP_REASON, + sizeof (stop_reason), &stop_reason); + if (status == AMD_DBGAPI_STATUS_ERROR_INVALID_WAVE_ID + && event_kind == AMD_DBGAPI_EVENT_KIND_WAVE_COMMAND_TERMINATED) + ws.set_thread_exited (0); + else if (status == AMD_DBGAPI_STATUS_SUCCESS) + { + if (stop_reason & AMD_DBGAPI_WAVE_STOP_REASON_APERTURE_VIOLATION) + ws.set_stopped (GDB_SIGNAL_BUS); + else if (stop_reason + & AMD_DBGAPI_WAVE_STOP_REASON_MEMORY_VIOLATION) + ws.set_stopped (GDB_SIGNAL_SEGV); + else if (stop_reason + & AMD_DBGAPI_WAVE_STOP_REASON_ILLEGAL_INSTRUCTION) + ws.set_stopped (GDB_SIGNAL_ILL); + else if (stop_reason + & (AMD_DBGAPI_WAVE_STOP_REASON_FP_INPUT_DENORMAL + | AMD_DBGAPI_WAVE_STOP_REASON_FP_DIVIDE_BY_0 + | AMD_DBGAPI_WAVE_STOP_REASON_FP_OVERFLOW + | AMD_DBGAPI_WAVE_STOP_REASON_FP_UNDERFLOW + | AMD_DBGAPI_WAVE_STOP_REASON_FP_INEXACT + | AMD_DBGAPI_WAVE_STOP_REASON_FP_INVALID_OPERATION + | AMD_DBGAPI_WAVE_STOP_REASON_INT_DIVIDE_BY_0)) + ws.set_stopped (GDB_SIGNAL_FPE); + else if (stop_reason + & (AMD_DBGAPI_WAVE_STOP_REASON_BREAKPOINT + | AMD_DBGAPI_WAVE_STOP_REASON_WATCHPOINT + | AMD_DBGAPI_WAVE_STOP_REASON_SINGLE_STEP + | AMD_DBGAPI_WAVE_STOP_REASON_DEBUG_TRAP + | AMD_DBGAPI_WAVE_STOP_REASON_TRAP)) + ws.set_stopped (GDB_SIGNAL_TRAP); + else if (stop_reason & AMD_DBGAPI_WAVE_STOP_REASON_ASSERT_TRAP) + ws.set_stopped (GDB_SIGNAL_ABRT); + else + ws.set_stopped (GDB_SIGNAL_0); + + thread_info *thread = find_thread_ptid (proc_target, event_ptid); + if (thread == nullptr) + { + /* Silently create new GPU threads to avoid spamming the + terminal with thousands of "[New Thread ...]" messages. */ + thread = add_thread_silent (proc_target, event_ptid); + set_running (proc_target, event_ptid, true); + set_executing (proc_target, event_ptid, true); + } + + /* If the wave is stopped because of a software breakpoint, the + program counter needs to be adjusted so that it points to the + breakpoint instruction. */ + if ((stop_reason & AMD_DBGAPI_WAVE_STOP_REASON_BREAKPOINT) != 0) + { + regcache *regcache = get_thread_regcache (thread); + gdbarch *gdbarch = regcache->arch (); + + CORE_ADDR pc = regcache_read_pc (regcache); + CORE_ADDR adjusted_pc + = pc - gdbarch_decr_pc_after_break (gdbarch); + + if (adjusted_pc != pc) + regcache_write_pc (regcache, adjusted_pc); + } + } + else + error (_("wave_get_info for wave_%ld failed (%s)"), + wave_id.handle, get_status_string (status)); + + info->wave_events.emplace_back (event_ptid, ws); + break; + } + + case AMD_DBGAPI_EVENT_KIND_CODE_OBJECT_LIST_UPDATED: + /* We get here when the following sequence of events happens: + + - the inferior hits the amd-dbgapi "r_brk" internal breakpoint + - amd_dbgapi_target_breakpoint::check_status calls + amd_dbgapi_report_breakpoint_hit, which queues an event of this + kind in dbgapi + - amd_dbgapi_target_breakpoint::check_status calls + process_event_queue, which pulls the event out of dbgapi, and + gets us here + + When amd_dbgapi_target_breakpoint::check_status is called, the current + inferior is the inferior that hit the breakpoint, which should still be + the case now. */ + gdb_assert (inf == current_inferior ()); + handle_solib_event (); + break; + + case AMD_DBGAPI_EVENT_KIND_BREAKPOINT_RESUME: + /* Breakpoint resume events should be handled by the breakpoint + action, and this code should not reach this. */ + gdb_assert_not_reached ("unhandled event kind"); + break; + + case AMD_DBGAPI_EVENT_KIND_RUNTIME: + { + amd_dbgapi_runtime_state_t runtime_state; + + status = amd_dbgapi_event_get_info (event_id, + AMD_DBGAPI_EVENT_INFO_RUNTIME_STATE, + sizeof (runtime_state), + &runtime_state); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + error (_("event_get_info for event_%ld failed (%s)"), + event_id.handle, get_status_string (status)); + + gdb_assert (runtime_state == AMD_DBGAPI_RUNTIME_STATE_UNLOADED); + gdb_assert + (info->runtime_state == AMD_DBGAPI_RUNTIME_STATE_LOADED_SUCCESS); + + info->runtime_state = runtime_state; + + gdb_assert (inf->target_is_pushed (&the_amd_dbgapi_target)); + inf->unpush_target (&the_amd_dbgapi_target); + } + break; + + default: + error (_("event kind (%d) not supported"), event_kind); + } +} + +/* Return a textual version of KIND. */ + +static const char * +event_kind_str (amd_dbgapi_event_kind_t kind) +{ + switch (kind) + { + case AMD_DBGAPI_EVENT_KIND_NONE: + return "NONE"; + + case AMD_DBGAPI_EVENT_KIND_WAVE_STOP: + return "WAVE_STOP"; + + case AMD_DBGAPI_EVENT_KIND_WAVE_COMMAND_TERMINATED: + return "WAVE_COMMAND_TERMINATED"; + + case AMD_DBGAPI_EVENT_KIND_CODE_OBJECT_LIST_UPDATED: + return "CODE_OBJECT_LIST_UPDATED"; + + case AMD_DBGAPI_EVENT_KIND_BREAKPOINT_RESUME: + return "BREAKPOINT_RESUME"; + + case AMD_DBGAPI_EVENT_KIND_RUNTIME: + return "RUNTIME"; + + case AMD_DBGAPI_EVENT_KIND_QUEUE_ERROR: + return "QUEUE_ERROR"; + } + + gdb_assert_not_reached ("unhandled amd_dbgapi_event_kind_t value"); +} + +/* Drain the dbgapi event queue of a given process_id, or of all processes if + process_id is AMD_DBGAPI_PROCESS_NONE. Stop processing the events if an + event of a given kind is requested and `process_id` is not + AMD_DBGAPI_PROCESS_NONE. Wave stop events that are not returned are queued + into their inferior's amd_dbgapi_inferior_info pending wave events. */ + +static amd_dbgapi_event_id_t +process_event_queue (amd_dbgapi_process_id_t process_id, + amd_dbgapi_event_kind_t until_event_kind) +{ + /* An event of a given type can only be requested from a single + process_id. */ + gdb_assert (until_event_kind == AMD_DBGAPI_EVENT_KIND_NONE + || process_id != AMD_DBGAPI_PROCESS_NONE); + + while (true) + { + amd_dbgapi_event_id_t event_id; + amd_dbgapi_event_kind_t event_kind; + + amd_dbgapi_status_t status + = amd_dbgapi_process_next_pending_event (process_id, &event_id, + &event_kind); + + if (status != AMD_DBGAPI_STATUS_SUCCESS) + error (_("next_pending_event failed (%s)"), get_status_string (status)); + + if (event_kind != AMD_DBGAPI_EVENT_KIND_NONE) + amd_dbgapi_debug_printf ("Pulled event from dbgapi: " + "event_id.handle = %" PRIu64 ", " + "event_kind = %s", + event_id.handle, + event_kind_str (event_kind)); + + if (event_id == AMD_DBGAPI_EVENT_NONE || event_kind == until_event_kind) + return event_id; + + process_one_event (event_id, event_kind); + } +} + +bool +amd_dbgapi_target::has_pending_events () +{ + if (amd_dbgapi_async_event_handler != nullptr + && async_event_handler_marked (amd_dbgapi_async_event_handler)) + return true; + + return beneath ()->has_pending_events (); +} + +/* Pop one pending event from the per-inferior structures. + + If PID is not -1, restrict the search to the inferior with that pid. */ + +static std::pair +consume_one_event (int pid) +{ + auto *target = current_inferior ()->process_target (); + struct amd_dbgapi_inferior_info *info = nullptr; + + if (pid == -1) + { + for (inferior *inf : all_inferiors (target)) + { + info = get_amd_dbgapi_inferior_info (inf); + if (!info->wave_events.empty ()) + break; + } + + gdb_assert (info != nullptr); + } + else + { + inferior *inf = find_inferior_pid (target, pid); + + gdb_assert (inf != nullptr); + info = get_amd_dbgapi_inferior_info (inf); + } + + if (info->wave_events.empty ()) + return { minus_one_ptid, {} }; + + auto event = info->wave_events.front (); + info->wave_events.pop_front (); + + return event; +} + +ptid_t +amd_dbgapi_target::wait (ptid_t ptid, struct target_waitstatus *ws, + target_wait_flags target_options) +{ + gdb_assert (!current_inferior ()->process_target ()->commit_resumed_state); + gdb_assert (ptid == minus_one_ptid || ptid.is_pid ()); + + amd_dbgapi_debug_printf ("ptid = %s", ptid.to_string ().c_str ()); + + ptid_t event_ptid = beneath ()->wait (ptid, ws, target_options); + if (event_ptid != minus_one_ptid) + { + if (ws->kind () == TARGET_WAITKIND_EXITED + || ws->kind () == TARGET_WAITKIND_SIGNALLED) + { + /* This inferior has exited so drain its dbgapi event queue. */ + while (consume_one_event (event_ptid.pid ()).first + != minus_one_ptid) + ; + } + return event_ptid; + } + + gdb_assert (ws->kind () == TARGET_WAITKIND_NO_RESUMED + || ws->kind () == TARGET_WAITKIND_IGNORE); + + /* Flush the async handler first. */ + if (target_is_async_p ()) + async_event_handler_clear (); + + /* There may be more events to process (either already in `wave_events` or + that we need to fetch from dbgapi. Mark the async event handler so that + amd_dbgapi_target::wait gets called again and again, until it eventually + returns minus_one_ptid. */ + auto more_events = make_scope_exit ([] () + { + if (target_is_async_p ()) + async_event_handler_mark (); + }); + + auto *proc_target = current_inferior ()->process_target (); + + /* Disable forward progress for the specified pid in ptid if it isn't + minus_on_ptid, or all attached processes if ptid is minus_one_ptid. */ + require_forward_progress (ptid, proc_target, false); + + target_waitstatus gpu_waitstatus; + std::tie (event_ptid, gpu_waitstatus) = consume_one_event (ptid.pid ()); + if (event_ptid == minus_one_ptid) + { + /* Drain the events from the amd_dbgapi and preserve the ordering. */ + process_event_queue (); + + std::tie (event_ptid, gpu_waitstatus) = consume_one_event (ptid.pid ()); + if (event_ptid == minus_one_ptid) + { + /* If we requested a specific ptid, and nothing came out, assume + another ptid may have more events, otherwise, keep the + async_event_handler flushed. */ + if (ptid == minus_one_ptid) + more_events.release (); + + if (ws->kind () == TARGET_WAITKIND_NO_RESUMED) + { + /* We can't easily check that all GPU waves are stopped, and no + new waves can be created (the GPU has fixed function hardware + to create new threads), so even if the target beneath returns + waitkind_no_resumed, we have to report waitkind_ignore if GPU + debugging is enabled for at least one resumed inferior handled + by the amd-dbgapi target. */ + + for (inferior *inf : all_inferiors ()) + if (inf->target_at (arch_stratum) == &the_amd_dbgapi_target + && get_amd_dbgapi_inferior_info (inf)->runtime_state + == AMD_DBGAPI_RUNTIME_STATE_LOADED_SUCCESS) + { + ws->set_ignore (); + break; + } + } + + /* There are no events to report, return the target beneath's + waitstatus (either IGNORE or NO_RESUMED). */ + return minus_one_ptid; + } + } + + *ws = gpu_waitstatus; + return event_ptid; +} + +bool +amd_dbgapi_target::stopped_by_sw_breakpoint () +{ + if (!ptid_is_gpu (inferior_ptid)) + return beneath ()->stopped_by_sw_breakpoint (); + + amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (inferior_ptid); + + amd_dbgapi_wave_stop_reasons_t stop_reason; + amd_dbgapi_status_t status + = amd_dbgapi_wave_get_info (wave_id, AMD_DBGAPI_WAVE_INFO_STOP_REASON, + sizeof (stop_reason), &stop_reason); + + if (status != AMD_DBGAPI_STATUS_SUCCESS) + return false; + + return (stop_reason & AMD_DBGAPI_WAVE_STOP_REASON_BREAKPOINT) != 0; +} + +bool +amd_dbgapi_target::stopped_by_hw_breakpoint () +{ + if (!ptid_is_gpu (inferior_ptid)) + return beneath ()->stopped_by_hw_breakpoint (); + + return false; +} + +/* Make the amd-dbgapi library attach to the process behind INF. + + Note that this is unrelated to the "attach" GDB concept / command. + + By attaching to the process, we get a notifier fd that tells us when it + activates the ROCm runtime and when there are subsequent debug events. */ + +static void +attach_amd_dbgapi (inferior *inf) +{ + AMD_DBGAPI_SCOPED_DEBUG_START_END ("inf num = %d", inf->num); + + if (!target_can_async_p ()) + { + warning (_("The amd-dbgapi target requires the target beneath to be " + "asynchronous, GPU debugging is disabled")); + return; + } + + auto *info = get_amd_dbgapi_inferior_info (inf); + + /* Are we already attached? */ + if (info->process_id != AMD_DBGAPI_PROCESS_NONE) + { + amd_dbgapi_debug_printf + ("already attached: process_id = %" PRIu64, info->process_id.handle); + return; + } + + amd_dbgapi_status_t status + = amd_dbgapi_process_attach + (reinterpret_cast (inf), + &info->process_id); + if (status == AMD_DBGAPI_STATUS_ERROR_RESTRICTION) + { + warning (_("amd-dbgapi: unable to enable GPU debugging due to a " + "restriction error")); + return; + } + else if (status != AMD_DBGAPI_STATUS_SUCCESS) + { + warning (_("amd-dbgapi: could not attach to process %d (%s), GPU " + "debugging will not be available."), inf->pid, + get_status_string (status)); + return; + } + + if (amd_dbgapi_process_get_info (info->process_id, + AMD_DBGAPI_PROCESS_INFO_NOTIFIER, + sizeof (info->notifier), &info->notifier) + != AMD_DBGAPI_STATUS_SUCCESS) + { + amd_dbgapi_process_detach (info->process_id); + info->process_id = AMD_DBGAPI_PROCESS_NONE; + warning (_("amd-dbgapi: could not retrieve process %d's notifier, GPU " + "debugging will not be available."), inf->pid); + return; + } + + amd_dbgapi_debug_printf ("process_id = %" PRIu64 ", notifier fd = %d", + info->process_id.handle, info->notifier); + + /* If GDB is attaching to a process that has the runtime loaded, there will + already be a "runtime loaded" event available. Consume it and push the + target. */ + dbgapi_notifier_handler (0, info); + + add_file_handler (info->notifier, dbgapi_notifier_handler, info, + "amd-dbgapi notifier"); +} + +static void maybe_reset_amd_dbgapi (); + +/* Make the amd-dbgapi library detach from INF. + + Note that this us unrelated to the "detach" GDB concept / command. + + This undoes what attach_amd_dbgapi does. */ + +static void +detach_amd_dbgapi (inferior *inf) +{ + AMD_DBGAPI_SCOPED_DEBUG_START_END ("inf num = %d", inf->num); + + auto *info = get_amd_dbgapi_inferior_info (inf); + + if (info->process_id == AMD_DBGAPI_PROCESS_NONE) + return; + + info->runtime_state = AMD_DBGAPI_RUNTIME_STATE_UNLOADED; + + amd_dbgapi_status_t status = amd_dbgapi_process_detach (info->process_id); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + warning (_("amd-dbgapi: could not detach from process %d (%s)"), + inf->pid, get_status_string (status)); + + gdb_assert (info->notifier != -1); + delete_file_handler (info->notifier); + + /* This is a noop if the target is not pushed. */ + inf->unpush_target (&the_amd_dbgapi_target); + + /* Delete the breakpoints that are still active. */ + for (auto &&value : info->breakpoint_map) + delete_breakpoint (value.second); + + /* Reset the amd_dbgapi_inferior_info. */ + *info = amd_dbgapi_inferior_info (inf); + + maybe_reset_amd_dbgapi (); +} + +void +amd_dbgapi_target::mourn_inferior () +{ + detach_amd_dbgapi (current_inferior ()); + beneath ()->mourn_inferior (); +} + +void +amd_dbgapi_target::detach (inferior *inf, int from_tty) +{ + /* We're about to resume the waves by detaching the dbgapi library from the + inferior, so we need to remove all breakpoints that are still inserted. + + Breakpoints may still be inserted because the inferior may be running in + non-stop mode, or because GDB changed the default setting to leave all + breakpoints inserted in all-stop mode when all threads are stopped. */ + remove_breakpoints_inf (current_inferior ()); + + detach_amd_dbgapi (inf); + beneath ()->detach (inf, from_tty); +} + +void +amd_dbgapi_target::fetch_registers (struct regcache *regcache, int regno) +{ + if (!ptid_is_gpu (regcache->ptid ())) + { + beneath ()->fetch_registers (regcache, regno); + return; + } + + struct gdbarch *gdbarch = regcache->arch (); + gdb_assert (is_amdgpu_arch (gdbarch)); + + amdgpu_gdbarch_tdep *tdep = get_amdgpu_gdbarch_tdep (gdbarch); + amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (regcache->ptid ()); + gdb_byte raw[AMDGPU_MAX_REGISTER_SIZE]; + amd_dbgapi_status_t status + = amd_dbgapi_read_register (wave_id, tdep->register_ids[regno], 0, + register_type (gdbarch, regno)->length (), + raw); + + if (status == AMD_DBGAPI_STATUS_SUCCESS) + regcache->raw_supply (regno, raw); + else if (status != AMD_DBGAPI_STATUS_ERROR_REGISTER_NOT_AVAILABLE) + warning (_("Couldn't read register %s (#%d) (%s)."), + gdbarch_register_name (gdbarch, regno), regno, + get_status_string (status)); +} + +void +amd_dbgapi_target::store_registers (struct regcache *regcache, int regno) +{ + if (!ptid_is_gpu (regcache->ptid ())) + { + beneath ()->store_registers (regcache, regno); + return; + } + + struct gdbarch *gdbarch = regcache->arch (); + gdb_assert (is_amdgpu_arch (gdbarch)); + + gdb_byte raw[AMDGPU_MAX_REGISTER_SIZE]; + regcache->raw_collect (regno, &raw); + + amdgpu_gdbarch_tdep *tdep = get_amdgpu_gdbarch_tdep (gdbarch); + + /* If the register has read-only bits, invalidate the value in the regcache + as the value actualy written may differ. */ + if (tdep->register_properties[regno] + & AMD_DBGAPI_REGISTER_PROPERTY_READONLY_BITS) + regcache->invalidate (regno); + + /* Invalidate all volatile registers if this register has the invalidate + volatile property. For example, writting to VCC may change the content + of STATUS.VCCZ. */ + if (tdep->register_properties[regno] + & AMD_DBGAPI_REGISTER_PROPERTY_INVALIDATE_VOLATILE) + { + for (size_t r = 0; r < tdep->register_properties.size (); ++r) + if (tdep->register_properties[r] & AMD_DBGAPI_REGISTER_PROPERTY_VOLATILE) + regcache->invalidate (r); + } + + amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (regcache->ptid ()); + amd_dbgapi_status_t status + = amd_dbgapi_write_register (wave_id, tdep->register_ids[regno], 0, + register_type (gdbarch, regno)->length (), + raw); + + if (status != AMD_DBGAPI_STATUS_SUCCESS) + warning (_("Couldn't write register %s (#%d)."), + gdbarch_register_name (gdbarch, regno), regno); +} + +struct gdbarch * +amd_dbgapi_target::thread_architecture (ptid_t ptid) +{ + if (!ptid_is_gpu (ptid)) + return beneath ()->thread_architecture (ptid); + + /* We can cache the gdbarch for a given wave_id (ptid::tid) because + wave IDs are unique, and aren't reused. */ + if (ptid.tid () == m_cached_arch_tid) + return m_cached_arch; + + amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (ptid); + amd_dbgapi_architecture_id_t architecture_id; + amd_dbgapi_status_t status; + + status = amd_dbgapi_wave_get_info (wave_id, AMD_DBGAPI_WAVE_INFO_ARCHITECTURE, + sizeof (architecture_id), + &architecture_id); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + error (_("Couldn't get architecture for wave_%ld"), ptid.tid ()); + + uint32_t elf_amdgpu_machine; + status = amd_dbgapi_architecture_get_info + (architecture_id, AMD_DBGAPI_ARCHITECTURE_INFO_ELF_AMDGPU_MACHINE, + sizeof (elf_amdgpu_machine), &elf_amdgpu_machine); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + error (_("Couldn't get elf_amdgpu_machine for architecture_%ld"), + architecture_id.handle); + + struct gdbarch_info info; + info.bfd_arch_info = bfd_lookup_arch (bfd_arch_amdgcn, elf_amdgpu_machine); + info.byte_order = BFD_ENDIAN_LITTLE; + + m_cached_arch_tid = ptid.tid (); + m_cached_arch = gdbarch_find_by_info (info); + if (m_cached_arch == nullptr) + error (_("Couldn't get elf_amdgpu_machine (%#x)"), elf_amdgpu_machine); + + return m_cached_arch; +} + +void +amd_dbgapi_target::thread_events (int enable) +{ + m_report_thread_events = enable; + beneath ()->thread_events (enable); +} + +void +amd_dbgapi_target::update_thread_list () +{ + for (inferior *inf : all_inferiors ()) + { + amd_dbgapi_process_id_t process_id + = get_amd_dbgapi_process_id (inf); + if (process_id == AMD_DBGAPI_PROCESS_NONE) + { + /* The inferior may not be attached yet. */ + continue; + } + + size_t count; + amd_dbgapi_wave_id_t *wave_list; + amd_dbgapi_changed_t changed; + amd_dbgapi_status_t status + = amd_dbgapi_process_wave_list (process_id, &count, &wave_list, + &changed); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + error (_("amd_dbgapi_wave_list failed (%s)"), + get_status_string (status)); + + if (changed == AMD_DBGAPI_CHANGED_NO) + continue; + + /* Create a set and free the wave list. */ + std::set threads; + for (size_t i = 0; i < count; ++i) + threads.emplace (wave_list[i].handle); + + xfree (wave_list); + + /* Prune the wave_ids that already have a thread_info. Any thread_info + which does not have a corresponding wave_id represents a wave which + is gone at this point and should be deleted. */ + for (thread_info *tp : inf->threads_safe ()) + if (ptid_is_gpu (tp->ptid) && tp->state != THREAD_EXITED) + { + auto it = threads.find (tp->ptid.tid ()); + + if (it == threads.end ()) + delete_thread (tp); + else + threads.erase (it); + } + + /* The wave_ids that are left require a new thread_info. */ + for (ptid_t::tid_type tid : threads) + { + ptid_t wave_ptid + = make_gpu_ptid (inf->pid, amd_dbgapi_wave_id_t {tid}); + + add_thread_silent (inf->process_target (), wave_ptid); + set_running (inf->process_target (), wave_ptid, true); + set_executing (inf->process_target (), wave_ptid, true); + } + } + + /* Give the beneath target a chance to do extra processing. */ + this->beneath ()->update_thread_list (); +} + +/* inferior_created observer. */ + +static void +amd_dbgapi_target_inferior_created (inferior *inf) +{ + /* If the inferior is not running on the native target (e.g. it is running + on a remote target), we don't want to deal with it. */ + if (inf->process_target () != get_native_target ()) + return; + + attach_amd_dbgapi (inf); +} + +/* inferior_exit observer. + + This covers normal exits, but also detached inferiors (including detached + fork parents). */ + +static void +amd_dbgapi_inferior_exited (inferior *inf) +{ + detach_amd_dbgapi (inf); +} + +/* inferior_pre_detach observer. */ + +static void +amd_dbgapi_inferior_pre_detach (inferior *inf) +{ + /* We need to amd-dbgapi-detach before we ptrace-detach. If the amd-dbgapi + target isn't pushed, do that now. If the amd-dbgapi target is pushed, + we'll do it in amd_dbgapi_target::detach. */ + if (!inf->target_is_pushed (&the_amd_dbgapi_target)) + detach_amd_dbgapi (inf); +} + +/* get_os_pid callback. */ + +static amd_dbgapi_status_t +amd_dbgapi_get_os_pid_callback + (amd_dbgapi_client_process_id_t client_process_id, pid_t *pid) +{ + inferior *inf = reinterpret_cast (client_process_id); + + if (inf->pid == 0) + return AMD_DBGAPI_STATUS_ERROR_PROCESS_EXITED; + + *pid = inf->pid; + return AMD_DBGAPI_STATUS_SUCCESS; +} + +/* insert_breakpoint callback. */ + +static amd_dbgapi_status_t +amd_dbgapi_insert_breakpoint_callback + (amd_dbgapi_client_process_id_t client_process_id, + amd_dbgapi_global_address_t address, + amd_dbgapi_breakpoint_id_t breakpoint_id) +{ + inferior *inf = reinterpret_cast (client_process_id); + struct amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf); + + auto it = info->breakpoint_map.find (breakpoint_id.handle); + if (it != info->breakpoint_map.end ()) + return AMD_DBGAPI_STATUS_ERROR_INVALID_BREAKPOINT_ID; + + /* We need to find the address in the given inferior's program space. */ + scoped_restore_current_thread restore_thread; + switch_to_inferior_no_thread (inf); + + /* Create a new breakpoint. */ + struct obj_section *section = find_pc_section (address); + if (section == nullptr || section->objfile == nullptr) + return AMD_DBGAPI_STATUS_ERROR; + + std::unique_ptr bp_up + (new amd_dbgapi_target_breakpoint (section->objfile->arch (), address)); + + breakpoint *bp = install_breakpoint (true, std::move (bp_up), 1); + + info->breakpoint_map.emplace (breakpoint_id.handle, bp); + return AMD_DBGAPI_STATUS_SUCCESS; +} + +/* remove_breakpoint callback. */ + +static amd_dbgapi_status_t +amd_dbgapi_remove_breakpoint_callback + (amd_dbgapi_client_process_id_t client_process_id, + amd_dbgapi_breakpoint_id_t breakpoint_id) +{ + inferior *inf = reinterpret_cast (client_process_id); + struct amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf); + + auto it = info->breakpoint_map.find (breakpoint_id.handle); + if (it == info->breakpoint_map.end ()) + return AMD_DBGAPI_STATUS_ERROR_INVALID_BREAKPOINT_ID; + + delete_breakpoint (it->second); + info->breakpoint_map.erase (it); + + return AMD_DBGAPI_STATUS_SUCCESS; +} + +/* Style for some kinds of messages. */ + +static cli_style_option fatal_error_style + ("amd_dbgapi_fatal_error", ui_file_style::RED); +static cli_style_option warning_style + ("amd_dbgapi_warning", ui_file_style::YELLOW); + +/* BLACK + BOLD means dark gray. */ +static cli_style_option trace_style + ("amd_dbgapi_trace", ui_file_style::BLACK, ui_file_style::BOLD); + +/* log_message callback. */ + +static void +amd_dbgapi_log_message_callback (amd_dbgapi_log_level_t level, + const char *message) +{ + gdb::optional tstate; + + if (target_supports_terminal_ours ()) + { + tstate.emplace (); + target_terminal::ours_for_output (); + } + + /* Error and warning messages are meant to be printed to the user. */ + if (level == AMD_DBGAPI_LOG_LEVEL_FATAL_ERROR + || level == AMD_DBGAPI_LOG_LEVEL_WARNING) + { + begin_line (); + ui_file_style style = (level == AMD_DBGAPI_LOG_LEVEL_FATAL_ERROR + ? fatal_error_style : warning_style).style (); + gdb_printf (gdb_stderr, "%ps\n", styled_string (style, message)); + return; + } + + /* Print other messages as debug logs. TRACE and VERBOSE messages are + very verbose, print them dark grey so it's easier to spot other messages + through the flood. */ + if (level >= AMD_DBGAPI_LOG_LEVEL_TRACE) + { + debug_prefixed_printf (amd_dbgapi_lib_debug_module (), nullptr, "%ps", + styled_string (trace_style.style (), message)); + return; + } + + debug_prefixed_printf (amd_dbgapi_lib_debug_module (), nullptr, "%s", + message); +} + +/* Callbacks passed to amd_dbgapi_initialize. */ + +static amd_dbgapi_callbacks_t dbgapi_callbacks = { + .allocate_memory = malloc, + .deallocate_memory = free, + .get_os_pid = amd_dbgapi_get_os_pid_callback, + .insert_breakpoint = amd_dbgapi_insert_breakpoint_callback, + .remove_breakpoint = amd_dbgapi_remove_breakpoint_callback, + .log_message = amd_dbgapi_log_message_callback, +}; + +void +amd_dbgapi_target::close () +{ + if (amd_dbgapi_async_event_handler != nullptr) + delete_async_event_handler (&amd_dbgapi_async_event_handler); +} + +/* List of set/show debug amd-dbgapi-lib commands. */ +struct cmd_list_element *set_debug_amd_dbgapi_lib_list; +struct cmd_list_element *show_debug_amd_dbgapi_lib_list; + +/* Mapping from amd-dbgapi log level enum values to text. */ + +static constexpr const char *debug_amd_dbgapi_lib_log_level_enums[] = +{ + /* [AMD_DBGAPI_LOG_LEVEL_NONE] = */ "off", + /* [AMD_DBGAPI_LOG_LEVEL_FATAL_ERROR] = */ "error", + /* [AMD_DBGAPI_LOG_LEVEL_WARNING] = */ "warning", + /* [AMD_DBGAPI_LOG_LEVEL_INFO] = */ "info", + /* [AMD_DBGAPI_LOG_LEVEL_TRACE] = */ "trace", + /* [AMD_DBGAPI_LOG_LEVEL_VERBOSE] = */ "verbose", + nullptr +}; + +/* Storage for "set debug amd-dbgapi-lib log-level". */ + +static const char *debug_amd_dbgapi_lib_log_level + = debug_amd_dbgapi_lib_log_level_enums[AMD_DBGAPI_LOG_LEVEL_WARNING]; + +/* Get the amd-dbgapi library log level requested by the user. */ + +static amd_dbgapi_log_level_t +get_debug_amd_dbgapi_lib_log_level () +{ + for (size_t pos = 0; + debug_amd_dbgapi_lib_log_level_enums[pos] != nullptr; + ++pos) + if (debug_amd_dbgapi_lib_log_level + == debug_amd_dbgapi_lib_log_level_enums[pos]) + return static_cast (pos); + + gdb_assert_not_reached ("invalid log level"); +} + +/* Callback for "set debug amd-dbgapi log-level", apply the selected log level + to the library. */ + +static void +set_debug_amd_dbgapi_lib_log_level (const char *args, int from_tty, + struct cmd_list_element *c) +{ + amd_dbgapi_set_log_level (get_debug_amd_dbgapi_lib_log_level ()); +} + +/* Callback for "show debug amd-dbgapi log-level". */ + +static void +show_debug_amd_dbgapi_lib_log_level (struct ui_file *file, int from_tty, + struct cmd_list_element *c, + const char *value) +{ + gdb_printf (file, _("The amd-dbgapi library log level is %s.\n"), value); +} + +/* If the amd-dbgapi library is not attached to any process, finalize and + re-initialize it so that the handle ID numbers will all start from the + beginning again. This is only for convenience, not essential. */ + +static void +maybe_reset_amd_dbgapi () +{ + for (inferior *inf : all_non_exited_inferiors ()) + { + amd_dbgapi_inferior_info *info = get_amd_dbgapi_inferior_info (inf); + + if (info->process_id != AMD_DBGAPI_PROCESS_NONE) + return; + } + + amd_dbgapi_status_t status = amd_dbgapi_finalize (); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + error (_("amd-dbgapi failed to finalize (%s)"), + get_status_string (status)); + + status = amd_dbgapi_initialize (&dbgapi_callbacks); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + error (_("amd-dbgapi failed to initialize (%s)"), + get_status_string (status)); +} + +extern initialize_file_ftype _initialize_amd_dbgapi_target; + +void +_initialize_amd_dbgapi_target () +{ + /* Make sure the loaded debugger library version is greater than or equal to + the one used to build GDB. */ + uint32_t major, minor, patch; + amd_dbgapi_get_version (&major, &minor, &patch); + if (major != AMD_DBGAPI_VERSION_MAJOR || minor < AMD_DBGAPI_VERSION_MINOR) + error (_("amd-dbgapi library version mismatch, got %d.%d.%d, need %d.%d+"), + major, minor, patch, AMD_DBGAPI_VERSION_MAJOR, + AMD_DBGAPI_VERSION_MINOR); + + /* Initialize the AMD Debugger API. */ + amd_dbgapi_status_t status = amd_dbgapi_initialize (&dbgapi_callbacks); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + error (_("amd-dbgapi failed to initialize (%s)"), + get_status_string (status)); + + /* Set the initial log level. */ + amd_dbgapi_set_log_level (get_debug_amd_dbgapi_lib_log_level ()); + + /* Install observers. */ + gdb::observers::inferior_created.attach + (amd_dbgapi_target_inferior_created, + amd_dbgapi_target_inferior_created_observer_token, "amd-dbgapi"); + gdb::observers::inferior_exit.attach (amd_dbgapi_inferior_exited, "amd-dbgapi"); + gdb::observers::inferior_pre_detach.attach (amd_dbgapi_inferior_pre_detach, "amd-dbgapi"); + + add_basic_prefix_cmd ("amd-dbgapi-lib", no_class, + _("Generic command for setting amd-dbgapi library " + "debugging flags."), + &set_debug_amd_dbgapi_lib_list, 0, &setdebuglist); + + add_show_prefix_cmd ("amd-dbgapi-lib", no_class, + _("Generic command for showing amd-dbgapi library " + "debugging flags."), + &show_debug_amd_dbgapi_lib_list, 0, &showdebuglist); + + add_setshow_enum_cmd ("log-level", class_maintenance, + debug_amd_dbgapi_lib_log_level_enums, + &debug_amd_dbgapi_lib_log_level, + _("Set the amd-dbgapi library log level."), + _("Show the amd-dbgapi library log level."), + _("off == no logging is enabled\n" + "error == fatal errors are reported\n" + "warning == fatal errors and warnings are reported\n" + "info == fatal errors, warnings, and info " + "messages are reported\n" + "trace == fatal errors, warnings, info, and " + "API tracing messages are reported\n" + "verbose == all messages are reported"), + set_debug_amd_dbgapi_lib_log_level, + show_debug_amd_dbgapi_lib_log_level, + &set_debug_amd_dbgapi_lib_list, + &show_debug_amd_dbgapi_lib_list); + + add_setshow_boolean_cmd ("amd-dbgapi", class_maintenance, + &debug_amd_dbgapi, + _("Set debugging of amd-dbgapi target."), + _("Show debugging of amd-dbgapi target."), + _("\ +When on, print debug messages relating to the amd-dbgapi target."), + nullptr, nullptr, + &setdebuglist, &showdebuglist); +} diff --git a/gdb/amd-dbgapi-target.h b/gdb/amd-dbgapi-target.h new file mode 100644 index 00000000000..beff2ad0bed --- /dev/null +++ b/gdb/amd-dbgapi-target.h @@ -0,0 +1,116 @@ +/* Target used to communicate with the AMD Debugger API. + + Copyright (C) 2019-2022 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 AMD_DBGAPI_TARGET_H +#define AMD_DBGAPI_TARGET_H 1 + +#include "gdbsupport/observable.h" + +#include + +struct inferior; + +namespace detail +{ + +template +using is_amd_dbgapi_handle + = gdb::Or, + std::is_same, + std::is_same, + std::is_same, + std::is_same, + std::is_same, + std::is_same, + std::is_same, + std::is_same, + std::is_same, + std::is_same, + std::is_same, + std::is_same, + std::is_same, + std::is_same>; + +} /* namespace detail */ + +/* Get the token of amd-dbgapi's inferior_created observer. */ + +const gdb::observers::token & + get_amd_dbgapi_target_inferior_created_observer_token (); + +/* Comparison operators for amd-dbgapi handle types. */ + +template >> +bool +operator== (const T &lhs, const T &rhs) +{ + return lhs.handle == rhs.handle; +} + +template >> +bool +operator!= (const T &lhs, const T &rhs) +{ + return !(lhs == rhs); +} + +/* Return true if the given ptid is a GPU thread (wave) ptid. */ + +static inline bool +ptid_is_gpu (ptid_t ptid) +{ + /* FIXME: Currently using values that are known not to conflict with other + processes to indicate if it is a GPU thread. ptid.pid 1 is the init + process and is the only process that could have a ptid.lwp of 1. The init + process cannot have a GPU. No other process can have a ptid.lwp of 1. + The GPU wave ID is stored in the ptid.tid. */ + return ptid.pid () != 1 && ptid.lwp () == 1; +} + +/* Return INF's amd_dbgapi process id. */ + +amd_dbgapi_process_id_t get_amd_dbgapi_process_id (inferior *inf); + +/* Get the amd-dbgapi wave id for PTID. */ + +static inline amd_dbgapi_wave_id_t +get_amd_dbgapi_wave_id (ptid_t ptid) +{ + gdb_assert (ptid_is_gpu (ptid)); + return amd_dbgapi_wave_id_t { + static_cast (ptid.tid ()) + }; +} + +/* Get the textual version of STATUS. + + Always returns non-nullptr, and asserts that STATUS has a valid value. */ + +static inline const char * +get_status_string (amd_dbgapi_status_t status) +{ + const char *ret; + status = amd_dbgapi_get_status_string (status, &ret); + gdb_assert (status == AMD_DBGAPI_STATUS_SUCCESS); + return ret; +} + +#endif /* AMD_DBGAPI_TARGET_H */ diff --git a/gdb/amdgpu-tdep.c b/gdb/amdgpu-tdep.c new file mode 100644 index 00000000000..fc5e2438c7f --- /dev/null +++ b/gdb/amdgpu-tdep.c @@ -0,0 +1,1367 @@ +/* Target-dependent code for the AMDGPU architectures. + + Copyright (C) 2019-2022 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 . */ + +#include "defs.h" + +#include "amd-dbgapi-target.h" +#include "amdgpu-tdep.h" +#include "arch-utils.h" +#include "disasm.h" +#include "dwarf2/frame.h" +#include "frame-unwind.h" +#include "gdbarch.h" +#include "gdbsupport/selftest.h" +#include "gdbtypes.h" +#include "inferior.h" +#include "objfiles.h" +#include "observable.h" +#include "producer.h" +#include "reggroups.h" + +/* See amdgpu-tdep.h. */ + +bool +is_amdgpu_arch (struct gdbarch *arch) +{ + gdb_assert (arch != nullptr); + return gdbarch_bfd_arch_info (arch)->arch == bfd_arch_amdgcn; +} + +/* See amdgpu-tdep.h. */ + +amdgpu_gdbarch_tdep * +get_amdgpu_gdbarch_tdep (gdbarch *arch) +{ + return gdbarch_tdep (arch); +} + +/* Return the name of register REGNUM. */ + +static const char * +amdgpu_register_name (struct gdbarch *gdbarch, int regnum) +{ + /* The list of registers reported by amd-dbgapi for a given architecture + contains some duplicate names. For instance, there is an "exec" register + for waves in the wave32 mode and one for the waves in the wave64 mode. + However, at most one register with a given name is actually allocated for + a specific wave. If INFERIOR_PTID represents a GPU wave, we query + amd-dbgapi to know whether the requested register actually exists for the + current wave, so there won't be duplicates in the the register names we + report for that wave. + + But there are two known cases where INFERIOR_PTID doesn't represent a GPU + wave: + + - The user does "set arch amdgcn:gfxNNN" followed with "maint print + registers" + - The "register_name" selftest + + In these cases, we can't query amd-dbgapi to know whether we should hide + the register or not. The "register_name" selftest checks that there aren't + duplicates in the register names returned by the gdbarch, so if we simply + return all register names, that test will fail. The other simple option is + to never return a register name, which is what we do here. */ + if (!ptid_is_gpu (inferior_ptid)) + return ""; + + amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (inferior_ptid); + amdgpu_gdbarch_tdep *tdep = get_amdgpu_gdbarch_tdep (gdbarch); + + amd_dbgapi_register_exists_t register_exists; + if (amd_dbgapi_wave_register_exists (wave_id, tdep->register_ids[regnum], + ®ister_exists) + != AMD_DBGAPI_STATUS_SUCCESS + || register_exists != AMD_DBGAPI_REGISTER_PRESENT) + return ""; + + return tdep->register_names[regnum].c_str (); +} + +/* Return the internal register number for the DWARF register number DWARF_REG. + + Return -1 if there's no internal register mapping to DWARF_REG. */ + +static int +amdgpu_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int dwarf_reg) +{ + amdgpu_gdbarch_tdep *tdep = get_amdgpu_gdbarch_tdep (gdbarch); + + if (dwarf_reg < tdep->dwarf_regnum_to_gdb_regnum.size ()) + return tdep->dwarf_regnum_to_gdb_regnum[dwarf_reg]; + + return -1; +} + +/* A hierarchy of classes to represent an amd-dbgapi register type. */ + +struct amd_dbgapi_register_type +{ + enum class kind + { + INTEGER, + FLOAT, + DOUBLE, + VECTOR, + CODE_PTR, + FLAGS, + ENUM, + }; + + amd_dbgapi_register_type (kind kind, std::string lookup_name) + : m_kind (kind), m_lookup_name (std::move (lookup_name)) + {} + + virtual ~amd_dbgapi_register_type () = default; + + /* Return the type's kind. */ + kind kind () const + { return m_kind; } + + /* Name to use for this type in the existing type map. */ + const std::string &lookup_name () const + { return m_lookup_name; } + +private: + enum kind m_kind; + std::string m_lookup_name; +}; + +using amd_dbgapi_register_type_up = std::unique_ptr; + +struct amd_dbgapi_register_type_integer : public amd_dbgapi_register_type +{ + amd_dbgapi_register_type_integer (bool is_unsigned, unsigned int bit_size) + : amd_dbgapi_register_type + (kind::INTEGER, + string_printf ("%sint%d", is_unsigned ? "u" : "", bit_size)), + m_is_unsigned (is_unsigned), + m_bit_size (bit_size) + {} + + bool is_unsigned () const + { return m_is_unsigned; } + + unsigned int bit_size () const + { return m_bit_size; } + +private: + bool m_is_unsigned; + unsigned int m_bit_size; +}; + +struct amd_dbgapi_register_type_float : public amd_dbgapi_register_type +{ + amd_dbgapi_register_type_float () + : amd_dbgapi_register_type (kind::FLOAT, "float") + {} +}; + +struct amd_dbgapi_register_type_double : public amd_dbgapi_register_type +{ + amd_dbgapi_register_type_double () + : amd_dbgapi_register_type (kind::DOUBLE, "double") + {} +}; + +struct amd_dbgapi_register_type_vector : public amd_dbgapi_register_type +{ + amd_dbgapi_register_type_vector (const amd_dbgapi_register_type &element_type, + unsigned int count) + : amd_dbgapi_register_type (kind::VECTOR, + make_lookup_name (element_type, count)), + m_element_type (element_type), + m_count (count) + {} + + const amd_dbgapi_register_type &element_type () const + { return m_element_type; } + + unsigned int count () const + { return m_count; } + + static std::string make_lookup_name + (const amd_dbgapi_register_type &element_type, unsigned int count) + { + return string_printf ("%s[%d]", element_type.lookup_name ().c_str (), + count); + } + +private: + const amd_dbgapi_register_type &m_element_type; + unsigned int m_count; +}; + +struct amd_dbgapi_register_type_code_ptr : public amd_dbgapi_register_type +{ + amd_dbgapi_register_type_code_ptr () + : amd_dbgapi_register_type (kind::CODE_PTR, "void (*)()") + {} +}; + +struct amd_dbgapi_register_type_flags : public amd_dbgapi_register_type +{ + struct field + { + std::string name; + unsigned int bit_pos_start; + unsigned int bit_pos_end; + const amd_dbgapi_register_type *type; + }; + + using container_type = std::vector; + using const_iterator_type = container_type::const_iterator; + + amd_dbgapi_register_type_flags (unsigned int bit_size, gdb::string_view name) + : amd_dbgapi_register_type (kind::FLAGS, + make_lookup_name (bit_size, name)), + m_bit_size (bit_size), + m_name (std::move (name)) + {} + + unsigned int bit_size () const + { return m_bit_size; } + + void add_field (std::string name, unsigned int bit_pos_start, + unsigned int bit_pos_end, + const amd_dbgapi_register_type *type) + { + m_fields.push_back (field {std::move (name), bit_pos_start, + bit_pos_end, type}); + } + + container_type::size_type size () const + { return m_fields.size (); } + + const field &operator[] (container_type::size_type pos) const + { return m_fields[pos]; } + + const_iterator_type begin () const + { return m_fields.begin (); } + + const_iterator_type end () const + { return m_fields.end (); } + + const std::string &name () const + { return m_name; } + + static std::string make_lookup_name (int bits, gdb::string_view name) + { + std::string res = string_printf ("flags%d_t ", bits); + res.append (name.data (), name.size ()); + return res; + } + +private: + unsigned int m_bit_size; + container_type m_fields; + std::string m_name; +}; + +using amd_dbgapi_register_type_flags_up + = std::unique_ptr; + +struct amd_dbgapi_register_type_enum : public amd_dbgapi_register_type +{ + struct enumerator + { + std::string name; + ULONGEST value; + }; + + using container_type = std::vector; + using const_iterator_type = container_type::const_iterator; + + amd_dbgapi_register_type_enum (gdb::string_view name) + : amd_dbgapi_register_type (kind::ENUM, make_lookup_name (name)), + m_name (name.data (), name.length ()) + {} + + void set_bit_size (int bit_size) + { m_bit_size = bit_size; } + + unsigned int bit_size () const + { return m_bit_size; } + + void add_enumerator (std::string name, ULONGEST value) + { m_enumerators.push_back (enumerator {std::move (name), value}); } + + container_type::size_type size () const + { return m_enumerators.size (); } + + const enumerator &operator[] (container_type::size_type pos) const + { return m_enumerators[pos]; } + + const_iterator_type begin () const + { return m_enumerators.begin (); } + + const_iterator_type end () const + { return m_enumerators.end (); } + + const std::string &name () const + { return m_name; } + + static std::string make_lookup_name (gdb::string_view name) + { + std::string res = "enum "; + res.append (name.data (), name.length ()); + return res; + } + +private: + unsigned int m_bit_size = 32; + container_type m_enumerators; + std::string m_name; +}; + +using amd_dbgapi_register_type_enum_up + = std::unique_ptr; + +/* Map type lookup names to types. */ +using amd_dbgapi_register_type_map + = std::unordered_map; + +/* Parse S as a ULONGEST, raise an error on overflow. */ + +static ULONGEST +try_strtoulst (gdb::string_view s) +{ + errno = 0; + ULONGEST value = strtoulst (s.data (), nullptr, 0); + if (errno != 0) + error (_("Failed to parse integer.")); + + return value; +}; + +/* Shared regex bits. */ +#define IDENTIFIER "[A-Za-z0-9_.]+" +#define WS "[ \t]+" +#define WSOPT "[ \t]*" + +static const amd_dbgapi_register_type & +parse_amd_dbgapi_register_type (gdb::string_view type_name, + amd_dbgapi_register_type_map &type_map); + + +/* parse_amd_dbgapi_register_type helper for enum types. */ + +static void +parse_amd_dbgapi_register_type_enum_fields + (amd_dbgapi_register_type_enum &enum_type, gdb::string_view fields) +{ + compiled_regex regex (/* name */ + "^(" IDENTIFIER ")" + WSOPT "=" WSOPT + /* value */ + "([0-9]+)" + WSOPT "(," WSOPT ")?", + REG_EXTENDED, + _("Error in AMDGPU enum register type regex")); + regmatch_t matches[4]; + + while (!fields.empty ()) + { + int res = regex.exec (fields.data (), ARRAY_SIZE (matches), matches, 0); + if (res == REG_NOMATCH) + error (_("Failed to parse enum fields")); + + auto sv_from_match = [fields] (const regmatch_t &m) + { return fields.substr (m.rm_so, m.rm_eo - m.rm_so); }; + + gdb::string_view name = sv_from_match (matches[1]); + gdb::string_view value_str = sv_from_match (matches[2]); + ULONGEST value = try_strtoulst (value_str); + + if (value > std::numeric_limits::max ()) + enum_type.set_bit_size (64); + + enum_type.add_enumerator (gdb::to_string (name), value); + + fields = fields.substr (matches[0].rm_eo); + } +} + +/* parse_amd_dbgapi_register_type helper for flags types. */ + +static void +parse_amd_dbgapi_register_type_flags_fields + (amd_dbgapi_register_type_flags &flags_type, + int bits, gdb::string_view name, gdb::string_view fields, + amd_dbgapi_register_type_map &type_map) +{ + gdb_assert (bits == 32 || bits == 64); + + std::string regex_str + = string_printf (/* type */ + "^(bool|uint%d_t|enum" WS IDENTIFIER WSOPT "(\\{[^}]*})?)" + WS + /* name */ + "(" IDENTIFIER ")" WSOPT + /* bit position */ + "@([0-9]+)(-[0-9]+)?" WSOPT ";" WSOPT, + bits); + compiled_regex regex (regex_str.c_str (), REG_EXTENDED, + _("Error in AMDGPU register type flags fields regex")); + regmatch_t matches[6]; + + while (!fields.empty ()) + { + int res = regex.exec (fields.data (), ARRAY_SIZE (matches), matches, 0); + if (res == REG_NOMATCH) + error (_("Failed to parse flags type fields string")); + + auto sv_from_match = [fields] (const regmatch_t &m) + { return fields.substr (m.rm_so, m.rm_eo - m.rm_so); }; + + gdb::string_view field_type_str = sv_from_match (matches[1]); + gdb::string_view field_name = sv_from_match (matches[3]); + gdb::string_view pos_begin_str = sv_from_match (matches[4]); + ULONGEST pos_begin = try_strtoulst (pos_begin_str); + + if (field_type_str == "bool") + flags_type.add_field (gdb::to_string (field_name), pos_begin, pos_begin, + nullptr); + else + { + if (matches[5].rm_so == -1) + error (_("Missing end bit position")); + + gdb::string_view pos_end_str = sv_from_match (matches[5]); + ULONGEST pos_end = try_strtoulst (pos_end_str.substr (1)); + const amd_dbgapi_register_type &field_type + = parse_amd_dbgapi_register_type (field_type_str, type_map); + flags_type.add_field (gdb::to_string (field_name), pos_begin, pos_end, + &field_type); + } + + fields = fields.substr (matches[0].rm_eo); + } +} + +/* parse_amd_dbgapi_register_type helper for scalars. */ + +static const amd_dbgapi_register_type & +parse_amd_dbgapi_register_type_scalar (gdb::string_view name, + amd_dbgapi_register_type_map &type_map) +{ + std::string name_str = gdb::to_string (name); + auto it = type_map.find (name_str); + if (it != type_map.end ()) + { + enum amd_dbgapi_register_type::kind kind = it->second->kind (); + if (kind != amd_dbgapi_register_type::kind::INTEGER + && kind != amd_dbgapi_register_type::kind::FLOAT + && kind != amd_dbgapi_register_type::kind::DOUBLE + && kind != amd_dbgapi_register_type::kind::CODE_PTR) + error (_("type mismatch")); + + return *it->second; + } + + amd_dbgapi_register_type_up type; + if (name == "int32_t") + type.reset (new amd_dbgapi_register_type_integer (false, 32)); + else if (name == "uint32_t") + type.reset (new amd_dbgapi_register_type_integer (true, 32)); + else if (name == "int64_t") + type.reset (new amd_dbgapi_register_type_integer (false, 64)); + else if (name == "uint64_t") + type.reset (new amd_dbgapi_register_type_integer (true, 64)); + else if (name == "float") + type.reset (new amd_dbgapi_register_type_float ()); + else if (name == "double") + type.reset (new amd_dbgapi_register_type_double ()); + else if (name == "void (*)()") + type.reset (new amd_dbgapi_register_type_code_ptr ()); + else + error (_("unknown type %s"), name_str.c_str ()); + + auto insertion_pair = type_map.emplace (name, std::move (type)); + return *insertion_pair.first->second; +} + +/* Parse an amd-dbgapi register type string into an amd_dbgapi_register_type + object. + + See the documentation of AMD_DBGAPI_REGISTER_INFO_TYPE in amd-dbgapi.h for + details about the format. */ + +static const amd_dbgapi_register_type & +parse_amd_dbgapi_register_type (gdb::string_view type_str, + amd_dbgapi_register_type_map &type_map) +{ + size_t pos_open_bracket = type_str.find_last_of ('['); + auto sv_from_match = [type_str] (const regmatch_t &m) + { return type_str.substr (m.rm_so, m.rm_eo - m.rm_so); }; + + if (pos_open_bracket != gdb::string_view::npos) + { + /* Vector types. */ + gdb::string_view element_type_str + = type_str.substr (0, pos_open_bracket); + const amd_dbgapi_register_type &element_type + = parse_amd_dbgapi_register_type (element_type_str, type_map); + + size_t pos_close_bracket = type_str.find_last_of (']'); + gdb_assert (pos_close_bracket != gdb::string_view::npos); + gdb::string_view count_str_view + = type_str.substr (pos_open_bracket + 1, + pos_close_bracket - pos_open_bracket); + std::string count_str = gdb::to_string (count_str_view); + unsigned int count = std::stoul (count_str); + + std::string lookup_name + = amd_dbgapi_register_type_vector::make_lookup_name (element_type, count); + auto existing_type_it = type_map.find (lookup_name); + if (existing_type_it != type_map.end ()) + { + gdb_assert (existing_type_it->second->kind () + == amd_dbgapi_register_type::kind::VECTOR); + return *existing_type_it->second; + } + + amd_dbgapi_register_type_up type + (new amd_dbgapi_register_type_vector (element_type, count)); + auto insertion_pair + = type_map.emplace (type->lookup_name (), std::move (type)); + return *insertion_pair.first->second; + } + + if (type_str.find ("flags32_t") == 0 || type_str.find ("flags64_t") == 0) + { + /* Split 'type_str' into 4 tokens: "(type) (name) ({ (fields) })". */ + compiled_regex regex ("^(flags32_t|flags64_t)" + WS "(" IDENTIFIER ")" WSOPT + "(\\{" WSOPT "(.*)})?", + REG_EXTENDED, + _("Error in AMDGPU register type regex")); + + regmatch_t matches[5]; + int res = regex.exec (type_str.data (), ARRAY_SIZE (matches), matches, 0); + if (res == REG_NOMATCH) + error (_("Failed to parse flags type string")); + + gdb::string_view flags_keyword = sv_from_match (matches[1]); + unsigned int bit_size = flags_keyword == "flags32_t" ? 32 : 64; + gdb::string_view name = sv_from_match (matches[2]); + std::string lookup_name + = amd_dbgapi_register_type_flags::make_lookup_name (bit_size, name); + auto existing_type_it = type_map.find (lookup_name); + + if (matches[3].rm_so == -1) + { + /* No braces, lookup existing type. */ + if (existing_type_it == type_map.end ()) + error (_("reference to unknown type %s."), + gdb::to_string (name).c_str ()); + + if (existing_type_it->second->kind () + != amd_dbgapi_register_type::kind::FLAGS) + error (_("type mismatch")); + + return *existing_type_it->second; + } + else + { + /* With braces, it's a definition. */ + if (existing_type_it != type_map.end ()) + error (_("re-definition of type %s."), + gdb::to_string (name).c_str ()); + + amd_dbgapi_register_type_flags_up flags_type + (new amd_dbgapi_register_type_flags (bit_size, name)); + gdb::string_view fields_without_braces = sv_from_match (matches[4]); + + parse_amd_dbgapi_register_type_flags_fields + (*flags_type, bit_size, name, fields_without_braces, type_map); + + auto insertion_pair + = type_map.emplace (flags_type->lookup_name (), + std::move (flags_type)); + return *insertion_pair.first->second; + } + } + + if (type_str.find ("enum") == 0) + { + compiled_regex regex ("^enum" WS "(" IDENTIFIER ")" WSOPT "(\\{" WSOPT "([^}]*)})?", + REG_EXTENDED, + _("Error in AMDGPU register type enum regex")); + + /* Split 'type_name' into 3 tokens: "(name) ( { (fields) } )". */ + regmatch_t matches[4]; + int res = regex.exec (type_str.data (), ARRAY_SIZE (matches), matches, 0); + if (res == REG_NOMATCH) + error (_("Failed to parse flags type string")); + + gdb::string_view name = sv_from_match (matches[1]); + + std::string lookup_name + = amd_dbgapi_register_type_enum::make_lookup_name (name); + auto existing_type_it = type_map.find (lookup_name); + + if (matches[2].rm_so == -1) + { + /* No braces, lookup existing type. */ + if (existing_type_it == type_map.end ()) + error (_("reference to unknown type %s"), + gdb::to_string (name).c_str ()); + + if (existing_type_it->second->kind () + != amd_dbgapi_register_type::kind::ENUM) + error (_("type mismatch")); + + return *existing_type_it->second; + } + else + { + /* With braces, it's a definition. */ + if (existing_type_it != type_map.end ()) + error (_("re-definition of type %s"), + gdb::to_string (name).c_str ()); + + amd_dbgapi_register_type_enum_up enum_type + (new amd_dbgapi_register_type_enum (name)); + gdb::string_view fields_without_braces = sv_from_match (matches[3]); + + parse_amd_dbgapi_register_type_enum_fields + (*enum_type, fields_without_braces); + + auto insertion_pair + = type_map.emplace (enum_type->lookup_name (), + std::move (enum_type)); + return *insertion_pair.first->second; + } + } + + return parse_amd_dbgapi_register_type_scalar (type_str, type_map); +} + +/* Convert an amd_dbgapi_register_type object to a GDB type. */ + +static type * +amd_dbgapi_register_type_to_gdb_type (const amd_dbgapi_register_type &type, + struct gdbarch *gdbarch) +{ + switch (type.kind ()) + { + case amd_dbgapi_register_type::kind::INTEGER: + { + const auto &integer_type + = static_cast (type); + switch (integer_type.bit_size ()) + { + case 32: + if (integer_type.is_unsigned ()) + return builtin_type (gdbarch)->builtin_uint32; + else + return builtin_type (gdbarch)->builtin_int32; + + case 64: + if (integer_type.is_unsigned ()) + return builtin_type (gdbarch)->builtin_uint64; + else + return builtin_type (gdbarch)->builtin_int64; + + default: + gdb_assert_not_reached ("invalid bit size"); + } + } + + case amd_dbgapi_register_type::kind::VECTOR: + { + const auto &vector_type + = static_cast (type); + struct type *element_type + = amd_dbgapi_register_type_to_gdb_type (vector_type.element_type (), + gdbarch); + return init_vector_type (element_type, vector_type.count ()); + } + + case amd_dbgapi_register_type::kind::FLOAT: + return builtin_type (gdbarch)->builtin_float; + + case amd_dbgapi_register_type::kind::DOUBLE: + return builtin_type (gdbarch)->builtin_double; + + case amd_dbgapi_register_type::kind::CODE_PTR: + return builtin_type (gdbarch)->builtin_func_ptr; + + case amd_dbgapi_register_type::kind::FLAGS: + { + const auto &flags_type + = static_cast (type); + struct type *gdb_type + = arch_flags_type (gdbarch, flags_type.name ().c_str (), + flags_type.bit_size ()); + + for (const auto &field : flags_type) + { + if (field.type == nullptr) + { + gdb_assert (field.bit_pos_start == field.bit_pos_end); + append_flags_type_flag (gdb_type, field.bit_pos_start, + field.name.c_str ()); + } + else + { + struct type *field_type + = amd_dbgapi_register_type_to_gdb_type (*field.type, gdbarch); + gdb_assert (field_type != nullptr); + append_flags_type_field + (gdb_type, field.bit_pos_start, + field.bit_pos_end - field.bit_pos_start + 1, + field_type, field.name.c_str ()); + } + } + + return gdb_type; + } + + case amd_dbgapi_register_type::kind::ENUM: + { + const auto &enum_type + = static_cast (type); + struct type *gdb_type + = arch_type (gdbarch, TYPE_CODE_ENUM, enum_type.bit_size (), + enum_type.name ().c_str ()); + + gdb_type->set_num_fields (enum_type.size ()); + gdb_type->set_fields + ((struct field *) TYPE_ZALLOC (gdb_type, (sizeof (struct field) + * enum_type.size ()))); + gdb_type->set_is_unsigned (true); + + for (size_t i = 0; i < enum_type.size (); ++i) + { + const auto &field = enum_type[i]; + gdb_type->field (i).set_name (xstrdup (field.name.c_str ())); + gdb_type->field (i).set_loc_enumval (field.value); + } + + return gdb_type; + } + + default: + gdb_assert_not_reached ("unhandled amd_dbgapi_register_type kind"); + } +} + +static type * +amdgpu_register_type (struct gdbarch *gdbarch, int regnum) +{ + amdgpu_gdbarch_tdep *tdep = get_amdgpu_gdbarch_tdep (gdbarch); + + if (tdep->register_types[regnum] == nullptr) + { + /* This is done lazily (not at gdbarch initialization time), because it + requires access to builtin_type, which can't be used while the gdbarch + is not fully initialized. */ + char *bytes; + amd_dbgapi_status_t status + = amd_dbgapi_register_get_info (tdep->register_ids[regnum], + AMD_DBGAPI_REGISTER_INFO_TYPE, + sizeof (bytes), &bytes); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + error (_("Failed to get register type from amd-dbgapi")); + + gdb::unique_xmalloc_ptr bytes_holder (bytes); + amd_dbgapi_register_type_map type_map; + const amd_dbgapi_register_type ®ister_type + = parse_amd_dbgapi_register_type (bytes, type_map); + tdep->register_types[regnum] + = amd_dbgapi_register_type_to_gdb_type (register_type, gdbarch); + gdb_assert (tdep->register_types[regnum] != nullptr); + } + + return tdep->register_types[regnum]; +} + +static int +amdgpu_register_reggroup_p (struct gdbarch *gdbarch, int regnum, + const reggroup *group) +{ + amdgpu_gdbarch_tdep *tdep = get_amdgpu_gdbarch_tdep (gdbarch); + + auto it = tdep->register_class_map.find (group->name ()); + if (it == tdep->register_class_map.end ()) + return group == all_reggroup; + + amd_dbgapi_register_class_state_t state; + if (amd_dbgapi_register_is_in_register_class (it->second, + tdep->register_ids[regnum], + &state) + != AMD_DBGAPI_STATUS_SUCCESS) + return group == all_reggroup; + + return (state == AMD_DBGAPI_REGISTER_CLASS_STATE_MEMBER + || group == all_reggroup); +} + +static int +amdgpu_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *) +{ + return get_amdgpu_gdbarch_tdep (gdbarch)->breakpoint_instruction_size; +} + +static const gdb_byte * +amdgpu_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size) +{ + *size = kind; + return get_amdgpu_gdbarch_tdep (gdbarch)->breakpoint_instruction_bytes.get (); +} + +struct amdgpu_frame_cache +{ + CORE_ADDR base; + CORE_ADDR pc; +}; + +static amdgpu_frame_cache * +amdgpu_frame_cache (frame_info_ptr this_frame, void **this_cache) +{ + if (*this_cache != nullptr) + return (struct amdgpu_frame_cache *) *this_cache; + + struct amdgpu_frame_cache *cache + = FRAME_OBSTACK_ZALLOC (struct amdgpu_frame_cache); + (*this_cache) = cache; + + cache->pc = get_frame_func (this_frame); + cache->base = 0; + + return cache; +} + +static void +amdgpu_frame_this_id (frame_info_ptr this_frame, void **this_cache, + frame_id *this_id) +{ + struct amdgpu_frame_cache *cache + = amdgpu_frame_cache (this_frame, this_cache); + + if (get_frame_type (this_frame) == INLINE_FRAME) + (*this_id) = frame_id_build (cache->base, cache->pc); + else + (*this_id) = outer_frame_id; + + frame_debug_printf ("this_frame=%d, type=%d, this_id=%s", + frame_relative_level (this_frame), + get_frame_type (this_frame), + this_id->to_string ().c_str ()); +} + +static frame_id +amdgpu_dummy_id (struct gdbarch *gdbarch, frame_info_ptr this_frame) +{ + return frame_id_build (0, get_frame_pc (this_frame)); +} + +static struct value * +amdgpu_frame_prev_register (frame_info_ptr this_frame, void **this_cache, + int regnum) +{ + return frame_unwind_got_register (this_frame, regnum, regnum); +} + +static const frame_unwind amdgpu_frame_unwind = { + "amdgpu", + NORMAL_FRAME, + default_frame_unwind_stop_reason, + amdgpu_frame_this_id, + amdgpu_frame_prev_register, + nullptr, + default_frame_sniffer, + nullptr, + nullptr, +}; + +static int +print_insn_amdgpu (bfd_vma memaddr, struct disassemble_info *info) +{ + gdb_disassemble_info *di + = static_cast (info->application_data); + + /* Try to read at most INSTRUCTION_SIZE bytes. */ + + amd_dbgapi_size_t instruction_size = gdbarch_max_insn_length (di->arch ()); + gdb::byte_vector buffer (instruction_size); + + /* read_memory_func doesn't support partial reads, so if the read + fails, try one byte less, on and on until we manage to read + something. A case where this would happen is if we're trying to + read the last instruction at the end of a file section and that + instruction is smaller than the largest instruction. */ + while (instruction_size > 0) + { + int ret = info->read_memory_func (memaddr, buffer.data (), + instruction_size, info); + if (ret == 0) + break; + + --instruction_size; + } + + if (instruction_size == 0) + { + info->memory_error_func (-1, memaddr, info); + return -1; + } + + amd_dbgapi_architecture_id_t architecture_id; + amd_dbgapi_status_t status + = amd_dbgapi_get_architecture (gdbarch_bfd_arch_info (di->arch ())->mach, + &architecture_id); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + return -1; + + auto symbolizer = [] (amd_dbgapi_symbolizer_id_t symbolizer_id, + amd_dbgapi_global_address_t address, + char **symbol_text) -> amd_dbgapi_status_t + { + gdb_disassemble_info *disasm_info + = reinterpret_cast (symbolizer_id); + gdb_printing_disassembler *disasm + = dynamic_cast (disasm_info); + gdb_assert (disasm != nullptr); + + string_file string (disasm->stream ()->can_emit_style_escape ()); + print_address (disasm->arch (), address, &string); + *symbol_text = xstrdup (string.c_str ()); + + return AMD_DBGAPI_STATUS_SUCCESS; + }; + auto symbolizer_id = reinterpret_cast (di); + char *instruction_text = nullptr; + status = amd_dbgapi_disassemble_instruction (architecture_id, memaddr, + &instruction_size, + buffer.data (), + &instruction_text, + symbolizer_id, + symbolizer); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + { + size_t alignment; + status = amd_dbgapi_architecture_get_info + (architecture_id, + AMD_DBGAPI_ARCHITECTURE_INFO_MINIMUM_INSTRUCTION_ALIGNMENT, + sizeof (alignment), &alignment); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + error (_("amd_dbgapi_architecture_get_info failed")); + + info->fprintf_func (di, ""); + + /* Skip to the next valid instruction address. */ + return align_up (memaddr + 1, alignment) - memaddr; + } + + /* Print the instruction. */ + info->fprintf_func (di, "%s", instruction_text); + + /* Free the memory allocated by the amd-dbgapi. */ + xfree (instruction_text); + + return static_cast (instruction_size); +} + +static CORE_ADDR +amdgpu_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) +{ + CORE_ADDR func_addr; + + /* See if we can determine the end of the prologue via the symbol table. + If so, then return either PC, or the PC after the prologue, whichever + is greater. */ + if (find_pc_partial_function (start_pc, nullptr, &func_addr, nullptr)) + { + CORE_ADDR post_prologue_pc + = skip_prologue_using_sal (gdbarch, func_addr); + struct compunit_symtab *cust = find_pc_compunit_symtab (func_addr); + + /* Clang always emits a line note before the prologue and another + one after. We trust clang to emit usable line notes. */ + if (post_prologue_pc != 0 + && cust != nullptr + && cust->producer () != nullptr + && producer_is_llvm (cust->producer ())) + return std::max (start_pc, post_prologue_pc); + } + + return start_pc; +} + +static bool +amdgpu_supports_arch_info (const struct bfd_arch_info *info) +{ + amd_dbgapi_architecture_id_t architecture_id; + amd_dbgapi_status_t status + = amd_dbgapi_get_architecture (info->mach, &architecture_id); + + gdb_assert (status != AMD_DBGAPI_STATUS_ERROR_NOT_INITIALIZED); + return status == AMD_DBGAPI_STATUS_SUCCESS; +} + +static struct gdbarch * +amdgpu_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) +{ + /* If there is already a candidate, use it. */ + arches = gdbarch_list_lookup_by_info (arches, &info); + if (arches != nullptr) + return arches->gdbarch; + + /* Allocate space for the new architecture. */ + gdbarch_up gdbarch_u + (gdbarch_alloc (&info, gdbarch_tdep_up (new amdgpu_gdbarch_tdep))); + gdbarch *gdbarch = gdbarch_u.get (); + amdgpu_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* Data types. */ + set_gdbarch_char_signed (gdbarch, 0); + set_gdbarch_ptr_bit (gdbarch, 64); + set_gdbarch_addr_bit (gdbarch, 64); + set_gdbarch_short_bit (gdbarch, 16); + set_gdbarch_int_bit (gdbarch, 32); + set_gdbarch_long_bit (gdbarch, 64); + set_gdbarch_long_long_bit (gdbarch, 64); + set_gdbarch_float_bit (gdbarch, 32); + set_gdbarch_double_bit (gdbarch, 64); + set_gdbarch_long_double_bit (gdbarch, 128); + set_gdbarch_half_format (gdbarch, floatformats_ieee_half); + set_gdbarch_float_format (gdbarch, floatformats_ieee_single); + set_gdbarch_double_format (gdbarch, floatformats_ieee_double); + set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double); + + /* Frame interpretation. */ + set_gdbarch_skip_prologue (gdbarch, amdgpu_skip_prologue); + set_gdbarch_inner_than (gdbarch, core_addr_greaterthan); + dwarf2_append_unwinders (gdbarch); + frame_unwind_append_unwinder (gdbarch, &amdgpu_frame_unwind); + set_gdbarch_dummy_id (gdbarch, amdgpu_dummy_id); + + /* Registers and memory. */ + amd_dbgapi_architecture_id_t architecture_id; + amd_dbgapi_status_t status + = amd_dbgapi_get_architecture (gdbarch_bfd_arch_info (gdbarch)->mach, + &architecture_id); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + { + warning (_("Failed to get architecture from amd-dbgapi")); + return nullptr; + } + + + /* Add register groups. */ + size_t register_class_count; + amd_dbgapi_register_class_id_t *register_class_ids; + status = amd_dbgapi_architecture_register_class_list (architecture_id, + ®ister_class_count, + ®ister_class_ids); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + { + warning (_("Failed to get register class list from amd-dbgapi")); + return nullptr; + } + + gdb::unique_xmalloc_ptr + register_class_ids_holder (register_class_ids); + + for (size_t i = 0; i < register_class_count; ++i) + { + char *bytes; + status = amd_dbgapi_architecture_register_class_get_info + (register_class_ids[i], AMD_DBGAPI_REGISTER_CLASS_INFO_NAME, + sizeof (bytes), &bytes); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + { + warning (_("Failed to get register class name from amd-dbgapi")); + return nullptr; + } + + gdb::unique_xmalloc_ptr name (bytes); + + auto inserted = tdep->register_class_map.emplace (name.get (), + register_class_ids[i]); + gdb_assert (inserted.second); + + /* Avoid creating a user reggroup with the same name as some built-in + reggroup, such as "general", "system", "vector", etc. */ + if (reggroup_find (gdbarch, name.get ()) != nullptr) + continue; + + /* Allocate the reggroup in the gdbarch. */ + reggroup_add + (gdbarch, reggroup_gdbarch_new (gdbarch, name.get (), USER_REGGROUP)); + } + + /* Add registers. */ + size_t register_count; + amd_dbgapi_register_id_t *register_ids; + status = amd_dbgapi_architecture_register_list (architecture_id, + ®ister_count, + ®ister_ids); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + { + warning (_("Failed to get register list from amd-dbgapi")); + return nullptr; + } + + gdb::unique_xmalloc_ptr register_ids_holder + (register_ids); + + tdep->register_ids.insert (tdep->register_ids.end (), ®ister_ids[0], + ®ister_ids[register_count]); + + tdep->register_properties.resize (register_count, + AMD_DBGAPI_REGISTER_PROPERTY_NONE); + for (size_t regnum = 0; regnum < register_count; ++regnum) + { + auto ®ister_properties = tdep->register_properties[regnum]; + if (amd_dbgapi_register_get_info (register_ids[regnum], + AMD_DBGAPI_REGISTER_INFO_PROPERTIES, + sizeof (register_properties), + ®ister_properties) + != AMD_DBGAPI_STATUS_SUCCESS) + { + warning (_("Failed to get register properties from amd-dbgapi")); + return nullptr; + } + } + + set_gdbarch_num_regs (gdbarch, register_count); + set_gdbarch_num_pseudo_regs (gdbarch, 0); + + tdep->register_names.resize (register_count); + tdep->register_types.resize (register_count); + for (size_t i = 0; i < register_count; ++i) + { + /* Set amd-dbgapi register id -> gdb regnum mapping. */ + tdep->regnum_map.emplace (tdep->register_ids[i], i); + + /* Get register name. */ + char *bytes; + status = amd_dbgapi_register_get_info (tdep->register_ids[i], + AMD_DBGAPI_REGISTER_INFO_NAME, + sizeof (bytes), &bytes); + if (status == AMD_DBGAPI_STATUS_SUCCESS) + { + tdep->register_names[i] = bytes; + xfree (bytes); + } + + /* Get register DWARF number. */ + uint64_t dwarf_num; + status = amd_dbgapi_register_get_info (tdep->register_ids[i], + AMD_DBGAPI_REGISTER_INFO_DWARF, + sizeof (dwarf_num), &dwarf_num); + if (status == AMD_DBGAPI_STATUS_SUCCESS) + { + if (dwarf_num >= tdep->dwarf_regnum_to_gdb_regnum.size ()) + tdep->dwarf_regnum_to_gdb_regnum.resize (dwarf_num + 1, -1); + + tdep->dwarf_regnum_to_gdb_regnum[dwarf_num] = i; + } + } + + amd_dbgapi_register_id_t pc_register_id; + status = amd_dbgapi_architecture_get_info + (architecture_id, AMD_DBGAPI_ARCHITECTURE_INFO_PC_REGISTER, + sizeof (pc_register_id), &pc_register_id); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + { + warning (_("Failed to get PC register from amd-dbgapi")); + return nullptr; + } + + set_gdbarch_pc_regnum (gdbarch, tdep->regnum_map[pc_register_id]); + set_gdbarch_ps_regnum (gdbarch, -1); + set_gdbarch_sp_regnum (gdbarch, -1); + set_gdbarch_fp0_regnum (gdbarch, -1); + + set_gdbarch_dwarf2_reg_to_regnum (gdbarch, amdgpu_dwarf_reg_to_regnum); + + /* Register representation. */ + set_gdbarch_register_name (gdbarch, amdgpu_register_name); + set_gdbarch_register_type (gdbarch, amdgpu_register_type); + set_gdbarch_register_reggroup_p (gdbarch, amdgpu_register_reggroup_p); + + /* Disassembly. */ + set_gdbarch_print_insn (gdbarch, print_insn_amdgpu); + + /* Instructions. */ + amd_dbgapi_size_t max_insn_length = 0; + status = amd_dbgapi_architecture_get_info + (architecture_id, AMD_DBGAPI_ARCHITECTURE_INFO_LARGEST_INSTRUCTION_SIZE, + sizeof (max_insn_length), &max_insn_length); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + error (_("amd_dbgapi_architecture_get_info failed")); + + set_gdbarch_max_insn_length (gdbarch, max_insn_length); + + status = amd_dbgapi_architecture_get_info + (architecture_id, AMD_DBGAPI_ARCHITECTURE_INFO_BREAKPOINT_INSTRUCTION_SIZE, + sizeof (tdep->breakpoint_instruction_size), + &tdep->breakpoint_instruction_size); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + error (_("amd_dbgapi_architecture_get_info failed")); + + gdb_byte *breakpoint_instruction_bytes; + status = amd_dbgapi_architecture_get_info + (architecture_id, AMD_DBGAPI_ARCHITECTURE_INFO_BREAKPOINT_INSTRUCTION, + sizeof (breakpoint_instruction_bytes), &breakpoint_instruction_bytes); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + error (_("amd_dbgapi_architecture_get_info failed")); + + tdep->breakpoint_instruction_bytes.reset (breakpoint_instruction_bytes); + + set_gdbarch_breakpoint_kind_from_pc (gdbarch, + amdgpu_breakpoint_kind_from_pc); + set_gdbarch_sw_breakpoint_from_kind (gdbarch, + amdgpu_sw_breakpoint_from_kind); + + amd_dbgapi_size_t pc_adjust; + status = amd_dbgapi_architecture_get_info + (architecture_id, + AMD_DBGAPI_ARCHITECTURE_INFO_BREAKPOINT_INSTRUCTION_PC_ADJUST, + sizeof (pc_adjust), &pc_adjust); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + error (_("amd_dbgapi_architecture_get_info failed")); + + set_gdbarch_decr_pc_after_break (gdbarch, pc_adjust); + + return gdbarch_u.release (); +} + +#if defined GDB_SELF_TEST + +static void +amdgpu_register_type_parse_test () +{ + { + /* A type that exercises flags and enums, in particular looking up an + existing enum type by name. */ + const char *flags_type_str = + "flags32_t mode { \ + enum fp_round { \ + NEAREST_EVEN = 0, \ + PLUS_INF = 1, \ + MINUS_INF = 2, \ + ZERO = 3 \ + } FP_ROUND.32 @0-1; \ + enum fp_round FP_ROUND.64_16 @2-3; \ + enum fp_denorm { \ + FLUSH_SRC_DST = 0, \ + FLUSH_DST = 1, \ + FLUSH_SRC = 2, \ + FLUSH_NONE = 3 \ + } FP_DENORM.32 @4-5; \ + enum fp_denorm FP_DENORM.64_16 @6-7; \ + bool DX10_CLAMP @8; \ + bool IEEE @9; \ + bool LOD_CLAMPED @10; \ + bool DEBUG_EN @11; \ + bool EXCP_EN.INVALID @12; \ + bool EXCP_EN.DENORM @13; \ + bool EXCP_EN.DIV0 @14; \ + bool EXCP_EN.OVERFLOW @15; \ + bool EXCP_EN.UNDERFLOW @16; \ + bool EXCP_EN.INEXACT @17; \ + bool EXCP_EN.INT_DIV0 @18; \ + bool EXCP_EN.ADDR_WATCH @19; \ + bool FP16_OVFL @23; \ + bool POPS_PACKER0 @24; \ + bool POPS_PACKER1 @25; \ + bool DISABLE_PERF @26; \ + bool GPR_IDX_EN @27; \ + bool VSKIP @28; \ + uint32_t CSP @29-31; \ + }"; + amd_dbgapi_register_type_map type_map; + const amd_dbgapi_register_type &type + = parse_amd_dbgapi_register_type (flags_type_str, type_map); + + gdb_assert (type.kind () == amd_dbgapi_register_type::kind::FLAGS); + + const auto &f = static_cast (type); + gdb_assert (f.size () == 23); + + /* Check the two "FP_ROUND" fields. */ + auto check_fp_round_field + = [] (const char *name, const amd_dbgapi_register_type_flags::field &field) + { + gdb_assert (field.name == name); + gdb_assert (field.type->kind () + == amd_dbgapi_register_type::kind::ENUM); + + const auto &e + = static_cast (*field.type); + gdb_assert (e.size () == 4); + gdb_assert (e[0].name == "NEAREST_EVEN"); + gdb_assert (e[0].value == 0); + gdb_assert (e[3].name == "ZERO"); + gdb_assert (e[3].value == 3); + }; + + check_fp_round_field ("FP_ROUND.32", f[0]); + check_fp_round_field ("FP_ROUND.64_16", f[1]); + + /* Check the "CSP" field. */ + gdb_assert (f[22].name == "CSP"); + gdb_assert (f[22].type->kind () == amd_dbgapi_register_type::kind::INTEGER); + + const auto &i + = static_cast (*f[22].type); + gdb_assert (i.bit_size () == 32); + gdb_assert (i.is_unsigned ()); + } + + { + /* Test the vector type. */ + const char *vector_type_str = "int32_t[64]"; + amd_dbgapi_register_type_map type_map; + const amd_dbgapi_register_type &type + = parse_amd_dbgapi_register_type (vector_type_str, type_map); + + gdb_assert (type.kind () == amd_dbgapi_register_type::kind::VECTOR); + + const auto &v = static_cast (type); + gdb_assert (v.count () == 64); + + const auto &et = v.element_type (); + gdb_assert (et.kind () == amd_dbgapi_register_type::kind::INTEGER); + + const auto &i = static_cast (et); + gdb_assert (i.bit_size () == 32); + gdb_assert (!i.is_unsigned ()); + } +} + +#endif + +void _initialize_amdgpu_tdep (); + +void +_initialize_amdgpu_tdep () +{ + gdbarch_register (bfd_arch_amdgcn, amdgpu_gdbarch_init, NULL, + amdgpu_supports_arch_info); +#if defined GDB_SELF_TEST + selftests::register_test ("amdgpu-register-type-parse-flags-fields", + amdgpu_register_type_parse_test); +#endif +} diff --git a/gdb/amdgpu-tdep.h b/gdb/amdgpu-tdep.h new file mode 100644 index 00000000000..24081ebaf7d --- /dev/null +++ b/gdb/amdgpu-tdep.h @@ -0,0 +1,93 @@ +/* Target-dependent code for the AMDGPU architectures. + + Copyright (C) 2019-2022 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 AMDGPU_TDEP_H +#define AMDGPU_TDEP_H + +#include "gdbarch.h" + +#include +#include + +/* Provide std::unordered_map::Hash for amd_dbgapi_register_id_t. */ +struct register_id_hash +{ + size_t + operator() (const amd_dbgapi_register_id_t ®ister_id) const + { + return std::hash () (register_id.handle); + } +}; + +/* Provide std::unordered_map::Equal for amd_dbgapi_register_id_t. */ +struct register_id_equal_to +{ + bool + operator() (const amd_dbgapi_register_id_t &lhs, + const amd_dbgapi_register_id_t &rhs) const + { + return std::equal_to () (lhs.handle, rhs.handle); + } +}; + +/* AMDGPU architecture specific information. */ +struct amdgpu_gdbarch_tdep : gdbarch_tdep_base +{ + /* This architecture's breakpoint instruction. */ + gdb::unique_xmalloc_ptr breakpoint_instruction_bytes; + size_t breakpoint_instruction_size; + + /* A vector of register_ids indexed by their equivalent gdb regnum. */ + std::vector register_ids; + + /* A vector of register_properties indexed by their equivalent gdb regnum. */ + std::vector register_properties; + + /* A vector of register names indexed by their equivalent gdb regnum. */ + std::vector register_names; + + /* A vector of register types created from the amd-dbgapi type strings, + indexed by their equivalent gdb regnum. These are computed lazily by + amdgpu_register_type, entries that haven't been computed yet are + nullptr. */ + std::vector register_types; + + /* A vector of GDB register numbers indexed by DWARF register number. + + Unused DWARF register numbers map to value -1. */ + std::vector dwarf_regnum_to_gdb_regnum; + + /* A map of gdb regnums keyed by they equivalent register_id. */ + std::unordered_map + regnum_map; + + /* A map of register_class_ids keyed by their name. */ + std::unordered_map + register_class_map; +}; + +/* Return true if GDBARCH is of an AMDGPU architecture. */ +bool is_amdgpu_arch (struct gdbarch *gdbarch); + +/* Return the amdgpu-specific data associated to ARCH. */ + +amdgpu_gdbarch_tdep *get_amdgpu_gdbarch_tdep (gdbarch *arch); + +#endif /* AMDGPU_TDEP_H */ diff --git a/gdb/configure b/gdb/configure index 1b07e1e798c..2f327c8e236 100755 --- a/gdb/configure +++ b/gdb/configure @@ -774,11 +774,10 @@ PKGVERSION CODESIGN_CERT DEBUGINFOD_LIBS DEBUGINFOD_CFLAGS -PKG_CONFIG_LIBDIR -PKG_CONFIG_PATH -PKG_CONFIG HAVE_NATIVE_GCORE_TARGET TARGET_OBS +AMD_DBGAPI_LIBS +AMD_DBGAPI_CFLAGS ENABLE_BFD_64_BIT_FALSE ENABLE_BFD_64_BIT_TRUE subdirs @@ -800,6 +799,9 @@ INCINTL LIBINTL_DEP LIBINTL USE_NLS +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG CCDEPMODE DEPDIR am__leading_dot @@ -913,6 +915,7 @@ with_auto_load_dir with_auto_load_safe_path enable_targets enable_64_bit_bfd +with_amd_dbgapi enable_gdbmi enable_tui enable_gdbtk @@ -984,11 +987,13 @@ CXXFLAGS CCC CPP CXXCPP -MAKEINFO -MAKEINFOFLAGS PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR +MAKEINFO +MAKEINFOFLAGS +AMD_DBGAPI_CFLAGS +AMD_DBGAPI_LIBS DEBUGINFOD_CFLAGS DEBUGINFOD_LIBS YACC @@ -1675,6 +1680,7 @@ Optional Packages: [--with-auto-load-dir] --without-auto-load-safe-path do not restrict auto-loaded files locations + --with-amd-dbgapi support for the amd-dbgapi target (yes / no / auto) --with-debuginfod Enable debuginfo lookups with debuginfod (auto/yes/no) --with-libunwind-ia64 use libunwind frame unwinding for ia64 targets @@ -1748,14 +1754,18 @@ Some influential environment variables: CXXFLAGS C++ compiler flags CPP C preprocessor CXXCPP C++ preprocessor - MAKEINFO Parent configure detects if it is of sufficient version. - MAKEINFOFLAGS - Parameters for MAKEINFO. PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path + MAKEINFO Parent configure detects if it is of sufficient version. + MAKEINFOFLAGS + Parameters for MAKEINFO. + AMD_DBGAPI_CFLAGS + C compiler flags for AMD_DBGAPI, overriding pkg-config + AMD_DBGAPI_LIBS + linker flags for AMD_DBGAPI, overriding pkg-config DEBUGINFOD_CFLAGS C compiler flags for DEBUGINFOD, overriding pkg-config DEBUGINFOD_LIBS @@ -11451,7 +11461,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11454 "configure" +#line 11464 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11557,7 +11567,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11560 "configure" +#line 11570 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -17537,6 +17547,130 @@ else CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type fi +# Since the first call to PKG_CHECK_MODULES may not happen (is guarded by +# a condition), we must call PKG_PROG_PKG_CONFIG explicitly to probe for +# pkg-config. + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi + CONFIG_OBS= CONFIG_DEPS= @@ -17997,6 +18131,157 @@ if test x${all_targets} = xtrue; then fi fi +# AMD debugger API support. + + +# Check whether --with-amd-dbgapi was given. +if test "${with_amd_dbgapi+set}" = set; then : + withval=$with_amd_dbgapi; + case $withval in + yes | no | auto) + ;; + *) + as_fn_error $? "bad value $withval for --with-amd-dbgapi" "$LINENO" 5 + ;; + esac + +else + with_amd_dbgapi=auto +fi + + +# If the user passes --without-amd-dbgapi but also explicitly enables a target +# that requires amd-dbgapi, it is an error. +if test "$with_amd_dbgapi" = no -a "$gdb_require_amd_dbgapi" = true; then + as_fn_error $? "an explicitly enabled target requires amd-dbgapi, but amd-dbgapi is explicitly disabled" "$LINENO" 5 +fi + +# Look for amd-dbgapi if: +# +# - a target architecture requiring it has explicitly been enabled, or +# - --enable-targets=all was provided and the user did not explicitly disable +# amd-dbgapi support +if test "$gdb_require_amd_dbgapi" = true \ + -o \( "$all_targets" = true -a "$with_amd_dbgapi" != no \); then + # amd-dbgapi version 0.68 is part of ROCm 5.4. There is no guarantee of API + # stability until amd-dbgapi hits 1.0, but for convenience, still check for + # greater or equal that version. It can be handy when testing with a newer + # version of the library. + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for amd-dbgapi >= 0.68.0" >&5 +$as_echo_n "checking for amd-dbgapi >= 0.68.0... " >&6; } + +if test -n "$AMD_DBGAPI_CFLAGS"; then + pkg_cv_AMD_DBGAPI_CFLAGS="$AMD_DBGAPI_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"amd-dbgapi >= 0.68.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "amd-dbgapi >= 0.68.0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_AMD_DBGAPI_CFLAGS=`$PKG_CONFIG --cflags "amd-dbgapi >= 0.68.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$AMD_DBGAPI_LIBS"; then + pkg_cv_AMD_DBGAPI_LIBS="$AMD_DBGAPI_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"amd-dbgapi >= 0.68.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "amd-dbgapi >= 0.68.0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_AMD_DBGAPI_LIBS=`$PKG_CONFIG --libs "amd-dbgapi >= 0.68.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + +if test $pkg_failed = no; then + pkg_save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $pkg_cv_AMD_DBGAPI_LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +else + pkg_failed=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$pkg_save_LDFLAGS +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + AMD_DBGAPI_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "amd-dbgapi >= 0.68.0" 2>&1` + else + AMD_DBGAPI_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "amd-dbgapi >= 0.68.0" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$AMD_DBGAPI_PKG_ERRORS" >&5 + + has_amd_dbgapi=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + has_amd_dbgapi=no +else + AMD_DBGAPI_CFLAGS=$pkg_cv_AMD_DBGAPI_CFLAGS + AMD_DBGAPI_LIBS=$pkg_cv_AMD_DBGAPI_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + has_amd_dbgapi=yes +fi + + if test "$has_amd_dbgapi" = "yes"; then + TARGET_OBS="$TARGET_OBS amd-dbgapi-target.o" + + # If --enable-targets=all was provided, use the list of all files depending + # on amd-dbgapi that is hardcoded in the Makefile. Else, the appropriate + # architecture entry in configure.tgt will have added the files to + # gdb_target_obs. + if test "$all_targets" = true; then + TARGET_OBS="$TARGET_OBS \$(ALL_AMD_DBGAPI_TARGET_OBS)" + fi + elif test "$gdb_require_amd_dbgapi" = true -o "$with_amd_dbgapi" = yes; then + # amd-dbgapi was not found and... + # + # - a target requiring it was explicitly enabled, or + # - the user explicitly wants to enable amd-dbgapi + as_fn_error $? "amd-dbgapi is required, but cannot find an appropriate version: $AMD_DBGAPI_PKG_ERRORS" "$LINENO" 5 + fi +fi + @@ -18099,126 +18384,6 @@ esac # Handle optional debuginfod support - - - - - - -if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. -set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $PKG_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -PKG_CONFIG=$ac_cv_path_PKG_CONFIG -if test -n "$PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 -$as_echo "$PKG_CONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_path_PKG_CONFIG"; then - ac_pt_PKG_CONFIG=$PKG_CONFIG - # Extract the first word of "pkg-config", so it can be a program name with args. -set dummy pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $ac_pt_PKG_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG -if test -n "$ac_pt_PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 -$as_echo "$ac_pt_PKG_CONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_pt_PKG_CONFIG" = x; then - PKG_CONFIG="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - PKG_CONFIG=$ac_pt_PKG_CONFIG - fi -else - PKG_CONFIG="$ac_cv_path_PKG_CONFIG" -fi - -fi -if test -n "$PKG_CONFIG"; then - _pkg_min_version=0.9.0 - { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 -$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } - if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - PKG_CONFIG="" - fi -fi - # Handle optional debuginfod support # Check whether --with-debuginfod was given. diff --git a/gdb/configure.ac b/gdb/configure.ac index cecf4a46bec..86efe23111a 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -61,6 +61,11 @@ AX_CXX_COMPILE_STDCXX(11, , mandatory) ZW_CREATE_DEPDIR ZW_PROG_COMPILER_DEPENDENCIES([CC]) +# Since the first call to PKG_CHECK_MODULES may not happen (is guarded by +# a condition), we must call PKG_PROG_PKG_CONFIG explicitly to probe for +# pkg-config. +PKG_PROG_PKG_CONFIG + dnl List of object files and targets accumulated by configure. CONFIG_OBS= @@ -241,6 +246,53 @@ if test x${all_targets} = xtrue; then fi fi +# AMD debugger API support. + +AC_ARG_WITH([amd-dbgapi], + [AS_HELP_STRING([--with-amd-dbgapi], + [support for the amd-dbgapi target (yes / no / auto)])], + [GDB_CHECK_YES_NO_AUTO_VAL([$withval], [--with-amd-dbgapi])], + [with_amd_dbgapi=auto]) + +# If the user passes --without-amd-dbgapi but also explicitly enables a target +# that requires amd-dbgapi, it is an error. +if test "$with_amd_dbgapi" = no -a "$gdb_require_amd_dbgapi" = true; then + AC_MSG_ERROR([an explicitly enabled target requires amd-dbgapi, but amd-dbgapi is explicitly disabled]) +fi + +# Look for amd-dbgapi if: +# +# - a target architecture requiring it has explicitly been enabled, or +# - --enable-targets=all was provided and the user did not explicitly disable +# amd-dbgapi support +if test "$gdb_require_amd_dbgapi" = true \ + -o \( "$all_targets" = true -a "$with_amd_dbgapi" != no \); then + # amd-dbgapi version 0.68 is part of ROCm 5.4. There is no guarantee of API + # stability until amd-dbgapi hits 1.0, but for convenience, still check for + # greater or equal that version. It can be handy when testing with a newer + # version of the library. + PKG_CHECK_MODULES([AMD_DBGAPI], [amd-dbgapi >= 0.68.0], + [has_amd_dbgapi=yes], [has_amd_dbgapi=no]) + + if test "$has_amd_dbgapi" = "yes"; then + TARGET_OBS="$TARGET_OBS amd-dbgapi-target.o" + + # If --enable-targets=all was provided, use the list of all files depending + # on amd-dbgapi that is hardcoded in the Makefile. Else, the appropriate + # architecture entry in configure.tgt will have added the files to + # gdb_target_obs. + if test "$all_targets" = true; then + TARGET_OBS="$TARGET_OBS \$(ALL_AMD_DBGAPI_TARGET_OBS)" + fi + elif test "$gdb_require_amd_dbgapi" = true -o "$with_amd_dbgapi" = yes; then + # amd-dbgapi was not found and... + # + # - a target requiring it was explicitly enabled, or + # - the user explicitly wants to enable amd-dbgapi + AC_MSG_ERROR([amd-dbgapi is required, but cannot find an appropriate version: $AMD_DBGAPI_PKG_ERRORS]) + fi +fi + AC_SUBST(TARGET_OBS) AC_SUBST(HAVE_NATIVE_GCORE_TARGET) diff --git a/gdb/configure.tgt b/gdb/configure.tgt index e84e222ba0d..d5b7dd1e7d7 100644 --- a/gdb/configure.tgt +++ b/gdb/configure.tgt @@ -2,13 +2,20 @@ # invoked from the autoconf generated configure script. # This file sets the following shell variables: -# gdb_target_obs target-specific object files to use -# gdb_sim simulator library for target -# gdb_osabi default OS ABI to use with target -# gdb_have_gcore set to "true"/"false" if this target can run gcore +# gdb_target_obs target-specific object files to use +# gdb_sim simulator library for target +# gdb_osabi default OS ABI to use with target +# gdb_have_gcore set to "true"/"false" if this target can run gcore +# gdb_require_amd_dbgapi set to "true" if this target requires the amd-dbgapi +# target # NOTE: Every file added to a gdb_target_obs variable for any target here -# must also be added to either ALL_TARGET_OBS or ALL_64_TARGET_OBS +# must also be added to either: +# +# - ALL_TARGET_OBS +# - ALL_64_TARGET_OBS +# - ALL_AMD_DBGAPI_TARGET_OBS +# # in Makefile.in! case $targ in @@ -161,6 +168,12 @@ alpha*-*-openbsd*) alpha-netbsd-tdep.o alpha-obsd-tdep.o netbsd-tdep.o" ;; +amdgcn*-*-*) + # Target: AMDGPU + gdb_require_amd_dbgapi=true + gdb_target_obs="amdgpu-tdep.o solib-rocm.o" + ;; + am33_2.0*-*-linux*) # Target: Matsushita mn10300 (AM33) running Linux gdb_target_obs="mn10300-tdep.o mn10300-linux-tdep.o linux-tdep.o \ diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 5b566669975..820de7d5119 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -7021,6 +7021,8 @@ signal happened. @value{GDBN} alerts you to the context switch with a message such as @samp{[Switching to Thread @var{n}]} to identify the thread. +@node set scheduler-locking + On some OSes, you can modify @value{GDBN}'s default behavior by locking the OS scheduler to allow only a single thread to run. @@ -25822,6 +25824,7 @@ all uses of @value{GDBN} with the architecture, both native and cross. * Nios II:: * Sparc64:: * S12Z:: +* AMD GPU:: @acronym{AMD GPU} architectures @end menu @node AArch64 @@ -26310,6 +26313,721 @@ This command displays the current value of the microprocessor's BDCCSR register. @end table +@node AMD GPU +@subsection @acronym{AMD GPU} +@cindex @acronym{AMD GPU} support + +@value{GDBN} supports commercially available @acronym{AMD GPU} +devices when the @url{https://docs.amd.com/, @acronym{AMD ROCm}} +platform is installed. + +@subsubsection @acronym{AMD GPU} Architectures + +The following @acronym{AMD GPU} architectures are supported: + +@table @emph + +@item @samp{gfx900} +AMD Vega 10 devices, displayed as @samp{vega10} by @value{GDBN}. + +@item @samp{gfx906} +AMD Vega 7nm devices, displayed as @samp{vega20} by @value{GDBN}. + +@item @samp{gfx908} +AMD Instinct@registeredsymbol{} MI100 accelerator devices, displayed as +@samp{arcturus} by @value{GDBN}. + +@item @samp{gfx90a} +Aldebaran devices, displayed as @samp{aldebaran} by @value{GDBN}. + +@item @samp{gfx1010} +Navi10 devices, displayed as @samp{navi10} by @value{GDBN}. + +@item @samp{gfx1011} +Navi12 devices, displayed as @samp{navi12} by @value{GDBN}. + +@item @samp{gfx1012} +Navi14 devices, displayed as @samp{navi14} by @value{GDBN}. + +@item @samp{gfx1030} +Sienna Cichlid devices, displayed as @samp{sienna_cichlid} by @value{GDBN}. + +@item @samp{gfx1031} +Navy Flounder devices, displayed as @samp{navy_flounder} by @value{GDBN}. + +@item @samp{gfx1032} +Dimgrey Cavefish devices, displayed as @samp{dimgrey_cavefish} by +@value{GDBN}. + +@end table + +@subsubsection @acronym{AMD ROCm} Source Languages + +@value{GDBN} supports the following source languages: + +@table @emph + +@item HIP +The +@url{https://github.com/ROCm-Developer-Tools/HIP/blob/master/docs/markdown/hip_kernel_language.md, +HIP Programming Language} is supported. + +When compiling, the @w{@option{-g}} option should be used to produce +debugging information suitable for use by @value{GDBN}. The +@w{@option{--offload-arch}} option is used to specify the @acronym{AMD +GPU} chips that the executable is required to support. For example, +to compile a HIP program that can utilize ``Vega 10'' and ``Vega 7nm'' +@acronym{AMD GPU} devices, with no optimization: + +@smallexample +hipcc -O0 -g --offload-arch=gfx900 --offload-arch=gfx906 bit_extract.cpp -o bit_extract +@end smallexample + +@item Assembly Code +Assembly code kernels are supported. + +@item Other Languages +Other languages, including OpenCL and Fortran, are currently supported +as the minimal pseudo-language, provided they are compiled specifying +at least the @acronym{AMD GPU} Code Object V3 and DWARF 4 formats. +@xref{Unsupported Languages}. + +@end table + +@subsubsection @acronym{AMD GPU} Device Driver and @acronym{AMD ROCm} Runtime + +@value{GDBN} requires a compatible @acronym{AMD GPU} device driver to +be installed. A warning message is displayed if either the device +driver version or the version of the debug support it implements is +unsupported. For example, + +@smallexample +amd-dbgapi: warning: AMD GPU driver's version 1.6 not supported (version 2.x where x >= 1 required) +amd-dbgapi: warning: AMD GPU driver's debug support version 9.0 not supported (version 10.x where x >= 1) required +@end smallexample + +@value{GDBN} will continue to function except no @acronym{AMD GPU} +debugging will be possible. + +@value{GDBN} requires each agent to have compatible firmware installed +by the device driver. A warning message is displayed if unsupported +firmware is detected. For example, + +@smallexample +amd-dbgapi: warning: AMD GPU gpu_id 17619's firmware version 458 not supported (version >= 555 required) +@end smallexample + +@value{GDBN} will continue to function except no @acronym{AMD GPU} +debugging will be possible on the agent. + +@value{GDBN} requires a compatible @acronym{AMD ROCm} runtime to be +loaded in order to detect @acronym{AMD GPU} code objects and +wavefronts. A warning message is displayed if an unsupported +@acronym{AMD ROCm} runtime is detected, or there is an error or +restriction that prevents debugging. For example, + +@smallexample +amd_dbgapi: warning: AMD GPU runtime's r_debug::r_version 5 not supported (r_debug::r_version >= 6 required) +@end smallexample + +@value{GDBN} will continue to function except no @acronym{AMD GPU} +debugging will be possible. + +@subsubsection @acronym{AMD GPU} Wavefronts + +An @acronym{AMD GPU} wavefront is represented in @value{GDBN} as a +thread. + +An @acronym{AMD GPU} wavefront can enter the halt state by: + +@itemize @bullet{} + +@item +Executing a @code{S_SETHALT 1} instruction. + +@item +Using the @samp{set $status} command to change the bit in the +@acronym{AMD GPU} wavefront's register that controls the halt state. + +@item +Delivering a signal to the wavefront (@pxref{AMD GPU Signals, , +@acronym{AMD GPU} Signals}). + +@end itemize + +When a wavefront is in the halt state, it executes no further +instructions. In addition, a wavefront that is associated with a +queue that is in the queue error state (@pxref{AMD GPU Signals, , +@acronym{AMD GPU} Signals}) is inhibited from executing further +instructions. Continuing such wavefronts will not hit any breakpoints +nor report completion of a single step command. If necessary, +@samp{Ctrl-C} can be used to cancel the command. + +Note that some @acronym{AMD GPU} architectures may have restrictions +on providing information about @acronym{AMD GPU} wavefronts created +when @value{GDBN} is not attached (@pxref{AMD GPU Attaching +Restrictions, , @acronym{AMD GPU} Attaching Restrictions}). + +When scheduler-locking is in effect (@pxref{set scheduler-locking}), +new wavefronts created by the resumed thread (either CPU thread or GPU +wavefront) are held in the halt state. + +@subsubsection @acronym{AMD GPU} Registers + +@acronym{AMD GPU} supports the following @var{reggroup} values for the +@samp{info registers @var{reggroup} @dots{}} command: + +@itemize @bullet + +@item +general + +@item +vector + +@item +scalar + +@item +system + +@end itemize + +The number of scalar and vector registers is configured when a +wavefront is created. Only allocated registers are displayed. + +Scalar registers are reported as 32-bit signed integer values. + +Vector registers are reported as a wavefront size vector of signed +32-bit values. + +The @code{pc} is reported as a function pointer value. + +The @code{exec} register is reported as a wavefront size-bit unsigned +integer value. + +The @code{vcc} and @code{xnack_mask} pseudo registers are reported as +a wavefront size-bit unsigned integer value. + +The @code{flat_scratch} pseudo register is reported as a 64-bit +unsigned integer value. + +The @code{mode}, @code{status}, and @code{trapsts} registers are +reported as flag values. For example, + +@smallexample +(gdb) p $mode +$1 = [ FP_ROUND.32=NEAREST_EVEN FP_ROUND.64_16=NEAREST_EVEN FP_DENORM.32=FLUSH_NONE FP_DENORM.64_16=FLUSH_NONE DX10_CLAMP IEEE CSP=0 ] +(gdb) p $status +$2 = [ SPI_PRIO=0 USER_PRIO=0 TRAP_EN VCCZ VALID ] +(gdb) p $trapsts +$3 = [ EXCP_CYCLE=0 DP_RATE=FULL ] +@end smallexample + +Use the @samp{ptype} command to see the type of any register. + +@subsubsection @acronym{AMD GPU} Code Objects + +The @samp{info sharedlibrary} command will show the @acronym{AMD GPU} code objects +together with the CPU code objects. For example: + +@smallexample +(@value{GDBP}) info sharedlibrary +From To Syms Read Shared Object Library +0x00007fd120664ac0 0x00007fd120682790 Yes (*) /lib64/ld-linux-x86-64.so.2 +... +0x00007fd0125d8ec0 0x00007fd015f21630 Yes (*) /opt/rocm-3.5.0/hip/lib/../../lib/libamd_comgr.so +0x00007fd11d74e870 0x00007fd11d75a868 Yes (*) /lib/x86_64-linux-gnu/libtinfo.so.5 +0x00007fd11d001000 0x00007fd11d00173c Yes file:///home/rocm/examples/bit_extract#offset=6477&size=10832 +0x00007fd11d008000 0x00007fd11d00adc0 Yes (*) memory://95557/mem#offset=0x7fd0083e7f60&size=41416 +(*): Shared library is missing debugging information. +(@value{GDBP}) +@end smallexample + +The code object path for @acronym{AMD GPU} code objects is shown as a +@acronym{URI, Universal Location Identifier} with a syntax defined by +the following BNF syntax: + +@smallexample +code_object_uri ::== file_uri | memory_uri +file_uri ::== "file://" file_path [ range_specifier ] +memory_uri ::== "memory://" process_id range_specifier +range_specifier ::== [ "#" | "?" ] "offset=" number "&" "size=" number +file_path ::== URI_ENCODED_OS_FILE_PATH +process_id ::== DECIMAL_NUMBER +number ::== HEX_NUMBER | DECIMAL_NUMBER | OCTAL_NUMBER +@end smallexample + +@noindent +Where: + +@table @var + +@item number +A C integral literal where hexadecimal values are prefixed by +@samp{0x} or @samp{0X}, and octal values by @samp{0}. + +@item file_path +The file's path specified as a URI encoded UTF-8 string. In URI +encoding, every character that is not: + +@itemize +@item In the @samp{a-z}, @samp{A-Z}, @samp{0-9} ranges +@item @samp{/}, @samp{_}, @samp{.}, @samp{~} or @samp{-} +@end itemize + +is encoded as two uppercase hexadecimal digits proceeded by @samp{%}. +Directories in the path are separated by @samp{/}. + +@item offset +A 0-based byte offset to the start of the code object. For a file +URI, it is from the start of the file specified by the +@var{file_path}, and if omitted defaults to 0. For a memory URI, it is +the memory address and is required. + +@item size +The number of bytes in the code object. For a file URI, if omitted it +defaults to the size of the file. It is required for a memory URI. + +@item process_id +The identity of the process owning the memory. For Linux it is the C +unsigned integral decimal literal for the process @var{pid}. + +@end table + +@acronym{AMD GPU} code objects are loaded into each @acronym{AMD GPU} +device separately. The @samp{info sharedlibrary} command will +therefore show the same code object loaded multiple times. As a +consequence, setting a breakpoint in @acronym{AMD GPU} code will +result in multiple breakpoint locations if there are multiple +@acronym{AMD GPU} devices. + +If the source language runtime defers loading code objects until +kernels are launched, then setting breakpoints may result in pending +breakpoints that will be resolved when the code object is finally loaded. + +@subsubsection @acronym{AMD GPU} Entity Target Identifiers and Convenience Variables + +The @acronym{AMD GPU} entities have the following target identifier formats: + +@table @var + +@item Thread Target ID +The @acronym{AMD GPU} thread target identifier (@var{systag}) string has the +following format: + +@smallexample +AMDGPU Wave @var{agent-id}:@var{queue-id}:@var{dispatch-id}:@var{wave-id} (@var{work-group-x},@var{work-group-y},@var{work-group-z})/@var{work-group-thread-index} +@end smallexample + +It is used in the @samp{Target ID} column of the @samp{info threads} command. + +@end table + +@anchor{AMD GPU Signals} +@subsubsection @acronym{AMD GPU} Signals + +@acronym{AMD GPU} wavefronts can raise the following signals when +executing instructions: + +@table @code + +@item SIGILL +Execution of an illegal instruction. + +@item SIGTRAP +Execution of a @code{S_TRAP} instruction other than: + +@itemize @bullet{} + +@item +@code{S_TRAP 1} which is used by @value{GDBN} to insert breakpoints. + +@item +@code{S_TRAP 2} which raises @code{SIGABRT}. + +@end itemize + +Note that @code{S_TRAP 3} only raises a signal when @value{GDBN} is +attached to the inferior. Otherwise, it is treated as a no-operation. +The compiler generates @code{S_TRAP 3} for the @code{llvm.debugtrap} +intrinsic. + +@item SIGABRT +Execution of a @code{S_TRAP 2} instruction. The compiler generates +@code{S_TRAP 2} for the @code{llvm.trap} intrinsic which is used for +assertions. + +@item SIGFPE +Execution of a floating point or integer instruction detects a +condition that is enabled to raise a signal. The conditions include: + +@itemize @bullet{} + +@item +Floating point operation is invalid. + +@item +Floating point operation had subnormal input that was rounded to zero. + +@item +Floating point operation performed a division by zero. + +@item +Floating point operation produced an overflow result. The result was +rounded to infinity. + +@item +Floating point operation produced an underflow result. A subnormal +result was rounded to zero. + +@item +Floating point operation produced an inexact result. + +@item +Integer operation performed a division by zero. + +@end itemize + +By default, these conditions are not enabled to raise signals. The +@samp{set $mode} command can be used to change the @acronym{AMD GPU} +wavefront's register that has bits controlling which conditions are +enabled to raise signals. The @samp{print $trapsts} command can be +used to inspect which conditions have been detected even if they are +not enabled to raise a signal. + +@item SIGBUS +Execution of an instruction that accessed global memory using an +address that is outside the virtual address range. + +@item SIGSEGV +Execution of an instruction that accessed a global memory page that is +either not mapped or accessed with incompatible permissions. + +@end table + +If a single instruction raises more than one signal, they will be +reported one at a time each time the wavefront is continued. + +If any of these signals are delivered to the wavefront, it will cause +the wavefront to enter the halt state and cause the @acronym{AMD ROCm} +runtime to put the associated queue into the queue error state. All +wavefronts associated with a queue that is in the queue error state +are inhibited from executing further instructions even if they are not +in the halt state. In addition, when the @acronym{AMD ROCm} runtime +puts a queue into the queue error state it may invoke an application +registered callback that could either abort the application or delete +the queue which will delete any wavefronts associated with the queue. + +The @value{GDBN} signal-related commands (@pxref{Signals}) can be used +to control when a signal is delivered to the inferior, what signal is +delivered to the inferior, and even if a signal should not be +delivered to the inferior. + +If the @samp{signal} or @samp{queue-signal} commands are used to +deliver a signal other than those listed above to an @acronym{AMD GPU} +wavefront, then the following error will be displayed when the +wavefront is resumed: + +@smallexample +Resuming with signal @var{signal} is not supported by this agent. +@end smallexample + +The wavefront will not be resumed and no signal will be delivered. +Use the @samp{signal} or @samp{queue-signal} commands to change the +signal to deliver, or use @samp{signal 0} or @samp{queue-signal 0} to +suppress delivering a signal. + +Note that some @acronym{AMD GPU} architectures may have restrictions +on supressing delivering signals to a wavefront (@pxref{AMD GPU Signal +Restrictions, , @acronym{AMD GPU} Signal Restrictions}). + +@subsubsection @acronym{AMD GPU} Logging + +The @samp{set debug amd-dbgapi-lib log-level @var{level}} command can be used +to enable diagnostic messages from the @samp{amd-dbgapi} library. The +@samp{show debug amd-dbgapi-lib log-level} command displays the current +@samp{amd-dbgapi} library log level. @xref{set debug amd-dbgapi-lib}. + +The @samp{set debug amd-dbgapi} command can be used +to enable diagnostic messages in the @samp{amd-dbgapi} target. The +@samp{show debug amd-dbgapi} command displays the current setting. +@xref{set debug amd-dbgapi}. + +For example, the following will enable information messages and send +the log to a new file: + +@smallexample +(@value{GDBP}) set debug amd-dbgapi-lib log-level info +(@value{GDBP}) set debug amd-dbgapi on +(@value{GDBP}) set logging overwrite +(@value{GDBP}) set logging file log.out +(@value{GDBP}) set logging debugredirect on +(@value{GDBP}) set logging enabled on +@end smallexample + +If you want to print the log to both the console and a file, omit the +@samp{set logging debugredirect on} command. @xref{Logging Output}. + +@subsubsection @acronym{AMD GPU} Restrictions + +@value{GDBN} @acronym{AMD GPU} support is currently a prototype and +has the following restrictions. Future releases aim to address these +restrictions. + +@enumerate + +@item +Only @acronym{AMD GPU} Code Object V3 and above are supported. + +@item +No support yet for @acronym{AMD GPU} core dumps. + +@item +When in non-stop mode, wavefronts may not hit breakpoints inserted +while not stopped, nor see memory updates made while not stopped, +until the wavefront is next stopped. Memory updated by non-stopped +wavefronts may not be visible until the wavefront is next stopped. + +@item +Single-stepping or resuming execution from an illegal instruction may +execute differently in @value{GDBN} than on real hardware. + +@item +On some @acronym{AMD GPU} devices, halting @acronym{AMD GPU} wavefronts +in an inferior can result in preventing other processes from executing +@acronym{AMD GPU} wavefronts. + +@item +Some @acronym{AMD GPU} devices, such as @samp{gfx90a}, can be in use +by multiple processes that are being debugged by @value{GDBN}. For +other devices the following warning message may be displayed. + +@smallexample +amd-dbgapi: warning: At least one agent is busy (debugging may be enabled by another process) +@end smallexample + +@value{GDBN} will continue to function except no @acronym{AMD GPU} +debugging will be possible. + +The Linux @emph{cgroups} facility can be used to limit which +@acronym{AMD GPU} devices are used by a process. In order for a +@value{GDBN} process to access the @acronym{AMD GPU} devices of the +process it is debugging, the @acronym{AMD GPU} devices must be +included in the @value{GDBN} process @emph{cgroup}. + +Therefore, multiple @value{GDBN} processes can each debug a process +provided the @emph{cgroups} specify disjoint sets of @acronym{AMD GPU} +devices. However, a single @value{GDBN} process cannot debug multiple +inferiors that use @acronym{AMD GPU} devices even if those inferiors +have @emph{cgroups} that specify disjoint @acronym{AMD GPU} devices. +This is because the @value{GDBN} process must have all the +@acronym{AMD GPU} devices in its @emph{cgroups} and so will attempt to +enable debugging for all AMD GPU devices for all inferiors it is +debugging. + +It is suggested to use @emph{Docker} rather than @emph{cgroups} +directly to limit the @acronym{AMD GPU} devices visible inside a +container: + +@enumerate + +@item +@samp{/dev/kfd} must be mapped into the container. + +@item +The @samp{/dev/dri/renderD@var{}} and +@samp{/dev/drm/card@var{}} files corresponding to each +AMD GPU device that is to be visible must be mapped into the +container. Note that non-@acronym{AMD GPU} devices may also be +present. + +The @var{render-minor-number} for a device can be obtained by looking +at the @samp{drm_render_minor} field value from: + +@smallexample +cat /sys/class/kfd/kfd/topology/nodes/@var{}/properties +@end smallexample + +@item +Make sure the container user is a member of the @var{render} group for +Ubuntu 20.04 onward and the @var{video} group for all other +distributions. + +@item +Specify the @samp{--cap-add=SYS_PTRACE} and +@samp{--security-opt seccomp=unconfined} options. + +@item +Install the @acronym{AMD ROCm} packages in the container. See +@uref{https://github.com/RadeonOpenCompute/ROCm-docker}. + +@end enumerate + +All processes running in the container will see the same subset of +devices. By having two containers with non-overlapping sets of AMD +GPUs, it is possible to use @value{GDBN} in both containers at the +same time since each @acronym{AMD GPU} device will only have one +@value{GDBN} process accessing it. + +For example: + +@smallexample +docker run -it --rm --cap-add=SYS_PTRACE --security-opt seccomp=unconfined \ + --device=/dev/kfd --device=/dev/drm/card0 --device=/dev/dri/renderD128 \ + --group-add render ubuntu:22.04 /bin/bash +@end smallexample + +@item +The HIP runtime currently performs deferred code object loading by +default. @acronym{AMD GPU} code objects are not loaded until the +first kernel is launched. Before then, all breakpoints have to be set +as pending breakpoints. + +If source line positions are used that only correspond to source lines +in unloaded code objects, then @value{GDBN} may not set pending +breakpoints, and instead set breakpoints in unpredictable places of +the loaded code objects if they contain code from the same file. This +can result in unexpected breakpoint hits being reported. When the +code object containing the source lines is loaded, the incorrect +breakpoints will be removed and replaced by the correct ones. This +problem can be avoided by only setting breakpoints in unloaded code +objects using symbol or function names. + +The @code{HIP_ENABLE_DEFERRED_LOADING} environment variable can be +used to disable deferred code object loading by the HIP runtime. This +ensures all code objects will be loaded when the inferior reaches the +beginning of the @code{main} function. + +For example, + +@smallexample +export HIP_ENABLE_DEFERRED_LOADING=0 +@end smallexample + +@emph{Note:} If deferred code object loading is disabled and the +application performs a @code{fork}, then the program may crash. + +@emph{Note:} Disabling code object loading can result in errors being +reported when executing @value{GDBN} due to open file limitations when +the application contains a large number of embedded device code +objects. With deferred code object loading enabled, only the device +code objects actually invoked are loaded, and so @value{GDBN} opens +fewer files. + +@item +Watchpoints are not yet supported for @acronym{AMD GPU} devices. + +@item When single stepping there can be times when GDB appears to wait +indefinitely for the single step to complete. This can happen if the wave +being single stepped is context switched off the GPU and cannot be restored due +to another process or other hardware limitations. If this happens, ‘Ctrl-C’ can +be used to cancel the single step command, and commands used to switch to +another thread or to allow other threads to complete. + +@item +If no CPU thread is running, then @samp{Ctrl-C} is not able to stop +@acronym{AMD GPU} threads. This can happen for example if you enable +@code{scheduler-locking} after the whole program stopped, and then +resume an @acronym{AMD GPU} thread. For example: + +@smallexample +Thread 6 hit Breakpoint 1, with lanes [0-63], kernel () at test.cpp:38 +38 size_t l = 0; +(@value{GDBP}) info threads + Id Target Id Frame + 1 Thread 0x7ffff6493880 (LWP 2222574) 0x00007ffff6cb989b in sched_yield () at ../sysdeps/unix/syscall-template.S:78 + 2 Thread 0x7ffff6492700 (LWP 2222582) 0x00007ffff6ccb50b in ioctl () at ../sysdeps/unix/syscall-template.S:78 + 4 Thread 0x7ffff5aff700 (LWP 2222584) 0x00007ffff6ccb50b in ioctl () at ../sysdeps/unix/syscall-template.S:78 + 5 Thread 0x7ffff515d700 (LWP 2222585) 0x00007ffff6764d81 in rocr::core::InterruptSignal::WaitRelaxed() from /opt/rocm/lib/libhsa-runtime64.so.1 +* 6 AMDGPU Wave 1:1:1:1 (0,0,0)/0 kernel () at test.cpp:38 +(@value{GDBP}) del 1 +(@value{GDBP}) set scheduler-locking on +(@value{GDBP}) c +Continuing. +^C +@end smallexample + +Above, @value{GDBN} does not respond to @samp{Ctrl-C}. The only way +to unblock the situation is to kill the @value{GDBN} process. + +@item +@acronym{AMD GPU} target does not currently support calling inferior +functions. + +@item +@acronym{AMD GPU} debugging is not supported by @code{gdbserver}. + +@item +No language specific support for Fortran or OpenCL. No OpenMP +language extension support for C, C++, or Fortran. + +@item +@value{GDBN} support for @acronym{AMD GPU} devices is not currently +available under virtualization. + +@anchor{AMD GPU Signal Restrictions} +@item +Suppressing delivering some signals to a wavefront for some +@acronym{AMD GPU} architectures may not prevent the @acronym{AMD ROCm} +runtime putting the associated queue into the queue error state. For +example, suppressing the @code{SIGSEGV} signal may prevent the +wavefront from being put in the halt state, but the @acronym{AMD ROCm} +runtime may still put the associated queue into the queue error state. + +Suppressing delivering some signals, such as @code{SIGSEGV}, for a +wavefront may also suppress the same signal raised by other +@acronym{AMD GPU} hardware such as from @acronym{DMA} or from the +@acronym{packet processor}, preventing the @acronym{AMD ROCm} runtime +being notified. + +@xref{AMD GPU Signals, , @acronym{AMD GPU} Signals}. + +@anchor{AMD GPU Attaching Restrictions} +@item +By default, for some architectures, the @acronym{AMD GPU} device +driver causes all @acronym{AMD GPU} wavefronts created when +@value{GDBN} is not attached to be unable to report the dispatch +associated with the wavefront, or the wavefront's work-group +position. The @samp{info threads} command will display this +missing information with a @samp{?}. + +For example, + +@smallexample +(gdb) info threads + Id Target Id Frame +* 1 Thread 0x7ffff6987840 (LWP 62056) "bit_extract" 0x00007ffff6da489b in sched_yield () at ../sysdeps/unix/syscall-template.S:78 + 2 Thread 0x7ffff6986700 (LWP 62064) "bit_extract" 0x00007ffff6db650b in ioctl () at ../sysdeps/unix/syscall-template.S:78 + 3 Thread 0x7ffff5f7f700 (LWP 62066) "bit_extract" 0x00007ffff6db650b in ioctl () at ../sysdeps/unix/syscall-template.S:78 + 4 Thread 0x7ffff597f700 (LWP 62067) "bit_extract" 0x00007ffff6db650b in ioctl () at ../sysdeps/unix/syscall-template.S:78 + 5 AMDGPU Wave 1:2:?:1 (?,?,?)/? "bit_extract" bit_extract_kernel (C_d=, A_d=, N=) at bit_extract.cpp:41 +@end smallexample + +This does not affect wavefronts created while @value{GDBN} is attached +which are always capable of reporting this information. + +If the @env{HSA_ENABLE_DEBUG} environment variable is set to @samp{1} +when the @acronym{AMD ROCm} runtime is initialized, then this +information will be available for all architectures even for wavefronts +created when @value{GDBN} was not attached. Setting this environment +variable may very marginally increase wavefront launch latency for some +architectures for very short lived wavefronts. + +@item +If an @acronym{AMD GPU} wavefront has the @code{DX10_CLAMP} bit set in +the @code{MODE} register, enabled arithmetic exceptions will not be +reported as @code{SIGFPE} signals. This happens if the +@code{DX10_CLAMP} kernel descriptor field is enabled. + +@xref{AMD GPU Signals, , @acronym{AMD GPU} Signals}. + +@item +@value{GDBN} does not support single root I/O virtualization (SR-IOV) +on any AMD GPU architecture that supports it. That includes +@samp{gfx1030}, @samp{gfx1031}, and @samp{gfx1032}. + +@end enumerate @node Controlling GDB @chapter Controlling @value{GDBN} @@ -27563,6 +28281,46 @@ module. @item show debug aix-thread Show the current state of AIX thread debugging info display. +@cindex AMD GPU debugging info +@anchor{set debug amd-dbgapi-lib} +@item set debug amd-dbgapi-lib +@itemx show debug amd-dbgapi-lib + +The @code{set debug amd-dbgapi-lib log-level @var{level}} command can be used +to enable diagnostic messages from the @samp{amd-dbgapi} library, where +@var{level} can be: + +@table @code + +@item off +no logging is enabled + +@item error +fatal errors are reported + +@item warning +fatal errors and warnings are reported + +@item info +fatal errors, warnings, and info messages are reported + +@item verbose +all messages are reported + +@end table + +The @code{show debug amd-dbgapi-lib log-level} command displays the current +@acronym{amd-dbgapi} library log level. + +@anchor{set debug amd-dbgapi} +@item set debug amd-dbgapi +@itemx show debug amd-dbgapi + +The @samp{set debug amd-dbgapi} command can be used +to enable diagnostic messages in the @samp{amd-dbgapi} target. The +@samp{show debug amd-dbgapi} command displays the current setting. +@xref{set debug amd-dbgapi}. + @item set debug check-physname @cindex physname Check the results of the ``physname'' computation. When reading DWARF diff --git a/gdb/regcache.c b/gdb/regcache.c index 02d6bdc271c..2d926fbed36 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -1915,7 +1915,8 @@ cooked_read_test (struct gdbarch *gdbarch) { auto bfd_arch = gdbarch_bfd_arch_info (gdbarch)->arch; - if (bfd_arch == bfd_arch_frv || bfd_arch == bfd_arch_h8300 + if (bfd_arch == bfd_arch_amdgcn + || bfd_arch == bfd_arch_frv || bfd_arch == bfd_arch_h8300 || bfd_arch == bfd_arch_m32c || bfd_arch == bfd_arch_sh || bfd_arch == bfd_arch_alpha || bfd_arch == bfd_arch_v850 || bfd_arch == bfd_arch_msp430 || bfd_arch == bfd_arch_mep diff --git a/gdb/solib-rocm.c b/gdb/solib-rocm.c new file mode 100644 index 00000000000..2b965acc790 --- /dev/null +++ b/gdb/solib-rocm.c @@ -0,0 +1,679 @@ +/* Handle ROCm Code Objects for GDB, the GNU Debugger. + + Copyright (C) 2019-2022 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 . */ + +#include "defs.h" + +#include "amd-dbgapi-target.h" +#include "amdgpu-tdep.h" +#include "arch-utils.h" +#include "elf-bfd.h" +#include "elf/amdgpu.h" +#include "gdbsupport/fileio.h" +#include "inferior.h" +#include "observable.h" +#include "solib.h" +#include "solib-svr4.h" +#include "solist.h" +#include "symfile.h" + +/* ROCm-specific inferior data. */ + +struct solib_info +{ + /* List of code objects loaded into the inferior. */ + so_list *solib_list; +}; + +/* Per-inferior data key. */ +static const registry::key rocm_solib_data; + +static target_so_ops rocm_solib_ops; + +/* Free the solib linked list. */ + +static void +rocm_free_solib_list (struct solib_info *info) +{ + while (info->solib_list != nullptr) + { + struct so_list *next = info->solib_list->next; + + free_so (info->solib_list); + info->solib_list = next; + } + + info->solib_list = nullptr; +} + + +/* Fetch the solib_info data for INF. */ + +static struct solib_info * +get_solib_info (inferior *inf) +{ + solib_info *info = rocm_solib_data.get (inf); + + if (info == nullptr) + info = rocm_solib_data.emplace (inf); + + return info; +} + +/* Relocate section addresses. */ + +static void +rocm_solib_relocate_section_addresses (struct so_list *so, + struct target_section *sec) +{ + if (!is_amdgpu_arch (gdbarch_from_bfd (so->abfd))) + { + svr4_so_ops.relocate_section_addresses (so, sec); + return; + } + + lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info; + sec->addr = sec->addr + li->l_addr; + sec->endaddr = sec->endaddr + li->l_addr; +} + +static void rocm_update_solib_list (); + +static void +rocm_solib_handle_event () +{ + /* Since we sit on top of svr4_so_ops, we might get called following an event + concerning host libraries. We must therefore forward the call. If the + event was for a ROCm code object, it will be a no-op. On the other hand, + if the event was for host libraries, rocm_update_solib_list will be + essentially be a no-op (it will reload the same code object list as was + previously loaded). */ + svr4_so_ops.handle_event (); + + rocm_update_solib_list (); +} + +/* Make a deep copy of the solib linked list. */ + +static so_list * +rocm_solib_copy_list (const so_list *src) +{ + struct so_list *dst = nullptr; + struct so_list **link = &dst; + + while (src != nullptr) + { + struct so_list *newobj; + + newobj = XNEW (struct so_list); + memcpy (newobj, src, sizeof (struct so_list)); + + lm_info_svr4 *src_li = (lm_info_svr4 *) src->lm_info; + newobj->lm_info = new lm_info_svr4 (*src_li); + + newobj->next = nullptr; + *link = newobj; + link = &newobj->next; + + src = src->next; + } + + return dst; +} + +/* Build a list of `struct so_list' objects describing the shared + objects currently loaded in the inferior. */ + +static struct so_list * +rocm_solib_current_sos () +{ + /* First, retrieve the host-side shared library list. */ + so_list *head = svr4_so_ops.current_sos (); + + /* Then, the device-side shared library list. */ + so_list *list = get_solib_info (current_inferior ())->solib_list; + + if (list == nullptr) + return head; + + list = rocm_solib_copy_list (list); + + if (head == nullptr) + return list; + + /* Append our libraries to the end of the list. */ + so_list *tail; + for (tail = head; tail->next; tail = tail->next) + /* Nothing. */; + tail->next = list; + + return head; +} + +namespace { + +/* Interface to interact with a ROCm code object stream. */ + +struct rocm_code_object_stream +{ + DISABLE_COPY_AND_ASSIGN (rocm_code_object_stream); + + /* Copy SIZE bytes from the underlying objfile storage starting at OFFSET + into the user provided buffer BUF. + + Return the number of bytes actually copied (might be inferior to SIZE if + the end of the stream is reached). */ + virtual file_ptr read (void *buf, file_ptr size, file_ptr offset) = 0; + + /* Retrieve file information in SB. + + Return 0 on success. On failure, set the appropriate bfd error number + (using bfd_set_error) and return -1. */ + int stat (struct stat *sb); + + virtual ~rocm_code_object_stream () = default; + +protected: + rocm_code_object_stream () = default; + + /* Return the size of the object file, or -1 if the size cannot be + determined. + + This is a helper function for stat. */ + virtual LONGEST size () = 0; +}; + +int +rocm_code_object_stream::stat (struct stat *sb) +{ + const LONGEST size = this->size (); + if (size == -1) + return -1; + + memset (sb, '\0', sizeof (struct stat)); + sb->st_size = size; + return 0; +} + +/* Interface to a ROCm object stream which is embedded in an ELF file + accessible to the debugger. */ + +struct rocm_code_object_stream_file final : rocm_code_object_stream +{ + DISABLE_COPY_AND_ASSIGN (rocm_code_object_stream_file); + + rocm_code_object_stream_file (int fd, ULONGEST offset, ULONGEST size); + + file_ptr read (void *buf, file_ptr size, file_ptr offset) override; + + LONGEST size () override; + + ~rocm_code_object_stream_file () override; + +protected: + + /* The target file descriptor for this stream. */ + int m_fd; + + /* The offset of the ELF file image in the target file. */ + ULONGEST m_offset; + + /* The size of the ELF file image. The value 0 means that it was + unspecified in the URI descriptor. */ + ULONGEST m_size; +}; + +rocm_code_object_stream_file::rocm_code_object_stream_file + (int fd, ULONGEST offset, ULONGEST size) + : m_fd (fd), m_offset (offset), m_size (size) +{ +} + +file_ptr +rocm_code_object_stream_file::read (void *buf, file_ptr size, + file_ptr offset) +{ + fileio_error target_errno; + file_ptr nbytes = 0; + while (size > 0) + { + QUIT; + + file_ptr bytes_read + = target_fileio_pread (m_fd, static_cast (buf) + nbytes, + size, m_offset + offset + nbytes, + &target_errno); + + if (bytes_read == 0) + break; + + if (bytes_read < 0) + { + errno = fileio_error_to_host (target_errno); + bfd_set_error (bfd_error_system_call); + return -1; + } + + nbytes += bytes_read; + size -= bytes_read; + } + + return nbytes; +} + +LONGEST +rocm_code_object_stream_file::size () +{ + if (m_size == 0) + { + fileio_error target_errno; + struct stat stat; + if (target_fileio_fstat (m_fd, &stat, &target_errno) < 0) + { + errno = fileio_error_to_host (target_errno); + bfd_set_error (bfd_error_system_call); + return -1; + } + + /* Check that the offset is valid. */ + if (m_offset >= stat.st_size) + { + bfd_set_error (bfd_error_bad_value); + return -1; + } + + m_size = stat.st_size - m_offset; + } + + return m_size; +} + +rocm_code_object_stream_file::~rocm_code_object_stream_file () +{ + fileio_error target_errno; + target_fileio_close (m_fd, &target_errno); +} + +/* Interface to a code object which lives in the inferior's memory. */ + +struct rocm_code_object_stream_memory final : public rocm_code_object_stream +{ + DISABLE_COPY_AND_ASSIGN (rocm_code_object_stream_memory); + + rocm_code_object_stream_memory (gdb::byte_vector buffer); + + file_ptr read (void *buf, file_ptr size, file_ptr offset) override; + +protected: + + /* Snapshot of the original ELF image taken during load. This is done to + support the situation where an inferior uses an in-memory image, and + releases or re-uses this memory before GDB is done using it. */ + gdb::byte_vector m_objfile_image; + + LONGEST size () override + { + return m_objfile_image.size (); + } +}; + +rocm_code_object_stream_memory::rocm_code_object_stream_memory + (gdb::byte_vector buffer) + : m_objfile_image (std::move (buffer)) +{ +} + +file_ptr +rocm_code_object_stream_memory::read (void *buf, file_ptr size, + file_ptr offset) +{ + if (size > m_objfile_image.size () - offset) + size = m_objfile_image.size () - offset; + + memcpy (buf, m_objfile_image.data () + offset, size); + return size; +} + +} /* anonymous namespace */ + +static void * +rocm_bfd_iovec_open (bfd *abfd, void *inferior_void) +{ + gdb::string_view uri (bfd_get_filename (abfd)); + gdb::string_view protocol_delim = "://"; + size_t protocol_end = uri.find (protocol_delim); + std::string protocol = gdb::to_string (uri.substr (0, protocol_end)); + protocol_end += protocol_delim.length (); + + std::transform (protocol.begin (), protocol.end (), protocol.begin (), + [] (unsigned char c) { return std::tolower (c); }); + + gdb::string_view path; + size_t path_end = uri.find_first_of ("#?", protocol_end); + if (path_end != std::string::npos) + path = uri.substr (protocol_end, path_end++ - protocol_end); + else + path = uri.substr (protocol_end); + + /* %-decode the string. */ + std::string decoded_path; + decoded_path.reserve (path.length ()); + for (size_t i = 0; i < path.length (); ++i) + if (path[i] == '%' + && i < path.length () - 2 + && std::isxdigit (path[i + 1]) + && std::isxdigit (path[i + 2])) + { + gdb::string_view hex_digits = path.substr (i + 1, 2); + decoded_path += std::stoi (gdb::to_string (hex_digits), 0, 16); + i += 2; + } + else + decoded_path += path[i]; + + /* Tokenize the query/fragment. */ + std::vector tokens; + size_t pos, last = path_end; + while ((pos = uri.find ('&', last)) != std::string::npos) + { + tokens.emplace_back (uri.substr (last, pos - last)); + last = pos + 1; + } + + if (last != std::string::npos) + tokens.emplace_back (uri.substr (last)); + + /* Create a tag-value map from the tokenized query/fragment. */ + std::unordered_map params; + for (gdb::string_view token : tokens) + { + size_t delim = token.find ('='); + if (delim != std::string::npos) + { + gdb::string_view tag = token.substr (0, delim); + gdb::string_view val = token.substr (delim + 1); + params.emplace (tag, val); + } + } + + try + { + ULONGEST offset = 0; + ULONGEST size = 0; + inferior *inferior = static_cast (inferior_void); + + auto try_strtoulst = [] (gdb::string_view v) + { + errno = 0; + ULONGEST value = strtoulst (v.data (), nullptr, 0); + if (errno != 0) + { + /* The actual message doesn't matter, the exception is caught + below, transformed in a BFD error, and the message is lost. */ + error (_("Failed to parse integer.")); + } + + return value; + }; + + auto offset_it = params.find ("offset"); + if (offset_it != params.end ()) + offset = try_strtoulst (offset_it->second); + + auto size_it = params.find ("size"); + if (size_it != params.end ()) + { + size = try_strtoulst (size_it->second); + if (size == 0) + error (_("Invalid size value")); + } + + if (protocol == "file") + { + fileio_error target_errno; + int fd + = target_fileio_open (static_cast (inferior), + decoded_path.c_str (), FILEIO_O_RDONLY, + false, 0, &target_errno); + + if (fd == -1) + { + errno = fileio_error_to_host (target_errno); + bfd_set_error (bfd_error_system_call); + return nullptr; + } + + return new rocm_code_object_stream_file (fd, offset, size); + } + + if (protocol == "memory") + { + ULONGEST pid = try_strtoulst (path); + if (pid != inferior->pid) + { + warning (_("`%s': code object is from another inferior"), + gdb::to_string (uri).c_str ()); + bfd_set_error (bfd_error_bad_value); + return nullptr; + } + + gdb::byte_vector buffer (size); + if (target_read_memory (offset, buffer.data (), size) != 0) + { + warning (_("Failed to copy the code object from the inferior")); + bfd_set_error (bfd_error_bad_value); + return nullptr; + } + + return new rocm_code_object_stream_memory (std::move (buffer)); + } + + warning (_("`%s': protocol not supported: %s"), + gdb::to_string (uri).c_str (), protocol.c_str ()); + bfd_set_error (bfd_error_bad_value); + return nullptr; + } + catch (const gdb_exception_quit &ex) + { + set_quit_flag (); + bfd_set_error (bfd_error_bad_value); + return nullptr; + } + catch (const gdb_exception &ex) + { + bfd_set_error (bfd_error_bad_value); + return nullptr; + } +} + +static int +rocm_bfd_iovec_close (bfd *nbfd, void *data) +{ + delete static_cast (data); + + return 0; +} + +static file_ptr +rocm_bfd_iovec_pread (bfd *abfd, void *data, void *buf, file_ptr size, + file_ptr offset) +{ + return static_cast (data)->read (buf, size, + offset); +} + +static int +rocm_bfd_iovec_stat (bfd *abfd, void *data, struct stat *sb) +{ + return static_cast (data)->stat (sb); +} + +static gdb_bfd_ref_ptr +rocm_solib_bfd_open (const char *pathname) +{ + /* Handle regular files with SVR4 open. */ + if (strstr (pathname, "://") == nullptr) + return svr4_so_ops.bfd_open (pathname); + + gdb_bfd_ref_ptr abfd + = gdb_bfd_openr_iovec (pathname, "elf64-amdgcn", rocm_bfd_iovec_open, + current_inferior (), rocm_bfd_iovec_pread, + rocm_bfd_iovec_close, rocm_bfd_iovec_stat); + + if (abfd == nullptr) + error (_("Could not open `%s' as an executable file: %s"), pathname, + bfd_errmsg (bfd_get_error ())); + + /* Check bfd format. */ + if (!bfd_check_format (abfd.get (), bfd_object)) + error (_("`%s': not in executable format: %s"), + bfd_get_filename (abfd.get ()), bfd_errmsg (bfd_get_error ())); + + unsigned char osabi = elf_elfheader (abfd)->e_ident[EI_OSABI]; + unsigned char osabiversion = elf_elfheader (abfd)->e_ident[EI_ABIVERSION]; + + /* Check that the code object is using the HSA OS ABI. */ + if (osabi != ELFOSABI_AMDGPU_HSA) + error (_("`%s': ELF file OS ABI is not supported (%d)."), + bfd_get_filename (abfd.get ()), osabi); + + /* We support HSA code objects V3 and greater. */ + if (osabiversion < ELFABIVERSION_AMDGPU_HSA_V3) + error (_("`%s': ELF file HSA OS ABI version is not supported (%d)."), + bfd_get_filename (abfd.get ()), osabiversion); + + return abfd; +} + +static void +rocm_solib_create_inferior_hook (int from_tty) +{ + rocm_free_solib_list (get_solib_info (current_inferior ())); + + svr4_so_ops.solib_create_inferior_hook (from_tty); +} + +static void +rocm_update_solib_list () +{ + inferior *inf = current_inferior (); + + amd_dbgapi_process_id_t process_id = get_amd_dbgapi_process_id (inf); + if (process_id.handle == AMD_DBGAPI_PROCESS_NONE.handle) + return; + + solib_info *info = get_solib_info (inf); + + rocm_free_solib_list (info); + struct so_list **link = &info->solib_list; + + amd_dbgapi_code_object_id_t *code_object_list; + size_t count; + + amd_dbgapi_status_t status + = amd_dbgapi_process_code_object_list (process_id, &count, + &code_object_list, nullptr); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + { + warning (_("amd_dbgapi_process_code_object_list failed (%s)"), + get_status_string (status)); + return; + } + + for (size_t i = 0; i < count; ++i) + { + CORE_ADDR l_addr; + char *uri_bytes; + + status = amd_dbgapi_code_object_get_info + (code_object_list[i], AMD_DBGAPI_CODE_OBJECT_INFO_LOAD_ADDRESS, + sizeof (l_addr), &l_addr); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + continue; + + status = amd_dbgapi_code_object_get_info + (code_object_list[i], AMD_DBGAPI_CODE_OBJECT_INFO_URI_NAME, + sizeof (uri_bytes), &uri_bytes); + if (status != AMD_DBGAPI_STATUS_SUCCESS) + continue; + + struct so_list *so = XCNEW (struct so_list); + lm_info_svr4 *li = new lm_info_svr4; + li->l_addr = l_addr; + so->lm_info = li; + + strncpy (so->so_name, uri_bytes, sizeof (so->so_name)); + so->so_name[sizeof (so->so_name) - 1] = '\0'; + xfree (uri_bytes); + + /* Make so_original_name unique so that code objects with the same URI + but different load addresses are seen by gdb core as different shared + objects. */ + xsnprintf (so->so_original_name, sizeof (so->so_original_name), + "code_object_%ld", code_object_list[i].handle); + + so->next = nullptr; + *link = so; + link = &so->next; + } + + xfree (code_object_list); + + if (rocm_solib_ops.current_sos == NULL) + { + /* Override what we need to. */ + rocm_solib_ops = svr4_so_ops; + rocm_solib_ops.current_sos = rocm_solib_current_sos; + rocm_solib_ops.solib_create_inferior_hook + = rocm_solib_create_inferior_hook; + rocm_solib_ops.bfd_open = rocm_solib_bfd_open; + rocm_solib_ops.relocate_section_addresses + = rocm_solib_relocate_section_addresses; + rocm_solib_ops.handle_event = rocm_solib_handle_event; + + /* Engage the ROCm so_ops. */ + set_gdbarch_so_ops (current_inferior ()->gdbarch, &rocm_solib_ops); + } +} + +static void +rocm_solib_target_inferior_created (inferior *inf) +{ + rocm_free_solib_list (get_solib_info (inf)); + rocm_update_solib_list (); + + /* Force GDB to reload the solibs. */ + current_inferior ()->pspace->clear_solib_cache (); + solib_add (nullptr, 0, auto_solib_add); +} + +/* -Wmissing-prototypes */ +extern initialize_file_ftype _initialize_rocm_solib; + +void +_initialize_rocm_solib () +{ + /* The dependency on the amd-dbgapi exists because solib-rocm's + inferior_created observer needs amd-dbgapi to have attached the process, + which happens in amd_dbgapi_target's inferior_created observer. */ + gdb::observers::inferior_created.attach + (rocm_solib_target_inferior_created, + "solib-rocm", + { &get_amd_dbgapi_target_inferior_created_observer_token () }); +} diff --git a/gdb/testsuite/gdb.rocm/simple.cpp b/gdb/testsuite/gdb.rocm/simple.cpp new file mode 100644 index 00000000000..31dc56a1d8c --- /dev/null +++ b/gdb/testsuite/gdb.rocm/simple.cpp @@ -0,0 +1,48 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2022 Free Software Foundation, Inc. + + 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 . */ + +#include "hip/hip_runtime.h" +#include + +__global__ void +do_an_addition (int a, int b, int *out) +{ + *out = a + b; +} + +int +main () +{ + int *result_ptr, result; + + /* Allocate memory for the device to write the result to. */ + hipError_t error = hipMalloc (&result_ptr, sizeof (int)); + assert (error == hipSuccess); + + /* Run `do_an_addition` on one workgroup containing one work item. */ + do_an_addition<<>> (1, 2, result_ptr); + + /* Copy result from device to host. Note that this acts as a synchronization + point, waiting for the kernel dispatch to complete. */ + error = hipMemcpyDtoH (&result, result_ptr, sizeof (int)); + assert (error == hipSuccess); + + printf ("result is %d\n", result); + assert (result == 3); + + return 0; +} diff --git a/gdb/testsuite/gdb.rocm/simple.exp b/gdb/testsuite/gdb.rocm/simple.exp new file mode 100644 index 00000000000..f84df71414e --- /dev/null +++ b/gdb/testsuite/gdb.rocm/simple.exp @@ -0,0 +1,52 @@ +# Copyright 2022 Free Software Foundation, Inc. + +# 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 . + +# A simple AMD GPU debugging smoke test. Run to a breakpoint in device code, +# then continue until the end of the program. + +load_lib rocm.exp + +standard_testfile .cpp + +if [skip_hipcc_tests] { + verbose "skipping hip test: ${testfile}" + return +} + +if {[build_executable "failed to prepare" $testfile $srcfile {debug hip}]} { + return +} + +proc do_test {} { + clean_restart $::binfile + + with_rocm_gpu_lock { + if ![runto_main] { + return + } + + gdb_test "with breakpoint pending on -- break do_an_addition" \ + "Breakpoint $::decimal \\(do_an_addition\\) pending." + + gdb_test "continue" \ + "Thread $::decimal hit Breakpoint $::decimal, do_an_addition .*" + + gdb_test "continue" \ + "Inferior 1 .* exited normally.*" \ + "continue to end" + } +} + +do_test diff --git a/gdb/testsuite/lib/future.exp b/gdb/testsuite/lib/future.exp index 17736ed360a..b35429c15ff 100644 --- a/gdb/testsuite/lib/future.exp +++ b/gdb/testsuite/lib/future.exp @@ -121,6 +121,19 @@ proc gdb_find_rustc {} { return $rustc } +proc gdb_find_hipcc {} { + global tool_root_dir + if {![is_remote host]} { + set hipcc [lookfor_file $tool_root_dir hipcc] + if {$hipcc == ""} { + set hipcc [lookfor_file /opt/rocm/bin hipcc] + } + } else { + set hipcc "" + } + return $hipcc +} + proc gdb_find_ldd {} { global LDD_FOR_TARGET if [info exists LDD_FOR_TARGET] { @@ -290,6 +303,18 @@ proc gdb_default_target_compile_1 {source destfile type options} { } } + if { $i == "hip" } { + set compiler_type "hip" + if {[board_info $dest exists hipflags]} { + append add_flags " [target_info hipflags]" + } + if {[board_info $dest exists hipcompiler]} { + set compiler [target_info hipcompiler] + } else { + set compiler [find_hipcc] + } + } + if {[regexp "^dest=" $i]} { regsub "^dest=" $i "" tmp if {[board_info $tmp exists name]} { @@ -352,6 +377,7 @@ proc gdb_default_target_compile_1 {source destfile type options} { global GO_FOR_TARGET global GO_LD_FOR_TARGET global RUSTC_FOR_TARGET + global HIPCC_FOR_TARGET if {[info exists GNATMAKE_FOR_TARGET]} { if { $compiler_type == "ada" } { @@ -398,6 +424,12 @@ proc gdb_default_target_compile_1 {source destfile type options} { } } + if {[info exists HIPCC_FOR_TARGET]} { + if {$compiler_type == "hip"} { + set compiler $HIPCC_FOR_TARGET + } + } + if { $type == "executable" && $linker != "" } { set compiler $linker } @@ -687,6 +719,12 @@ if {[info procs find_rustc] == ""} { gdb_note [join [list $note_prefix "Rust" $note_suffix] ""] } +if {[info procs find_hipcc] == ""} { + rename gdb_find_hipcc find_hipcc + set use_gdb_compile(hip) 1 + gdb_note [join [list $note_prefix "HIP" $note_suffix] ""] +} + # If dejagnu's default_target_compile is missing support for any language, # override it. if { [array size use_gdb_compile] != 0 } { diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index e4ce3c30c2f..f51de435d17 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -4847,6 +4847,13 @@ proc gdb_compile {source dest type options} { lappend new_options "early_flags=-fno-stack-protector" } + # hipcc defaults to -O2, so add -O0 to early flags for the hip language. + # If "optimize" is also requested, another -O flag (e.g. -O2) will be added + # to the flags, overriding this -O0. + if {[lsearch -exact $options hip] != -1} { + lappend new_options "early_flags=-O0" + } + # Because we link with libraries using their basename, we may need # (depending on the platform) to set a special rpath value, to allow # the executable to find the libraries it depends on. diff --git a/gdb/testsuite/lib/rocm.exp b/gdb/testsuite/lib/rocm.exp new file mode 100644 index 00000000000..e22f392deb1 --- /dev/null +++ b/gdb/testsuite/lib/rocm.exp @@ -0,0 +1,94 @@ +# Copyright (C) 2019-2022 Free Software Foundation, Inc. +# +# 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 . +# +# Support library for testing ROCm (AMD GPU) GDB features. + +proc skip_hipcc_tests { } { + # Only the native target supports ROCm debugging. E.g., when + # testing against GDBserver, there's no point in running the ROCm + # tests. + if {[target_info gdb_protocol] != ""} { + return 1 + } + return 0 +} + +# The lock file used to ensure that only one GDB has access to the GPU +# at a time. +set gpu_lock_filename $objdir/gpu-parallel.lock + +# Acquire lock file LOCKFILE. Tries forever until the lock file is +# successfully created. + +proc lock_file_acquire {lockfile} { + verbose -log "acquiring lock file: $::subdir/${::gdb_test_file_name}.exp" + while {true} { + if {![catch {open $lockfile {WRONLY CREAT EXCL}} rc]} { + set msg "locked by $::subdir/${::gdb_test_file_name}.exp" + verbose -log "lock file: $msg" + # For debugging, put info in the lockfile about who owns + # it. + puts $rc $msg + flush $rc + return [list $rc $lockfile] + } + after 10 + } +} + +# Release a lock file. + +proc lock_file_release {info} { + verbose -log "releasing lock file: $::subdir/${::gdb_test_file_name}.exp" + + if {![catch {fconfigure [lindex $info 0]}]} { + if {![catch { + close [lindex $info 0] + file delete -force [lindex $info 1] + } rc]} { + return "" + } else { + return -code error "Error releasing lockfile: '$rc'" + } + } else { + error "invalid lock" + } +} + +# Run body under the GPU lock. Also calls gdb_exit before releasing +# the GPU lock. + +proc with_rocm_gpu_lock { body } { + if {[info exists ::GDB_PARALLEL]} { + set lock_rc [lock_file_acquire $::gpu_lock_filename] + } + + set code [catch {uplevel 1 $body} result] + + # In case BODY returned early due to some testcase failing, and + # left GDB running, debugging the GPU. + gdb_exit + + if {[info exists ::GDB_PARALLEL]} { + lock_file_release $lock_rc + } + + if {$code == 1} { + global errorInfo errorCode + return -code $code -errorinfo $errorInfo -errorcode $errorCode $result + } else { + return -code $code $result + } +}