From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id QlWDBrjOSminCwsAWB0awg (envelope-from ) for ; Thu, 12 Jun 2025 08:57:28 -0400 Authentication-Results: simark.ca; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=USKWmxRv; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 075B51E102; Thu, 12 Jun 2025 08:57:28 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-5.5 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_INVALID,DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_SBL_CSS,RCVD_IN_VALIDITY_CERTIFIED,RCVD_IN_VALIDITY_RPBL, RCVD_IN_VALIDITY_SAFE autolearn=ham autolearn_force=no version=4.0.1 Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 9A34A1E089 for ; Thu, 12 Jun 2025 08:57:24 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0F9433866221 for ; Thu, 12 Jun 2025 12:57:24 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0F9433866221 Authentication-Results: sourceware.org; dkim=fail reason="signature verification failed" (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=USKWmxRv Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id C0CA6386620D for ; Thu, 12 Jun 2025 12:56:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C0CA6386620D Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org C0CA6386620D Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1749732977; cv=none; b=fhtJUxGOkk6g/ITJdcbGypaVoLPMGGOp2Mr63NOCzApynNXd/K7k/2wJdeAUU+gQGrCQfqxeEovUs5ZSpRtwlEIH1HGZEjF9+uz8T7xA9h1zzxGHPASdXMSxreAmz7hLhX5j0KrnXw2cP84mxYiWGvBv0STigDDWESu/gfuDMrA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1749732977; c=relaxed/simple; bh=7AmO0w9VstyLlK/oX4aLr4VqL8PZVg55VpA8pibAEvg=; h=DKIM-Signature:Message-ID:Date:MIME-Version:Subject:To:From; b=eC8GIqh7QZPJZuR3+DXKSZV/hlRTTe9Zo+dKyLn/bmqtFWwpChAXlH96Gqg0PjgSCOgNNOEVlfQDptyXNpOvvXjh2Y7obR79mlRTJtu2Kv/w2oqqshmlMYwLcqvX07QsjIuNUD1Ah3qBNPjd3Jh8HfDHwevwaxipk32tId67tls= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C0CA6386620D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1749732977; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EvtK6FUVYiMRAKFQ+YTB3MfosNPjsrH/VQOXFOL7iJI=; b=USKWmxRvuDHZGInNLAn2/rrCFOY8/2x1yZToLHJps9Z2fywR307RIeJ8y7D8N1f1ha2hA/ Mc0SyrOy8DpgsTReJY+5Oegts96gGgtMc6BKfsgOKWNZhfjo1LkZkKwsTSeyYPjo2jGYOF 3JnlF6Hfj18T+wEX5bVUPYdz2SzLajM= Received: from mail-qv1-f72.google.com (mail-qv1-f72.google.com [209.85.219.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-93-AJVsl_0gMRenrGADc3E_gA-1; Thu, 12 Jun 2025 08:56:15 -0400 X-MC-Unique: AJVsl_0gMRenrGADc3E_gA-1 X-Mimecast-MFC-AGG-ID: AJVsl_0gMRenrGADc3E_gA_1749732975 Received: by mail-qv1-f72.google.com with SMTP id 6a1803df08f44-6fad49f42cbso14129766d6.3 for ; Thu, 12 Jun 2025 05:56:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749732974; x=1750337774; h=content-transfer-encoding:in-reply-to:from:content-language :references:to:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=SJsGJzRpLMO1wonUA6jtpXiUV99Fw0niI3dpe6RhpE4=; b=K9cqKqFgxpUs/fO80nhC5SD+HS1BJoIkg9pD8PXQ+IFZUB9f2Mm0HibyZvZ70/yKLG 6qoNeh3z11jNGsPhsDE/YxxCzTxgdYMiYYPLXKt3witvpGTfR5TZtPgdxiM0jo+K9K2n +f73b59e85BSQ289YbggU4uVFFqoTerq/EyZ0y7PdoyaVXUx/8gLFs0DLq2JESZPtOMD FV2oHMODAOHWMoEkgof0Oo835c0fLI2AKkP5RsKXI5Nxw2Nt6Q1K6rPPlabSFyaaMkv/ Ggk6D+2MMc4STHaTZnGH3RhyJk5UjsYv5nmPwDcmxrSi+iBVkIYzLO/otiVSN6MmFg8S JOrw== X-Forwarded-Encrypted: i=1; AJvYcCWAFG8qwHiFaM3zNOvbADsMDZwMKjlXL6RyyMivEVXrQMq9wJkKkAQsuR6KiTLT/bEJGfRSXBPCq75Jig==@sourceware.org X-Gm-Message-State: AOJu0YxWT32gkWaNZ/K6g+ce5p/r87bGCOL1/Tnzx5PgPAK+cGfwMIL1 SIo4qbg/CFdu/1zNj1i0YU5k83K5Ll5AZMfxh7+LPo7GDYHts/jky7qNdJlnrlerbsVc6KM/7Vv EfHe2DEn1yRBs7/NqhTQmH5uY0/r+wEHipxmoVWpXcIkoNbfol6vmfDsyI+rH7pAbf+sRnF8= X-Gm-Gg: ASbGncveAZ7fBD1/D22vpfmmHXLNi0f48tiN/Nd5xYzAbOdK0TuRCP4AuREakLA3ARU /CSoUHCu7dMfQEooGzv09eCHYmqWVCdmuuX75OvHm1QKUTJJ8b/KEWe/KFMC2UwKXek2BpmqoIQ lmfT1nxwOoD1MSEu20B52cTWgPBt2u2gPR4cxF4x4cA7KZMr2/lTlHDwbjp1Lh7ZjLQom/dnoR8 h/uPfcD30cmzS7b7rET0N9jl09ypsGUHeF3uOitomrRAwIHAd+jZyeZTSeRebgDXdK50zXCyrwO O0zIehEV6l98e84QkQFCkjQvarbtfUVCGA== X-Received: by 2002:a05:6214:f01:b0:6fa:c55e:873 with SMTP id 6a1803df08f44-6fb2c37ea7fmr118402496d6.37.1749732972561; Thu, 12 Jun 2025 05:56:12 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFRmz3wzih+oiET3wRire/ZZCrHQmxhDnrafIgd6e6amtyDKEXZzEocOAnd1pVlGj/WAqA6VQ== X-Received: by 2002:a05:6214:f01:b0:6fa:c55e:873 with SMTP id 6a1803df08f44-6fb2c37ea7fmr118400386d6.37.1749732970437; Thu, 12 Jun 2025 05:56:10 -0700 (PDT) Received: from ?IPV6:2804:14d:8084:9a69::1000? ([2804:14d:8084:9a69::1000]) by smtp.gmail.com with ESMTPSA id 6a1803df08f44-6fb35c427a7sm9598466d6.81.2025.06.12.05.56.08 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 12 Jun 2025 05:56:09 -0700 (PDT) Message-ID: Date: Thu, 12 Jun 2025 09:56:06 -0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v2 4/4] gdb/solib: C++ify solib_ops To: Simon Marchi , gdb-patches@sourceware.org References: <20250609194146.137730-1-simon.marchi@efficios.com> <20250609194146.137730-4-simon.marchi@efficios.com> From: Guinevere Larsen In-Reply-To: <20250609194146.137730-4-simon.marchi@efficios.com> X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: n_eWYJfwP2i3m1q3VRzvwjMI7uVyOMn94qhWIbkcnkE_1749732975 X-Mimecast-Originator: redhat.com Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org On 6/9/25 4:40 PM, Simon Marchi wrote: > New in v2: added a precision in the commit message about some change in > solib-rocm.c, about when / how rocm_solib_ops is set. > > Convert solib_ops into an abstract base class (with abstract methods, > some of them with default implementations) and convert all the existing > solib_ops instances to solib_ops derived classes / implementations. > > Prior to this patch, solib_ops is a structure holding function pointers, > of which there are only a handful of global instances (in the > `solib-*.c` files). When passing an `solib_ops *` around, it's a > pointer to one of these instances. After this patch, there are no more > global solib_ops instances. Instances are created as needed and stored > in struct program_space. These instances could eventually be made to > contain the program space-specific data, which is currently kept in > per-program space registries (I have some pending patches for that). > > Prior to this patch, `gdbarch_so_ops` is a gdbarch method that returns a > pointer to the appropriate solib_ops implementation for the gdbarch. > This is replaced with the `gdbarch_new_solib_ops` method, which returns > a new instance of the appropriate solib_ops implementation for this > gdbarch. This requires introducing some factory functions for the > various solib_ops implementation, to be used as `gdbarch_new_solib_ops` > callbacks. For instance: > > solib_ops_up > new_linux_ilp32_svr4_solib_ops () > { > return std::make_unique (); > } > > The previous code is full of cases of tdep files copying some base > solib_ops implementation, and overriding one or more function pointer > (see ppc_linux_init_abi, for instance). I tried to convert all of this > is a class hierarchy. I like that it's now possible to get a good > static view of all the existing solib_ops variants. The hierarchy looks > like this: > > solib_ops > ├── aix_solib_ops > ├── darwin_solib_ops > ├── dsbt_solib_ops > ├── frv_solib_ops > ├── rocm_solib_ops > ├── svr4_solib_ops > │ ├── ilp32_svr4_solib_ops > │ ├── lp64_svr4_solib_ops > │ ├── linux_ilp32_svr4_solib_ops > │ │ ├── mips_linux_ilp32_svr4_solib_ops > │ │ └── ppc_linux_ilp32_svr4_solib_ops > │ ├── linux_lp64_svr4_solib_ops > │ │ └── mips_linux_lp64_svr4_solib_ops > │ ├── mips_nbsd_ilp32_svr4_solib_ops > │ ├── mips_nbsd_lp64_svr4_solib_ops > │ ├── mips_fbsd_ilp32_svr4_solib_ops > │ └── mips_fbsd_lp64_svr4_solib_ops > └── target_solib_ops > └── windows_solib_ops > > The solib-svr4 code has per-arch specialization to provide a > link_map_offsets, containing the offsets of the interesting fields in > `struct link_map` on that particular architecture. Prior to this patch, > arches would set a callback returning the appropriate link_map_offsets > by calling `set_solib_svr4_fetch_link_map_offsets`, which also happened > to set the gdbarch's so_ops to `&svr_so_ops`. I converted this to an > abstract virtual method of `struct svr4_solib_ops`, meaning that all > classes deriving from svr4_solib_ops must provide a method returning the > appropriate link_map_offsets for the architecture. I renamed > `set_solib_svr4_fetch_link_map_offsets` to `set_solib_svr4_ops`. This > function is still necessary because it also calls > set_gdbarch_iterate_over_objfiles_in_search_order, but if it was not for > that, we could get rid of it. > > There is a little "base class template" hack in mips-linux-tdep.c, > because both mips_linux_ilp32_svr4_solib_ops and > mips_linux_lp64_svr4_solib_ops need to derive from different SVR4 base > classes (linux_ilp32_svr4_solib_ops and linux_lp64_svr4_solib_ops), but > they both want to override the in_dynsym_resolve_code method with the > same implementation. Let me know if there's a more straightforward way > to do this. > > The solib_ops::supports_namespaces method is new: the support for > namespaces was previously predicated by the presence or absence of a > find_solib_ns method. It now needs to be explicit. > > There is a new progspace::release_solib_ops method, which is only needed > for rocm_solib_ops. For the moment, rocm_solib_ops replaces and wraps > the existing svr4_solib_ops instance, in order to combine the results of > the two. The plan is to have a subsequent patch to allow program spaces to have > multiple solib_ops, removing the need that release_solib_ops. > > Speaking of rocm_solib_ops: it previously overrode only a few methods by > copying svr4_solib_ops and overwriting some function pointers. Now, it > needs to implement all the methods that svr4_solib_ops implements, in > order to forward the call. Otherwise, the default solib_ops method woul > be called, hiding the svr4_solib_ops implementation. Again, this can be > removed once we have support for multiple solib_ops in a program_space. > > There is also a small change in how rocm_solib_ops is activated. Prior > to this patch, it's done at the end of rocm_update_solib_list. Since it > overrides the function pointer in the static svr4_solib_ops, and then > overwrites the host gdbarch, so_ops field, it's something that happens > only once. After the patch though, we need to set rocm_solib_ops in all > the program spaces that appear. We do this in > rocm_solib_target_inferior_created and in the new > rocm_solib_target_inferior_execd. After this, I will explore doing a > change where rocm_solib_ops is only set when we detect the ROCm runtime > is loaded. > > Change-Id: I5896b5bcbf8bdb024d67980380feba1ffefaa4c9 > --- Hi! I took a look over the entire series and the code looks good, and many of the changes are very good. I don't really feel like I can properly review this patch though, but I did ran it through aarch64 and ppc64le, and I see no issues, so Tested-By: Guinevere Larsen -- Cheers, Guinevere Larsen She/Her/Hers > gdb/Makefile.in | 3 + > gdb/aarch64-fbsd-tdep.c | 3 +- > gdb/aarch64-linux-tdep.c | 5 +- > gdb/alpha-linux-tdep.c | 5 +- > gdb/alpha-netbsd-tdep.c | 3 +- > gdb/alpha-obsd-tdep.c | 3 +- > gdb/amd-dbgapi-target.c | 18 +- > gdb/amd-dbgapi-target.h | 5 + > gdb/amd64-darwin-tdep.c | 2 +- > gdb/amd64-fbsd-tdep.c | 3 +- > gdb/amd64-gnu-tdep.c | 3 +- > gdb/amd64-linux-tdep.c | 7 +- > gdb/amd64-netbsd-tdep.c | 3 +- > gdb/amd64-obsd-tdep.c | 3 +- > gdb/amd64-sol2-tdep.c | 3 +- > gdb/arc-linux-tdep.c | 4 +- > gdb/arm-fbsd-tdep.c | 3 +- > gdb/arm-linux-tdep.c | 4 +- > gdb/arm-netbsd-tdep.c | 3 +- > gdb/arm-obsd-tdep.c | 3 +- > gdb/configure.tgt | 62 ++++-- > gdb/cris-linux-tdep.c | 5 +- > gdb/csky-linux-tdep.c | 4 +- > gdb/dicos-tdep.c | 2 +- > gdb/frv-tdep.c | 3 +- > gdb/frv-tdep.h | 3 - > gdb/gdbarch-gen.c | 24 +-- > gdb/gdbarch-gen.h | 7 +- > gdb/gdbarch.h | 1 + > gdb/gdbarch_components.py | 12 +- > gdb/hppa-bsd-tdep.c | 3 +- > gdb/hppa-linux-tdep.c | 4 +- > gdb/i386-darwin-tdep.c | 2 +- > gdb/i386-fbsd-tdep.c | 3 +- > gdb/i386-gnu-tdep.c | 3 +- > gdb/i386-linux-tdep.c | 4 +- > gdb/i386-netbsd-tdep.c | 3 +- > gdb/i386-obsd-tdep.c | 3 +- > gdb/i386-sol2-tdep.c | 3 +- > gdb/ia64-linux-tdep.c | 4 +- > gdb/infcmd.c | 2 +- > gdb/infrun.c | 2 +- > gdb/linux-tdep.c | 61 ------ > gdb/linux-tdep.h | 6 +- > gdb/loongarch-linux-tdep.c | 8 +- > gdb/m32r-linux-tdep.c | 4 +- > gdb/m68k-bsd-tdep.c | 3 +- > gdb/m68k-linux-tdep.c | 4 +- > gdb/microblaze-linux-tdep.c | 4 +- > gdb/mips-fbsd-tdep.c | 57 ++++- > gdb/mips-linux-tdep.c | 65 ++++-- > gdb/mips-netbsd-tdep.c | 54 ++++- > gdb/mips64-obsd-tdep.c | 3 +- > gdb/mn10300-linux-tdep.c | 4 +- > gdb/or1k-linux-tdep.c | 4 +- > gdb/ppc-fbsd-tdep.c | 6 +- > gdb/ppc-linux-tdep.c | 46 ++-- > gdb/ppc-netbsd-tdep.c | 3 +- > gdb/ppc-obsd-tdep.c | 3 +- > gdb/progspace.h | 17 +- > gdb/riscv-fbsd-tdep.c | 7 +- > gdb/riscv-linux-tdep.c | 8 +- > gdb/rs6000-aix-tdep.c | 2 +- > gdb/s390-linux-tdep.c | 7 +- > gdb/sh-linux-tdep.c | 4 +- > gdb/sh-netbsd-tdep.c | 3 +- > gdb/solib-aix.c | 67 +++--- > gdb/solib-aix.h | 7 +- > gdb/solib-darwin.c | 65 +++--- > gdb/solib-darwin.h | 6 +- > gdb/solib-dsbt.c | 59 ++--- > gdb/solib-dsbt.h | 6 +- > gdb/solib-frv.c | 63 +++--- > gdb/solib-frv.h | 28 +++ > gdb/solib-rocm.c | 148 +++++++++---- > gdb/solib-svr4-linux.c | 98 +++++++++ > gdb/solib-svr4-linux.h | 47 ++++ > gdb/solib-svr4.c | 415 +++++++++++++++--------------------- > gdb/solib-svr4.h | 126 +++++++++-- > gdb/solib-target.c | 40 ++-- > gdb/solib-target.h | 16 +- > gdb/solib.c | 90 ++++---- > gdb/solib.h | 137 +++++++----- > gdb/sparc-linux-tdep.c | 4 +- > gdb/sparc-netbsd-tdep.c | 3 +- > gdb/sparc-sol2-tdep.c | 3 +- > gdb/sparc64-fbsd-tdep.c | 3 +- > gdb/sparc64-linux-tdep.c | 4 +- > gdb/sparc64-netbsd-tdep.c | 3 +- > gdb/sparc64-obsd-tdep.c | 3 +- > gdb/sparc64-sol2-tdep.c | 3 +- > gdb/tic6x-linux-tdep.c | 2 +- > gdb/tilegx-linux-tdep.c | 7 +- > gdb/vax-netbsd-tdep.c | 3 +- > gdb/windows-tdep.c | 26 ++- > gdb/xtensa-linux-tdep.c | 4 +- > gdb/xtensa-tdep.c | 3 +- > 97 files changed, 1225 insertions(+), 892 deletions(-) > create mode 100644 gdb/solib-frv.h > create mode 100644 gdb/solib-svr4-linux.c > create mode 100644 gdb/solib-svr4-linux.h > > diff --git a/gdb/Makefile.in b/gdb/Makefile.in > index 998203ce1e20..fc0c56564c23 100644 > --- a/gdb/Makefile.in > +++ b/gdb/Makefile.in > @@ -891,6 +891,7 @@ ALL_TARGET_OBS = \ > solib-dsbt.o \ > solib-frv.o \ > solib-svr4.o \ > + solib-svr4-linux.o \ > sparc-linux-tdep.o \ > sparc-netbsd-tdep.o \ > sparc-obsd-tdep.o \ > @@ -1478,7 +1479,9 @@ HFILES_NO_SRCDIR = \ > solib.h \ > solib-aix.h \ > solib-darwin.h \ > + solib-frv.h \ > solib-svr4.h \ > + solib-svr4-linux.h \ > solib-target.h \ > source.h \ > source-cache.h \ > diff --git a/gdb/aarch64-fbsd-tdep.c b/gdb/aarch64-fbsd-tdep.c > index 07fa38a37285..7227456b7a6f 100644 > --- a/gdb/aarch64-fbsd-tdep.c > +++ b/gdb/aarch64-fbsd-tdep.c > @@ -239,8 +239,7 @@ aarch64_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > /* Generic FreeBSD support. */ > fbsd_init_abi (info, gdbarch); > > - set_solib_svr4_fetch_link_map_offsets (gdbarch, > - svr4_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops); > > tramp_frame_prepend_unwinder (gdbarch, &aarch64_fbsd_sigframe); > > diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c > index a194ac809c23..43b5e2a781f0 100644 > --- a/gdb/aarch64-linux-tdep.c > +++ b/gdb/aarch64-linux-tdep.c > @@ -23,6 +23,7 @@ > #include "extract-store-integer.h" > #include "gdbarch.h" > #include "glibc-tdep.h" > +#include "solib-svr4-linux.h" > #include "linux-tdep.h" > #include "svr4-tls-tdep.h" > #include "aarch64-tdep.h" > @@ -2768,9 +2769,7 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > tdep->lowest_pc = 0x8000; > > linux_init_abi (info, gdbarch, 1); > - > - set_solib_svr4_fetch_link_map_offsets (gdbarch, > - linux_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_lp64_svr4_solib_ops); > > /* Enable TLS support. */ > set_gdbarch_fetch_tls_load_module_address (gdbarch, > diff --git a/gdb/alpha-linux-tdep.c b/gdb/alpha-linux-tdep.c > index 2f6affa6a6d5..0ad731e567ed 100644 > --- a/gdb/alpha-linux-tdep.c > +++ b/gdb/alpha-linux-tdep.c > @@ -17,6 +17,7 @@ > along with this program. If not, see . */ > > #include "frame.h" > +#include "solib-svr4-linux.h" > #include "osabi.h" > #include "solib-svr4.h" > #include "symtab.h" > @@ -369,9 +370,7 @@ alpha_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > tdep->jb_elt_size = 8; > > set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); > - > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, linux_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_lp64_svr4_solib_ops); > > /* Enable TLS support. */ > set_gdbarch_fetch_tls_load_module_address (gdbarch, > diff --git a/gdb/alpha-netbsd-tdep.c b/gdb/alpha-netbsd-tdep.c > index a24003918bba..1c1dc66791e7 100644 > --- a/gdb/alpha-netbsd-tdep.c > +++ b/gdb/alpha-netbsd-tdep.c > @@ -264,8 +264,7 @@ alphanbsd_init_abi (struct gdbarch_info info, > set_gdbarch_software_single_step (gdbarch, alpha_software_single_step); > > /* NetBSD/alpha has SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops); > > tdep->dynamic_sigtramp_offset = alphanbsd_sigtramp_offset; > tdep->pc_in_sigtramp = alphanbsd_pc_in_sigtramp; > diff --git a/gdb/alpha-obsd-tdep.c b/gdb/alpha-obsd-tdep.c > index b5ddbbc61cf4..6d153bb1b413 100644 > --- a/gdb/alpha-obsd-tdep.c > +++ b/gdb/alpha-obsd-tdep.c > @@ -109,8 +109,7 @@ alphaobsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch) > set_gdbarch_software_single_step (gdbarch, alpha_software_single_step); > > /* OpenBSD/alpha has SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops); > set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver); > > tdep->dynamic_sigtramp_offset = alphaobsd_sigtramp_offset; > diff --git a/gdb/amd-dbgapi-target.c b/gdb/amd-dbgapi-target.c > index 819b373da321..d7e9d040a557 100644 > --- a/gdb/amd-dbgapi-target.c > +++ b/gdb/amd-dbgapi-target.c > @@ -104,12 +104,26 @@ amd_dbgapi_lib_debug_module () > > static gdb::observers::token amd_dbgapi_target_inferior_created_observer_token; > > +/* See amd-dbgapi-target.h. */ > + > const gdb::observers::token & > get_amd_dbgapi_target_inferior_created_observer_token () > { > return amd_dbgapi_target_inferior_created_observer_token; > } > > +/* inferior_execd observer token. */ > + > +static gdb::observers::token amd_dbgapi_target_inferior_execd_observer_token; > + > +/* See amd-dbgapi-target.h. */ > + > +const gdb::observers::token & > +get_amd_dbgapi_target_inferior_execd_observer_token () > +{ > + return amd_dbgapi_target_inferior_execd_observer_token; > +} > + > /* A type holding coordinates, etc. info for a given wave. */ > > struct wave_coordinates > @@ -2511,7 +2525,9 @@ _initialize_amd_dbgapi_target () > gdb::observers::inferior_created.attach > (amd_dbgapi_target_inferior_created, > amd_dbgapi_target_inferior_created_observer_token, "amd-dbgapi"); > - gdb::observers::inferior_execd.attach (amd_dbgapi_inferior_execd, "amd-dbgapi"); > + gdb::observers::inferior_execd.attach > + (amd_dbgapi_inferior_execd, amd_dbgapi_target_inferior_execd_observer_token, > + "amd-dbgapi"); > gdb::observers::inferior_forked.attach (amd_dbgapi_inferior_forked, "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"); > diff --git a/gdb/amd-dbgapi-target.h b/gdb/amd-dbgapi-target.h > index dd37ba3b82d2..fe3a50ba33b0 100644 > --- a/gdb/amd-dbgapi-target.h > +++ b/gdb/amd-dbgapi-target.h > @@ -54,6 +54,11 @@ using is_amd_dbgapi_handle > const gdb::observers::token & > get_amd_dbgapi_target_inferior_created_observer_token (); > > +/* Get the token of amd-dbgapi's inferior_execd observer. */ > + > +const gdb::observers::token & > + get_amd_dbgapi_target_inferior_execd_observer_token (); > + > /* Comparison operators for amd-dbgapi handle types. */ > > template diff --git a/gdb/amd64-darwin-tdep.c b/gdb/amd64-darwin-tdep.c > index dde023e0fb08..f26ccc49f2c0 100644 > --- a/gdb/amd64-darwin-tdep.c > +++ b/gdb/amd64-darwin-tdep.c > @@ -113,7 +113,7 @@ x86_darwin_init_abi_64 (struct gdbarch_info info, struct gdbarch *gdbarch) > > tdep->jb_pc_offset = 56; > > - set_gdbarch_so_ops (gdbarch, &darwin_so_ops); > + set_gdbarch_new_solib_ops (gdbarch, new_darwin_solib_ops); > } > > void _initialize_amd64_darwin_tdep (); > diff --git a/gdb/amd64-fbsd-tdep.c b/gdb/amd64-fbsd-tdep.c > index eea01054aca0..b936a70bb54f 100644 > --- a/gdb/amd64-fbsd-tdep.c > +++ b/gdb/amd64-fbsd-tdep.c > @@ -328,8 +328,7 @@ amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > amd64fbsd_core_read_description); > > /* FreeBSD uses SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops); > > set_gdbarch_fetch_tls_load_module_address (gdbarch, > svr4_fetch_objfile_link_map); > diff --git a/gdb/amd64-gnu-tdep.c b/gdb/amd64-gnu-tdep.c > index 602fa8e61160..3dfdf81adf8b 100644 > --- a/gdb/amd64-gnu-tdep.c > +++ b/gdb/amd64-gnu-tdep.c > @@ -218,8 +218,7 @@ amd64_gnu_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > tdep->sc_num_regs = ARRAY_SIZE (amd64_gnu_sc_reg_offset); > > /* Hurd uses SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops); > } > > void _initialize_amd64_gnu_tdep (); > diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c > index e5a2ab9dd526..8a44d233caa3 100644 > --- a/gdb/amd64-linux-tdep.c > +++ b/gdb/amd64-linux-tdep.c > @@ -33,6 +33,7 @@ > #include "amd64-linux-tdep.h" > #include "i386-linux-tdep.h" > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > #include "svr4-tls-tdep.h" > #include "gdbsupport/x86-xstate.h" > #include "inferior.h" > @@ -2130,8 +2131,7 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > tdep->i386_syscall_record = amd64_linux_syscall_record; > > /* GNU/Linux uses SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, linux_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_lp64_svr4_solib_ops); > > /* Register DTrace handlers. */ > set_gdbarch_dtrace_parse_probe_argument (gdbarch, amd64_dtrace_parse_probe_argument); > @@ -2344,8 +2344,7 @@ amd64_x32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > tdep->i386_syscall_record = amd64_x32_linux_syscall_record; > > /* GNU/Linux uses SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, linux_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops); > } > > void _initialize_amd64_linux_tdep (); > diff --git a/gdb/amd64-netbsd-tdep.c b/gdb/amd64-netbsd-tdep.c > index f4464b796118..d1e088003dba 100644 > --- a/gdb/amd64-netbsd-tdep.c > +++ b/gdb/amd64-netbsd-tdep.c > @@ -116,8 +116,7 @@ amd64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > tdep->sc_num_regs = ARRAY_SIZE (amd64nbsd_r_reg_offset); > > /* NetBSD uses SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops); > } > > void _initialize_amd64nbsd_tdep (); > diff --git a/gdb/amd64-obsd-tdep.c b/gdb/amd64-obsd-tdep.c > index 5acc380e7995..bd3d655a5e08 100644 > --- a/gdb/amd64-obsd-tdep.c > +++ b/gdb/amd64-obsd-tdep.c > @@ -443,8 +443,7 @@ amd64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > bsd_uthread_set_collect_uthread (gdbarch, amd64obsd_collect_uthread); > > /* OpenBSD uses SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops); > > /* Unwind kernel trap frames correctly. */ > frame_unwind_prepend_unwinder (gdbarch, &amd64obsd_trapframe_unwind); > diff --git a/gdb/amd64-sol2-tdep.c b/gdb/amd64-sol2-tdep.c > index 84d5f87b814a..7c9fa1965aeb 100644 > --- a/gdb/amd64-sol2-tdep.c > +++ b/gdb/amd64-sol2-tdep.c > @@ -96,8 +96,7 @@ amd64_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > tdep->sc_num_regs = tdep->gregset_num_regs; > > /* Solaris uses SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops); > } > > void _initialize_amd64_sol2_tdep (); > diff --git a/gdb/arc-linux-tdep.c b/gdb/arc-linux-tdep.c > index adf669151d1e..dfa5fc225b07 100644 > --- a/gdb/arc-linux-tdep.c > +++ b/gdb/arc-linux-tdep.c > @@ -19,6 +19,7 @@ > > /* GDB header files. */ > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > #include "objfiles.h" > #include "opcode/arc.h" > #include "osabi.h" > @@ -736,8 +737,7 @@ arc_linux_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch) > > /* GNU/Linux uses SVR4-style shared libraries, with 32-bit ints, longs > and pointers (ILP32). */ > - set_solib_svr4_fetch_link_map_offsets (gdbarch, > - linux_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops); > } > > /* Suppress warning from -Wmissing-prototypes. */ > diff --git a/gdb/arm-fbsd-tdep.c b/gdb/arm-fbsd-tdep.c > index c9a466f91cd4..2e9024136f93 100644 > --- a/gdb/arm-fbsd-tdep.c > +++ b/gdb/arm-fbsd-tdep.c > @@ -300,8 +300,7 @@ arm_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > > tramp_frame_prepend_unwinder (gdbarch, &arm_fbsd_sigframe); > > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops); > > tdep->jb_pc = 24; > tdep->jb_elt_size = 4; > diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c > index 485a5d9cee36..316b3e733cef 100644 > --- a/gdb/arm-linux-tdep.c > +++ b/gdb/arm-linux-tdep.c > @@ -41,6 +41,7 @@ > #include "arm-tdep.h" > #include "arm-linux-tdep.h" > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > #include "glibc-tdep.h" > #include "arch-utils.h" > #include "inferior.h" > @@ -1801,8 +1802,7 @@ arm_linux_init_abi (struct gdbarch_info info, > } > tdep->jb_elt_size = ARM_LINUX_JB_ELEMENT_SIZE; > > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, linux_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops); > > /* Single stepping. */ > set_gdbarch_software_single_step (gdbarch, arm_linux_software_single_step); > diff --git a/gdb/arm-netbsd-tdep.c b/gdb/arm-netbsd-tdep.c > index a16205436a9a..89fcbde10283 100644 > --- a/gdb/arm-netbsd-tdep.c > +++ b/gdb/arm-netbsd-tdep.c > @@ -156,8 +156,7 @@ arm_netbsd_elf_init_abi (struct gdbarch_info info, > tdep->fp_model = ARM_FLOAT_SOFT_VFP; > > /* NetBSD ELF uses SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops); > } > > void _initialize_arm_netbsd_tdep (); > diff --git a/gdb/arm-obsd-tdep.c b/gdb/arm-obsd-tdep.c > index 6fd4c8544719..a2ec923854ca 100644 > --- a/gdb/arm-obsd-tdep.c > +++ b/gdb/arm-obsd-tdep.c > @@ -83,8 +83,7 @@ armobsd_init_abi (struct gdbarch_info info, > tramp_frame_prepend_unwinder (gdbarch, &armobsd_sigframe); > > /* OpenBSD/arm uses SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops); > set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver); > > tdep->jb_pc = 24; > diff --git a/gdb/configure.tgt b/gdb/configure.tgt > index e9b306809dc1..255c77e9f8c0 100644 > --- a/gdb/configure.tgt > +++ b/gdb/configure.tgt > @@ -150,14 +150,15 @@ aarch64*-*-linux*) > arch/aarch64-scalable-linux.o \ > arch/arm.o arch/arm-linux.o arch/arm-get-next-pcs.o \ > arm-tdep.o arm-linux-tdep.o \ > - glibc-tdep.o linux-tdep.o solib-svr4.o svr4-tls-tdep.o \ > + glibc-tdep.o linux-tdep.o solib-svr4.o \ > + solib-svr4-linux.o svr4-tls-tdep.o \ > symfile-mem.o linux-record.o" > ;; > > alpha*-*-linux*) > # Target: Little-endian Alpha running Linux > gdb_target_obs="alpha-mdebug-tdep.o alpha-linux-tdep.o \ > - linux-tdep.o solib-svr4.o" > + linux-tdep.o solib-svr4.o solib-svr4-linux.o" > ;; > alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu) > # Target: NetBSD/alpha > @@ -179,7 +180,7 @@ amdgcn*-*-*) > am33_2.0*-*-linux*) > # Target: Matsushita mn10300 (AM33) running Linux > gdb_target_obs="mn10300-tdep.o mn10300-linux-tdep.o linux-tdep.o \ > - solib-svr4.o" > + solib-svr4.o solib-svr4-linux.o" > ;; > > arc*-*-elf32) > @@ -189,7 +190,8 @@ arc*-*-elf32) > > arc*-*-linux*) > # Target: ARC machine running Linux > - gdb_target_obs="arc-linux-tdep.o linux-tdep.o solib-svr4.o" > + gdb_target_obs="arc-linux-tdep.o linux-tdep.o solib-svr4.o \ > + solib-svr4-linux.o" > ;; > > arm*-wince-pe | arm*-*-mingw32ce*) > @@ -199,7 +201,8 @@ arm*-wince-pe | arm*-*-mingw32ce*) > arm*-*-linux*) > # Target: ARM based machine running GNU/Linux > gdb_target_obs="arch/arm-linux.o arm-linux-tdep.o glibc-tdep.o \ > - solib-svr4.o symfile-mem.o linux-tdep.o linux-record.o" > + solib-svr4.o solib-svr4-linux.o symfile-mem.o \ > + linux-tdep.o linux-record.o" > ;; > arm*-*-freebsd*) > # Target: FreeBSD/arm > @@ -239,13 +242,14 @@ bpf-*-*) > > cris*) > # Target: CRIS > - gdb_target_obs="cris-tdep.o cris-linux-tdep.o linux-tdep.o solib-svr4.o" > + gdb_target_obs="cris-tdep.o cris-linux-tdep.o linux-tdep.o \ > + solib-svr4.o solib-svr4-linux.o" > ;; > > csky*-*-linux*) > # Target: CSKY running GNU/Linux > gdb_target_obs="csky-tdep.o csky-linux-tdep.o glibc-tdep.o \ > - linux-tdep.o solib-svr4.o" > + linux-tdep.o solib-svr4.o solib-svr4-linux.o" > ;; > > csky*-*-*) > @@ -270,7 +274,8 @@ h8300-*-*) > hppa*-*-linux*) > # Target: HP PA-RISC running Linux > gdb_target_obs="hppa-linux-tdep.o glibc-tdep.o \ > - linux-tdep.o solib-svr4.o symfile-mem.o" > + linux-tdep.o solib-svr4.o solib-svr4-linux.o \ > + symfile-mem.o" > ;; > hppa*-*-netbsd*) > # Target: NetBSD/hppa > @@ -315,7 +320,7 @@ i[34567]86-*-linux*) > # Target: Intel 386 running GNU/Linux > gdb_target_obs="i386-linux-tdep.o \ > glibc-tdep.o \ > - solib-svr4.o symfile-mem.o \ > + solib-svr4.o solib-svr4-linux.o symfile-mem.o \ > linux-tdep.o linux-record.o \ > arch/i386-linux-tdesc.o \ > arch/x86-linux-tdesc-features.o" > @@ -345,7 +350,7 @@ i[34567]86-*-go32* | i[34567]86-*-msdosdjgpp*) > ia64-*-linux*) > # Target: Intel IA-64 running GNU/Linux > gdb_target_obs="ia64-linux-tdep.o linux-tdep.o \ > - solib-svr4.o symfile-mem.o" > + solib-svr4.o solib-svr4-linux.o symfile-mem.o" > ;; > ia64-*-*vms*) > # Target: Intel IA-64 running OpenVMS > @@ -363,7 +368,8 @@ lm32-*-*) > loongarch*-*-linux*) > # Target: LoongArch running Linux > gdb_target_obs="loongarch-linux-tdep.o glibc-tdep.o \ > - linux-tdep.o solib-svr4.o linux-record.o" > + linux-tdep.o solib-svr4.o solib-svr4-linux.o \ > + linux-record.o" > ;; > > m32c-*-*) > @@ -374,8 +380,8 @@ m32c-*-*) > m32r*-*-linux*) > # Target: Renesas M32R running GNU/Linux > gdb_target_obs="m32r-tdep.o m32r-linux-tdep.o \ > - glibc-tdep.o solib-svr4.o symfile-mem.o \ > - linux-tdep.o" > + glibc-tdep.o solib-svr4.o solib-svr4-linux.o \ > + symfile-mem.o linux-tdep.o" > ;; > m32r*-*-*) > # Target: Renesas m32r processor > @@ -395,7 +401,8 @@ fido-*-elf*) > m68*-*-linux*) > # Target: Motorola m68k with a.out and ELF > gdb_target_obs="m68k-tdep.o m68k-linux-tdep.o solib-svr4.o \ > - linux-tdep.o glibc-tdep.o symfile-mem.o" > + solib-svr4-linux.o linux-tdep.o glibc-tdep.o \ > + symfile-mem.o" > ;; > m68*-*-netbsd* | m68*-*-knetbsd*-gnu) > # Target: NetBSD/m68k > @@ -415,7 +422,7 @@ mep-*-*) > microblaze*-linux-*|microblaze*-*-linux*) > # Target: Xilinx MicroBlaze running Linux > gdb_target_obs="microblaze-tdep.o microblaze-linux-tdep.o solib-svr4.o \ > - symfile-mem.o linux-tdep.o" > + solib-svr4-linux.o symfile-mem.o linux-tdep.o" > ;; > microblaze*-*-*) > # Target: Xilinx MicroBlaze running standalone > @@ -425,7 +432,8 @@ microblaze*-*-*) > mips*-*-linux*) > # Target: Linux/MIPS > gdb_target_obs="mips-tdep.o mips-linux-tdep.o glibc-tdep.o \ > - solib-svr4.o symfile-mem.o linux-tdep.o" > + solib-svr4.o solib-svr4-linux.o symfile-mem.o \ > + linux-tdep.o" > ;; > mips*-*-netbsd* | mips*-*-knetbsd*-gnu) > # Target: MIPS running NetBSD > @@ -469,7 +477,8 @@ nds32*-*-elf) > or1k*-*-linux*) > # Target: OpenCores OpenRISC 1000 32-bit running Linux > gdb_target_obs="or1k-tdep.o or1k-linux-tdep.o solib-svr4.o \ > - symfile-mem.o glibc-tdep.o linux-tdep.o" > + solib-svr4-linux.o symfile-mem.o glibc-tdep.o \ > + linux-tdep.o" > ;; > > or1k-*-* | or1knd-*-*) > @@ -503,7 +512,8 @@ powerpc-*-aix* | rs6000-*-* | powerpc64-*-aix*) > powerpc*-*-linux*) > # Target: PowerPC running Linux > gdb_target_obs="rs6000-tdep.o ppc-linux-tdep.o ppc-sysv-tdep.o \ > - ppc64-tdep.o solib-svr4.o svr4-tls-tdep.o \ > + ppc64-tdep.o solib-svr4.o solib-svr4-linux.o \ > + svr4-tls-tdep.o \ > glibc-tdep.o symfile-mem.o linux-tdep.o \ > ravenscar-thread.o ppc-ravenscar-thread.o \ > linux-record.o \ > @@ -524,6 +534,7 @@ powerpc*-*-*) > s390*-*-linux*) > # Target: S390 running Linux > gdb_target_obs="s390-linux-tdep.o s390-tdep.o solib-svr4.o \ > + solib-svr4-linux.o \ > linux-tdep.o linux-record.o symfile-mem.o \ > svr4-tls-tdep.o" > ;; > @@ -536,7 +547,8 @@ riscv*-*-freebsd*) > riscv*-*-linux*) > # Target: Linux/RISC-V > gdb_target_obs="riscv-linux-tdep.o riscv-canonicalize-syscall-gen.o \ > - glibc-tdep.o linux-tdep.o solib-svr4.o symfile-mem.o \ > + glibc-tdep.o linux-tdep.o solib-svr4.o solib-svr4-linux.o \ > + symfile-mem.o \ > linux-record.o svr4-tls-tdep.o" > ;; > > @@ -558,7 +570,7 @@ rx-*-*) > sh*-*-linux*) > # Target: GNU/Linux Super-H > gdb_target_obs="sh-tdep.o sh-linux-tdep.o \ > - solib-svr4.o symfile-mem.o \ > + solib-svr4.o solib-svr4-linux.o symfile-mem.o \ > glibc-tdep.o linux-tdep.o" > ;; > sh*-*-netbsd* | sh*-*-knetbsd*-gnu) > @@ -577,7 +589,8 @@ sh*) > sparc-*-linux*) > # Target: GNU/Linux SPARC > gdb_target_obs="sparc-tdep.o \ > - sparc-linux-tdep.o solib-svr4.o symfile-mem.o \ > + sparc-linux-tdep.o solib-svr4.o solib-svr4-linux.o \ > + symfile-mem.o \ > linux-tdep.o \ > ravenscar-thread.o sparc-ravenscar-thread.o" > if test "x$have_64_bit_bfd" = "xyes"; then > @@ -590,7 +603,8 @@ sparc64-*-linux*) > # Target: GNU/Linux UltraSPARC > gdb_target_obs="sparc64-tdep.o \ > sparc64-linux-tdep.o sparc-tdep.o \ > - sparc-linux-tdep.o solib-svr4.o linux-tdep.o \ > + sparc-linux-tdep.o solib-svr4.o solib-svr4-linux.o \ > + linux-tdep.o \ > ravenscar-thread.o sparc-ravenscar-thread.o" > ;; > sparc*-*-freebsd* | sparc*-*-kfreebsd*-gnu) > @@ -658,6 +672,7 @@ tic6x-*-*) > tilegx-*-linux*) > # Target: TILE-Gx > gdb_target_obs="tilegx-tdep.o tilegx-linux-tdep.o solib-svr4.o \ > + solib-svr4-linux.o \ > symfile-mem.o glibc-tdep.o linux-tdep.o" > ;; > > @@ -708,7 +723,8 @@ x86_64-*-linux*) > # Target: GNU/Linux x86-64 > gdb_target_obs="amd64-linux-tdep.o ${i386_tobjs} \ > i386-linux-tdep.o glibc-tdep.o svr4-tls-tdep.o \ > - solib-svr4.o symfile-mem.o linux-tdep.o linux-record.o \ > + solib-svr4.o solib-svr4-linux.o symfile-mem.o \ > + linux-tdep.o linux-record.o \ > arch/i386-linux-tdesc.o arch/amd64-linux-tdesc.o \ > arch/x86-linux-tdesc-features.o" > ;; > diff --git a/gdb/cris-linux-tdep.c b/gdb/cris-linux-tdep.c > index b2ac80d371c3..80e4c886fbfb 100644 > --- a/gdb/cris-linux-tdep.c > +++ b/gdb/cris-linux-tdep.c > @@ -23,6 +23,7 @@ > > #include "osabi.h" > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > #include "solib-svr4.h" > #include "symtab.h" > #include "gdbarch.h" > @@ -41,9 +42,7 @@ cris_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > set_gdbarch_fetch_tls_load_module_address (gdbarch, > svr4_fetch_objfile_link_map); > > - set_solib_svr4_fetch_link_map_offsets (gdbarch, > - linux_ilp32_fetch_link_map_offsets); > - > + set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops); > } > > void _initialize_cris_linux_tdep (); > diff --git a/gdb/csky-linux-tdep.c b/gdb/csky-linux-tdep.c > index 2afb35846bda..724542a10665 100644 > --- a/gdb/csky-linux-tdep.c > +++ b/gdb/csky-linux-tdep.c > @@ -22,6 +22,7 @@ > #include "osabi.h" > #include "glibc-tdep.h" > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > #include "gdbarch.h" > #include "solib-svr4.h" > #include "regset.h" > @@ -407,8 +408,7 @@ csky_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > /* Shared library handling. */ > set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); > set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver); > - set_solib_svr4_fetch_link_map_offsets (gdbarch, > - linux_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops); > > /* Enable TLS support. */ > set_gdbarch_fetch_tls_load_module_address (gdbarch, > diff --git a/gdb/dicos-tdep.c b/gdb/dicos-tdep.c > index 4dfac76654e8..fd43d9d859e6 100644 > --- a/gdb/dicos-tdep.c > +++ b/gdb/dicos-tdep.c > @@ -27,7 +27,7 @@ > void > dicos_init_abi (struct gdbarch *gdbarch) > { > - set_gdbarch_so_ops (gdbarch, &solib_target_so_ops); > + set_gdbarch_new_solib_ops (gdbarch, new_target_solib_ops); > > /* Every process, although has its own address space, sees the same > list of shared libraries. There's no "main executable" in DICOS, > diff --git a/gdb/frv-tdep.c b/gdb/frv-tdep.c > index 360887247ebc..9baa9cc24c21 100644 > --- a/gdb/frv-tdep.c > +++ b/gdb/frv-tdep.c > @@ -25,6 +25,7 @@ > #include "frame.h" > #include "frame-unwind.h" > #include "frame-base.h" > +#include "solib-frv.h" > #include "trad-frame.h" > #include "dis-asm.h" > #include "sim-regno.h" > @@ -1554,7 +1555,7 @@ frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) > set_gdbarch_convert_from_func_ptr_addr (gdbarch, > frv_convert_from_func_ptr_addr); > > - set_gdbarch_so_ops (gdbarch, &frv_so_ops); > + set_gdbarch_new_solib_ops (gdbarch, new_frv_solib_ops); > > /* Hook in ABI-specific overrides, if they have been registered. */ > gdbarch_init_osabi (info, gdbarch); > diff --git a/gdb/frv-tdep.h b/gdb/frv-tdep.h > index 07982b40db0f..7b51b428e9c4 100644 > --- a/gdb/frv-tdep.h > +++ b/gdb/frv-tdep.h > @@ -118,7 +118,4 @@ CORE_ADDR frv_fdpic_find_canonical_descriptor (CORE_ADDR entry_point); > needed for TLS support. */ > CORE_ADDR frv_fetch_objfile_link_map (struct objfile *objfile); > > -struct solib_ops; > -extern const solib_ops frv_so_ops; > - > #endif /* GDB_FRV_TDEP_H */ > diff --git a/gdb/gdbarch-gen.c b/gdb/gdbarch-gen.c > index 32d16598940b..d191131d7b24 100644 > --- a/gdb/gdbarch-gen.c > +++ b/gdb/gdbarch-gen.c > @@ -157,7 +157,7 @@ struct gdbarch > gdbarch_single_step_through_delay_ftype *single_step_through_delay = nullptr; > gdbarch_print_insn_ftype *print_insn = default_print_insn; > gdbarch_skip_trampoline_code_ftype *skip_trampoline_code = generic_skip_trampoline_code; > - const solib_ops * so_ops = &solib_target_so_ops; > + gdbarch_new_solib_ops_ftype *new_solib_ops = new_target_solib_ops; > gdbarch_skip_solib_resolver_ftype *skip_solib_resolver = generic_skip_solib_resolver; > gdbarch_in_solib_return_trampoline_ftype *in_solib_return_trampoline = generic_in_solib_return_trampoline; > gdbarch_in_indirect_branch_thunk_ftype *in_indirect_branch_thunk = default_in_indirect_branch_thunk; > @@ -425,7 +425,7 @@ verify_gdbarch (struct gdbarch *gdbarch) > /* Skip verify of single_step_through_delay, has predicate. */ > /* Skip verify of print_insn, invalid_p == 0. */ > /* Skip verify of skip_trampoline_code, invalid_p == 0. */ > - /* Skip verify of so_ops, invalid_p == 0. */ > + /* Skip verify of new_solib_ops, invalid_p == 0. */ > /* Skip verify of skip_solib_resolver, invalid_p == 0. */ > /* Skip verify of in_solib_return_trampoline, invalid_p == 0. */ > /* Skip verify of in_indirect_branch_thunk, invalid_p == 0. */ > @@ -966,8 +966,8 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) > "gdbarch_dump: skip_trampoline_code = <%s>\n", > host_address_to_string (gdbarch->skip_trampoline_code)); > gdb_printf (file, > - "gdbarch_dump: so_ops = %s\n", > - host_address_to_string (gdbarch->so_ops)); > + "gdbarch_dump: new_solib_ops = <%s>\n", > + host_address_to_string (gdbarch->new_solib_ops)); > gdb_printf (file, > "gdbarch_dump: skip_solib_resolver = <%s>\n", > host_address_to_string (gdbarch->skip_solib_resolver)); > @@ -3469,21 +3469,21 @@ set_gdbarch_skip_trampoline_code (struct gdbarch *gdbarch, > gdbarch->skip_trampoline_code = skip_trampoline_code; > } > > -const solib_ops * > -gdbarch_so_ops (struct gdbarch *gdbarch) > +solib_ops_up > +gdbarch_new_solib_ops (struct gdbarch *gdbarch) > { > gdb_assert (gdbarch != NULL); > - /* Skip verify of so_ops, invalid_p == 0. */ > + gdb_assert (gdbarch->new_solib_ops != NULL); > if (gdbarch_debug >= 2) > - gdb_printf (gdb_stdlog, "gdbarch_so_ops called\n"); > - return gdbarch->so_ops; > + gdb_printf (gdb_stdlog, "gdbarch_new_solib_ops called\n"); > + return gdbarch->new_solib_ops (); > } > > void > -set_gdbarch_so_ops (struct gdbarch *gdbarch, > - const solib_ops * so_ops) > +set_gdbarch_new_solib_ops (struct gdbarch *gdbarch, > + gdbarch_new_solib_ops_ftype new_solib_ops) > { > - gdbarch->so_ops = so_ops; > + gdbarch->new_solib_ops = new_solib_ops; > } > > CORE_ADDR > diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h > index 313a8f198fdb..b5a3762f438e 100644 > --- a/gdb/gdbarch-gen.h > +++ b/gdb/gdbarch-gen.h > @@ -818,10 +818,11 @@ typedef CORE_ADDR (gdbarch_skip_trampoline_code_ftype) (const frame_info_ptr &fr > extern CORE_ADDR gdbarch_skip_trampoline_code (struct gdbarch *gdbarch, const frame_info_ptr &frame, CORE_ADDR pc); > extern void set_gdbarch_skip_trampoline_code (struct gdbarch *gdbarch, gdbarch_skip_trampoline_code_ftype *skip_trampoline_code); > > -/* Vtable of solib operations functions. */ > +/* Return a newly-allocated solib_ops object capable of providing the solibs for this architecture. */ > > -extern const solib_ops * gdbarch_so_ops (struct gdbarch *gdbarch); > -extern void set_gdbarch_so_ops (struct gdbarch *gdbarch, const solib_ops * so_ops); > +typedef solib_ops_up (gdbarch_new_solib_ops_ftype) (); > +extern solib_ops_up gdbarch_new_solib_ops (struct gdbarch *gdbarch); > +extern void set_gdbarch_new_solib_ops (struct gdbarch *gdbarch, gdbarch_new_solib_ops_ftype *new_solib_ops); > > /* If in_solib_dynsym_resolve_code() returns true, and SKIP_SOLIB_RESOLVER > evaluates non-zero, this is the address where the debugger will place > diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h > index 9feb2cc24e5b..6accbd2fd5ee 100644 > --- a/gdb/gdbarch.h > +++ b/gdb/gdbarch.h > @@ -30,6 +30,7 @@ > #include "displaced-stepping.h" > #include "gdbsupport/gdb-checked-static-cast.h" > #include "registry.h" > +#include "solib.h" > > struct floatformat; > struct ui_file; > diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py > index ec09d9550889..000729494611 100644 > --- a/gdb/gdbarch_components.py > +++ b/gdb/gdbarch_components.py > @@ -1431,12 +1431,12 @@ Function( > invalid=False, > ) > > -Value( > - comment="Vtable of solib operations functions.", > - type="const solib_ops *", > - name="so_ops", > - predefault="&solib_target_so_ops", > - printer="host_address_to_string (gdbarch->so_ops)", > +Function( > + comment="Return a newly-allocated solib_ops object capable of providing the solibs for this architecture.", > + type="solib_ops_up", > + name="new_solib_ops", > + params=[], > + predefault="new_target_solib_ops", > invalid=False, > ) > > diff --git a/gdb/hppa-bsd-tdep.c b/gdb/hppa-bsd-tdep.c > index db6c92f8aab5..f7269c921b55 100644 > --- a/gdb/hppa-bsd-tdep.c > +++ b/gdb/hppa-bsd-tdep.c > @@ -128,8 +128,7 @@ hppabsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > set_gdbarch_skip_trampoline_code (gdbarch, hppa_skip_trampoline_code); > > /* OpenBSD and NetBSD use SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops); > > /* Hook in the DWARF CFI frame unwinder. */ > dwarf2_frame_set_init_reg (gdbarch, hppabsd_dwarf2_frame_init_reg); > diff --git a/gdb/hppa-linux-tdep.c b/gdb/hppa-linux-tdep.c > index 16cdd4540165..b6a43ffa740c 100644 > --- a/gdb/hppa-linux-tdep.c > +++ b/gdb/hppa-linux-tdep.c > @@ -32,6 +32,7 @@ > #include "regcache.h" > #include "hppa-tdep.h" > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > #include "elf/common.h" > > /* Map DWARF DBX register numbers to GDB register numbers. */ > @@ -499,8 +500,7 @@ hppa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > frame_unwind_append_unwinder (gdbarch, &hppa_linux_sigtramp_frame_unwind); > > /* GNU/Linux uses SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, linux_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops); > > tdep->in_solib_call_trampoline = hppa_in_solib_call_trampoline; > set_gdbarch_skip_trampoline_code (gdbarch, hppa_skip_trampoline_code); > diff --git a/gdb/i386-darwin-tdep.c b/gdb/i386-darwin-tdep.c > index 6180e0293a6e..9a1f39273942 100644 > --- a/gdb/i386-darwin-tdep.c > +++ b/gdb/i386-darwin-tdep.c > @@ -271,7 +271,7 @@ i386_darwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > alignment. */ > set_gdbarch_long_double_bit (gdbarch, 128); > > - set_gdbarch_so_ops (gdbarch, &darwin_so_ops); > + set_gdbarch_new_solib_ops (gdbarch, new_darwin_solib_ops); > } > > static enum gdb_osabi > diff --git a/gdb/i386-fbsd-tdep.c b/gdb/i386-fbsd-tdep.c > index 72237d89cfcc..5840b618e8fd 100644 > --- a/gdb/i386-fbsd-tdep.c > +++ b/gdb/i386-fbsd-tdep.c > @@ -402,8 +402,7 @@ i386fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > i386fbsd_core_read_description); > > /* FreeBSD uses SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops); > > set_gdbarch_fetch_tls_load_module_address (gdbarch, > svr4_fetch_objfile_link_map); > diff --git a/gdb/i386-gnu-tdep.c b/gdb/i386-gnu-tdep.c > index 97fbc697b845..18fb2a6d2098 100644 > --- a/gdb/i386-gnu-tdep.c > +++ b/gdb/i386-gnu-tdep.c > @@ -180,8 +180,7 @@ i386gnu_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > > /* Hurd uses SVR4-style shared libraries. */ > set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops); > > /* Hurd uses the dynamic linker included in the GNU C Library. */ > set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver); > diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c > index 4b05cc6870b5..93b518d93afc 100644 > --- a/gdb/i386-linux-tdep.c > +++ b/gdb/i386-linux-tdep.c > @@ -30,6 +30,7 @@ > #include "i386-tdep.h" > #include "i386-linux-tdep.h" > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > #include "utils.h" > #include "glibc-tdep.h" > #include "solib-svr4.h" > @@ -1461,8 +1462,7 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > > /* GNU/Linux uses SVR4-style shared libraries. */ > set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, linux_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops); > > /* GNU/Linux uses the dynamic linker included in the GNU C Library. */ > set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver); > diff --git a/gdb/i386-netbsd-tdep.c b/gdb/i386-netbsd-tdep.c > index 701ce048b5e8..d9a3e375d621 100644 > --- a/gdb/i386-netbsd-tdep.c > +++ b/gdb/i386-netbsd-tdep.c > @@ -415,8 +415,7 @@ i386nbsdelf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > i386_elf_init_abi (info, gdbarch); > > /* NetBSD ELF uses SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops); > > /* NetBSD ELF uses -fpcc-struct-return by default. */ > tdep->struct_return = pcc_struct_return; > diff --git a/gdb/i386-obsd-tdep.c b/gdb/i386-obsd-tdep.c > index be656688b369..0ea12d82f1b0 100644 > --- a/gdb/i386-obsd-tdep.c > +++ b/gdb/i386-obsd-tdep.c > @@ -441,8 +441,7 @@ i386obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > frame_unwind_prepend_unwinder (gdbarch, &i386obsd_trapframe_unwind); > > /* OpenBSD ELF uses SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops); > } > > void _initialize_i386obsd_tdep (); > diff --git a/gdb/i386-sol2-tdep.c b/gdb/i386-sol2-tdep.c > index e842236718d6..ffc95f41f0ca 100644 > --- a/gdb/i386-sol2-tdep.c > +++ b/gdb/i386-sol2-tdep.c > @@ -86,8 +86,7 @@ i386_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > tdep->sc_num_regs = tdep->gregset_num_regs; > > /* Solaris has SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops); > } > > > diff --git a/gdb/ia64-linux-tdep.c b/gdb/ia64-linux-tdep.c > index c45b2bb26e89..d84848f1c35a 100644 > --- a/gdb/ia64-linux-tdep.c > +++ b/gdb/ia64-linux-tdep.c > @@ -26,6 +26,7 @@ > #include "solib-svr4.h" > #include "symtab.h" > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > #include "regset.h" > > #include > @@ -235,8 +236,7 @@ ia64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > > set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); > > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, linux_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_lp64_svr4_solib_ops); > > /* Enable TLS support. */ > set_gdbarch_fetch_tls_load_module_address (gdbarch, > diff --git a/gdb/infcmd.c b/gdb/infcmd.c > index 1adad5c3eaa3..6c67a918f57a 100644 > --- a/gdb/infcmd.c > +++ b/gdb/infcmd.c > @@ -260,7 +260,7 @@ post_create_inferior (int from_tty, bool set_pspace_solib_ops) > > if (set_pspace_solib_ops) > current_program_space->set_solib_ops > - (*gdbarch_so_ops (current_inferior ()->arch ())); > + (gdbarch_new_solib_ops (current_inferior ()->arch ())); > > if (current_program_space->exec_bfd ()) > { > diff --git a/gdb/infrun.c b/gdb/infrun.c > index 5cdf66d26dcb..5c652045e8ac 100644 > --- a/gdb/infrun.c > +++ b/gdb/infrun.c > @@ -1383,7 +1383,7 @@ follow_exec (ptid_t ptid, const char *exec_file_target) > target_find_description (); > > current_program_space->set_solib_ops > - (*gdbarch_so_ops (following_inferior->arch ())); > + (gdbarch_new_solib_ops (following_inferior->arch ())); > gdb::observers::inferior_execd.notify (execing_inferior, following_inferior); > > breakpoint_re_set (); > diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c > index 1e339b59e2e8..12c05f31d53a 100644 > --- a/gdb/linux-tdep.c > +++ b/gdb/linux-tdep.c > @@ -3118,64 +3118,3 @@ more information about this file, refer to the manpage of proc(5) and core(5).") > &setlist, &showlist); > > } > - > -/* Fetch (and possibly build) an appropriate `link_map_offsets' for > - ILP32/LP64 Linux systems which don't have the r_ldsomap field. */ > - > -link_map_offsets * > -linux_ilp32_fetch_link_map_offsets () > -{ > - static link_map_offsets lmo; > - static link_map_offsets *lmp = nullptr; > - > - if (lmp == nullptr) > - { > - lmp = &lmo; > - > - lmo.r_version_offset = 0; > - lmo.r_version_size = 4; > - lmo.r_map_offset = 4; > - lmo.r_brk_offset = 8; > - lmo.r_ldsomap_offset = -1; > - lmo.r_next_offset = 20; > - > - /* Everything we need is in the first 20 bytes. */ > - lmo.link_map_size = 20; > - lmo.l_addr_offset = 0; > - lmo.l_name_offset = 4; > - lmo.l_ld_offset = 8; > - lmo.l_next_offset = 12; > - lmo.l_prev_offset = 16; > - } > - > - return lmp; > -} > - > -link_map_offsets * > -linux_lp64_fetch_link_map_offsets () > -{ > - static link_map_offsets lmo; > - static link_map_offsets *lmp = nullptr; > - > - if (lmp == nullptr) > - { > - lmp = &lmo; > - > - lmo.r_version_offset = 0; > - lmo.r_version_size = 4; > - lmo.r_map_offset = 8; > - lmo.r_brk_offset = 16; > - lmo.r_ldsomap_offset = -1; > - lmo.r_next_offset = 40; > - > - /* Everything we need is in the first 40 bytes. */ > - lmo.link_map_size = 40; > - lmo.l_addr_offset = 0; > - lmo.l_name_offset = 8; > - lmo.l_ld_offset = 16; > - lmo.l_next_offset = 24; > - lmo.l_prev_offset = 32; > - } > - > - return lmp; > -} > diff --git a/gdb/linux-tdep.h b/gdb/linux-tdep.h > index 7485fc132a63..3d82ea5bbdf3 100644 > --- a/gdb/linux-tdep.h > +++ b/gdb/linux-tdep.h > @@ -22,6 +22,7 @@ > > #include "bfd.h" > #include "displaced-stepping.h" > +#include "solib.h" > > struct inferior; > struct regcache; > @@ -112,9 +113,4 @@ extern CORE_ADDR linux_get_hwcap2 (const std::optional &auxv, > > extern CORE_ADDR linux_get_hwcap2 (); > > -/* Fetch (and possibly build) an appropriate `struct link_map_offsets' > - for ILP32 and LP64 Linux systems. */ > -extern struct link_map_offsets *linux_ilp32_fetch_link_map_offsets (); > -extern struct link_map_offsets *linux_lp64_fetch_link_map_offsets (); > - > #endif /* GDB_LINUX_TDEP_H */ > diff --git a/gdb/loongarch-linux-tdep.c b/gdb/loongarch-linux-tdep.c > index 38485e04b1ec..af6474e8390b 100644 > --- a/gdb/loongarch-linux-tdep.c > +++ b/gdb/loongarch-linux-tdep.c > @@ -25,6 +25,7 @@ > #include "inferior.h" > #include "linux-record.h" > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > #include "loongarch-tdep.h" > #include "record-full.h" > #include "regset.h" > @@ -1145,10 +1146,9 @@ loongarch_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > > linux_init_abi (info, gdbarch, 0); > > - set_solib_svr4_fetch_link_map_offsets (gdbarch, > - info.bfd_arch_info->bits_per_address == 32 > - ? linux_ilp32_fetch_link_map_offsets > - : linux_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, (info.bfd_arch_info->bits_per_address == 32 > + ? new_linux_ilp32_svr4_solib_ops > + : new_linux_lp64_svr4_solib_ops)); > > /* GNU/Linux uses SVR4-style shared libraries. */ > set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); > diff --git a/gdb/m32r-linux-tdep.c b/gdb/m32r-linux-tdep.c > index 4fbe7d9927c0..52061923f8eb 100644 > --- a/gdb/m32r-linux-tdep.c > +++ b/gdb/m32r-linux-tdep.c > @@ -36,6 +36,7 @@ > > #include "m32r-tdep.h" > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > #include "gdbarch.h" > > > @@ -461,8 +462,7 @@ m32r_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > > /* GNU/Linux uses SVR4-style shared libraries. */ > set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, linux_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops); > > /* Core file support. */ > set_gdbarch_iterate_over_regset_sections > diff --git a/gdb/m68k-bsd-tdep.c b/gdb/m68k-bsd-tdep.c > index 09c57c6e61da..8155f7d2fe06 100644 > --- a/gdb/m68k-bsd-tdep.c > +++ b/gdb/m68k-bsd-tdep.c > @@ -147,8 +147,7 @@ m68kbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > tdep->struct_return = pcc_struct_return; > > /* NetBSD ELF uses SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops); > } > > void _initialize_m68kbsd_tdep (); > diff --git a/gdb/m68k-linux-tdep.c b/gdb/m68k-linux-tdep.c > index cfc37abc59c6..baaf0d4c9740 100644 > --- a/gdb/m68k-linux-tdep.c > +++ b/gdb/m68k-linux-tdep.c > @@ -35,6 +35,7 @@ > #include "observable.h" > #include "elf/common.h" > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > #include "regset.h" > > /* Offsets (in target ints) into jmp_buf. */ > @@ -407,8 +408,7 @@ m68k_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > /* Shared library handling. */ > > /* GNU/Linux uses SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets (gdbarch, > - linux_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops); > > /* GNU/Linux uses the dynamic linker included in the GNU C Library. */ > set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver); > diff --git a/gdb/microblaze-linux-tdep.c b/gdb/microblaze-linux-tdep.c > index 8dcbeaafb834..9d18fbe7aa04 100644 > --- a/gdb/microblaze-linux-tdep.c > +++ b/gdb/microblaze-linux-tdep.c > @@ -35,6 +35,7 @@ > #include "frame-unwind.h" > #include "tramp-frame.h" > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > > static int > microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch, > @@ -125,8 +126,7 @@ microblaze_linux_init_abi (struct gdbarch_info info, > microblaze_linux_memory_remove_breakpoint); > > /* Shared library handling. */ > - set_solib_svr4_fetch_link_map_offsets (gdbarch, > - linux_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops); > > /* Trampolines. */ > tramp_frame_prepend_unwinder (gdbarch, > diff --git a/gdb/mips-fbsd-tdep.c b/gdb/mips-fbsd-tdep.c > index c280527b6abb..f00ab31db3c9 100644 > --- a/gdb/mips-fbsd-tdep.c > +++ b/gdb/mips-fbsd-tdep.c > @@ -476,12 +476,28 @@ mips_fbsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc) > return fbsd_skip_solib_resolver (gdbarch, pc); > } > > -/* FreeBSD/mips uses a slightly different `struct link_map' than the > - other FreeBSD platforms as it includes an additional `l_off' > - member. */ > +/* solib_ops for ILP32 FreeBSD/MIPS systems. */ > > -static struct link_map_offsets * > -mips_fbsd_ilp32_fetch_link_map_offsets (void) > +struct mips_fbsd_ilp32_solib_ops : public svr4_solib_ops > +{ > + /* FreeBSD/MIPS uses a slightly different `struct link_map' than the > + other FreeBSD platforms as it includes an additional `l_off' member. */ > + > + link_map_offsets *fetch_link_map_offsets () const override; > +}; > + > +/* Return a new solib_ops for ILP32 FreeBSD/MIPS systems. */ > + > +static solib_ops_up > +new_mips_fbsd_ilp32_solib_ops () > +{ > + return std::make_unique (); > +} > + > +/* See mips_fbsd_ilp32_solib_ops. */ > + > +link_map_offsets * > +mips_fbsd_ilp32_solib_ops::fetch_link_map_offsets () const > { > static struct link_map_offsets lmo; > static struct link_map_offsets *lmp = NULL; > @@ -508,8 +524,28 @@ mips_fbsd_ilp32_fetch_link_map_offsets (void) > return lmp; > } > > -static struct link_map_offsets * > -mips_fbsd_lp64_fetch_link_map_offsets (void) > +/* solib_ops for LP64 FreeBSD/MIPS systems. */ > + > +struct mips_fbsd_lp64_solib_ops : public svr4_solib_ops > +{ > + /* FreeBSD/MIPS uses a slightly different `struct link_map' than the > + other FreeBSD platforms as it includes an additional `l_off' member. */ > + > + link_map_offsets *fetch_link_map_offsets () const override; > +}; > + > +/* Return a new solib_ops for LP64 FreeBSD/MIPS systems. */ > + > +static solib_ops_up > +new_mips_fbsd_lp64_solib_ops () > +{ > + return std::make_unique (); > +} > + > +/* See mips_fbsd_lp64_solib_ops. */ > + > +link_map_offsets * > +mips_fbsd_lp64_solib_ops::fetch_link_map_offsets () const > { > static struct link_map_offsets lmo; > static struct link_map_offsets *lmp = NULL; > @@ -565,10 +601,9 @@ mips_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > set_gdbarch_skip_solib_resolver (gdbarch, mips_fbsd_skip_solib_resolver); > > /* FreeBSD/mips has SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32 ? > - mips_fbsd_ilp32_fetch_link_map_offsets : > - mips_fbsd_lp64_fetch_link_map_offsets)); > + set_solib_svr4_ops (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32 > + ? new_mips_fbsd_ilp32_solib_ops > + : new_mips_fbsd_lp64_solib_ops)); > } > > void _initialize_mips_fbsd_tdep (); > diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c > index bf3df3697e15..29633d8298df 100644 > --- a/gdb/mips-linux-tdep.c > +++ b/gdb/mips-linux-tdep.c > @@ -36,6 +36,7 @@ > #include "mips-linux-tdep.h" > #include "glibc-tdep.h" > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > #include "xml-syscall.h" > #include "gdbsupport/gdb_signals.h" > #include "inferior.h" > @@ -45,8 +46,6 @@ > #include "features/mips64-linux.c" > #include "features/mips64-dsp-linux.c" > > -static solib_ops mips_svr4_so_ops; > - > /* This enum represents the signals' numbers on the MIPS > architecture. It just contains the signal definitions which are > different from the generic implementation. > @@ -666,15 +665,22 @@ mips_linux_in_dynsym_stub (CORE_ADDR pc) > return 1; > } > > -/* Return true iff PC belongs to the dynamic linker resolution > - code, a PLT entry, or a lazy binding stub. */ > +/* Mix-in class to add Linux/MIPS-specific methods to a base solib_ops > + class. */ > > -static bool > -mips_linux_in_dynsym_resolve_code (CORE_ADDR pc) > +template > +struct mips_linux_svr4_solib_ops : public Base > +{ > + bool in_dynsym_resolve_code (CORE_ADDR pc) const override; > +}; > + > +template > +bool > +mips_linux_svr4_solib_ops::in_dynsym_resolve_code (CORE_ADDR pc) const > { > /* Check whether PC is in the dynamic linker. This also checks > whether it is in the .plt section, used by non-PIC executables. */ > - if (svr4_in_dynsym_resolve_code (pc)) > + if (Base::in_dynsym_resolve_code (pc)) > return true; > > /* Likewise for the stubs. They live in the .MIPS.stubs section these > @@ -686,6 +692,32 @@ mips_linux_in_dynsym_resolve_code (CORE_ADDR pc) > return false; > } > > +/* solib_ops for ILP32 Linux/MIPS systems. */ > + > +using mips_linux_ilp32_svr4_solib_ops > + = mips_linux_svr4_solib_ops; > + > +/* Return a new solib_ops for ILP32 Linux/MIPS systems. */ > + > +static solib_ops_up > +new_mips_linux_ilp32_svr4_solib_ops () > +{ > + return std::make_unique (); > +} > + > +/* solib_ops for LP64 Linux/MIPS systems. */ > + > +using mips_linux_lp64_svr4_solib_ops > + = mips_linux_svr4_solib_ops; > + > +/* Return a new solib_ops for LP64 Linux/MIPS systems. */ > + > +static solib_ops_up > +new_mips_linux_lp64_svr4_solib_ops () > +{ > + return std::make_unique (); > +} > + > /* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c, > and glibc_skip_solib_resolver in glibc-tdep.c. The normal glibc > implementation of this triggers at "fixup" from the same objfile as > @@ -1537,8 +1569,7 @@ mips_linux_init_abi (struct gdbarch_info info, > case MIPS_ABI_O32: > set_gdbarch_get_longjmp_target (gdbarch, > mips_linux_get_longjmp_target); > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, linux_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_mips_linux_ilp32_svr4_solib_ops); > tramp_frame_prepend_unwinder (gdbarch, µmips_linux_o32_sigframe); > tramp_frame_prepend_unwinder (gdbarch, > µmips_linux_o32_rt_sigframe); > @@ -1549,8 +1580,7 @@ mips_linux_init_abi (struct gdbarch_info info, > case MIPS_ABI_N32: > set_gdbarch_get_longjmp_target (gdbarch, > mips_linux_get_longjmp_target); > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, linux_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_mips_linux_ilp32_svr4_solib_ops); > set_gdbarch_long_double_bit (gdbarch, 128); > set_gdbarch_long_double_format (gdbarch, floatformats_ieee_quad); > tramp_frame_prepend_unwinder (gdbarch, > @@ -1561,8 +1591,7 @@ mips_linux_init_abi (struct gdbarch_info info, > case MIPS_ABI_N64: > set_gdbarch_get_longjmp_target (gdbarch, > mips64_linux_get_longjmp_target); > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, linux_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_mips_linux_lp64_svr4_solib_ops); > set_gdbarch_long_double_bit (gdbarch, 128); > set_gdbarch_long_double_format (gdbarch, floatformats_ieee_quad); > tramp_frame_prepend_unwinder (gdbarch, > @@ -1582,16 +1611,6 @@ mips_linux_init_abi (struct gdbarch_info info, > set_gdbarch_fetch_tls_load_module_address (gdbarch, > svr4_fetch_objfile_link_map); > > - /* Initialize this lazily, to avoid an initialization order > - dependency on solib-svr4.c's _initialize routine. */ > - if (mips_svr4_so_ops.in_dynsym_resolve_code == NULL) > - { > - mips_svr4_so_ops = svr4_so_ops; > - mips_svr4_so_ops.in_dynsym_resolve_code > - = mips_linux_in_dynsym_resolve_code; > - } > - set_gdbarch_so_ops (gdbarch, &mips_svr4_so_ops); > - > set_gdbarch_write_pc (gdbarch, mips_linux_write_pc); > > set_gdbarch_core_read_description (gdbarch, > diff --git a/gdb/mips-netbsd-tdep.c b/gdb/mips-netbsd-tdep.c > index c9bdaa6800bb..165bf95c1881 100644 > --- a/gdb/mips-netbsd-tdep.c > +++ b/gdb/mips-netbsd-tdep.c > @@ -288,13 +288,27 @@ mipsnbsd_cannot_store_register (struct gdbarch *gdbarch, int regno) > || regno == mips_regnum (gdbarch)->fp_implementation_revision); > } > > -/* Shared library support. */ > +/* solib_ops for ILP32 NetBSD/MIPS systems. */ > > -/* NetBSD/mips uses a slightly different `struct link_map' than the > - other NetBSD platforms. */ > +struct mips_nbsd_ilp32_svr4_solib_ops : public svr4_solib_ops > +{ > + /* NetBSD/MIPS uses a slightly different `struct link_map' than the > + other NetBSD platforms. */ > + link_map_offsets *fetch_link_map_offsets () const override; > +}; > > -static struct link_map_offsets * > -mipsnbsd_ilp32_fetch_link_map_offsets (void) > +/* Return a new solib_ops for ILP32 NetBSD/MIPS systems. */ > + > +static solib_ops_up > +new_mips_nbsd_ilp32_svr4_solib_ops () > +{ > + return std::make_unique (); > +} > + > +/* See mips_nbsd_ilp32_svr4_solib_ops. */ > + > +link_map_offsets * > +mips_nbsd_ilp32_svr4_solib_ops::fetch_link_map_offsets () const > { > static struct link_map_offsets lmo; > static struct link_map_offsets *lmp = NULL; > @@ -322,8 +336,27 @@ mipsnbsd_ilp32_fetch_link_map_offsets (void) > return lmp; > } > > -static struct link_map_offsets * > -mipsnbsd_lp64_fetch_link_map_offsets (void) > +/* solib_ops for LP64 NetBSD/MIPS systems. */ > + > +struct mips_nbsd_lp64_svr4_solib_ops : public svr4_solib_ops > +{ > + /* NetBSD/MIPS uses a slightly different `struct link_map' than the > + other NetBSD platforms. */ > + link_map_offsets *fetch_link_map_offsets () const override; > +}; > + > +/* Return a new solib_ops for LP64 NetBSD/MIPS systems. */ > + > +static solib_ops_up > +new_mips_nbsd_lp64_svr4_solib_ops () > +{ > + return std::make_unique (); > +} > + > +/* See mips_nbsd_lp64_svr4_solib_ops. */ > + > +link_map_offsets * > +mips_nbsd_lp64_svr4_solib_ops::fetch_link_map_offsets () const > { > static struct link_map_offsets lmo; > static struct link_map_offsets *lmp = NULL; > @@ -369,10 +402,9 @@ mipsnbsd_init_abi (struct gdbarch_info info, > set_gdbarch_software_single_step (gdbarch, mips_software_single_step); > > /* NetBSD/mips has SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32 ? > - mipsnbsd_ilp32_fetch_link_map_offsets : > - mipsnbsd_lp64_fetch_link_map_offsets)); > + set_solib_svr4_ops (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32 > + ? new_mips_nbsd_ilp32_svr4_solib_ops > + : new_mips_nbsd_lp64_svr4_solib_ops)); > } > > void _initialize_mipsnbsd_tdep (); > diff --git a/gdb/mips64-obsd-tdep.c b/gdb/mips64-obsd-tdep.c > index d0c9a1c86587..2d856c1442f2 100644 > --- a/gdb/mips64-obsd-tdep.c > +++ b/gdb/mips64-obsd-tdep.c > @@ -150,8 +150,7 @@ mips64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > obsd_init_abi(info, gdbarch); > > /* OpenBSD/mips64 has SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops); > } > > void _initialize_mips64obsd_tdep (); > diff --git a/gdb/mn10300-linux-tdep.c b/gdb/mn10300-linux-tdep.c > index 3334ca0cc7d2..0fa5db972151 100644 > --- a/gdb/mn10300-linux-tdep.c > +++ b/gdb/mn10300-linux-tdep.c > @@ -29,6 +29,7 @@ > #include "trad-frame.h" > #include "tramp-frame.h" > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > #include "gdbarch.h" > > /* Transliterated from ... */ > @@ -707,8 +708,7 @@ am33_linux_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch) > > set_gdbarch_iterate_over_regset_sections > (gdbarch, am33_iterate_over_regset_sections); > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, linux_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops); > > tramp_frame_prepend_unwinder (gdbarch, &am33_linux_sigframe); > tramp_frame_prepend_unwinder (gdbarch, &am33_linux_rt_sigframe); > diff --git a/gdb/or1k-linux-tdep.c b/gdb/or1k-linux-tdep.c > index 4784e0b73e94..ca7562ee9a59 100644 > --- a/gdb/or1k-linux-tdep.c > +++ b/gdb/or1k-linux-tdep.c > @@ -20,6 +20,7 @@ > #include "osabi.h" > #include "glibc-tdep.h" > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > #include "solib-svr4.h" > #include "regset.h" > #include "tramp-frame.h" > @@ -144,8 +145,7 @@ or1k_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > { > linux_init_abi (info, gdbarch, 0); > > - set_solib_svr4_fetch_link_map_offsets (gdbarch, > - linux_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops); > > /* GNU/Linux uses SVR4-style shared libraries. */ > set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); > diff --git a/gdb/ppc-fbsd-tdep.c b/gdb/ppc-fbsd-tdep.c > index 3bab0318f487..5705bd96c314 100644 > --- a/gdb/ppc-fbsd-tdep.c > +++ b/gdb/ppc-fbsd-tdep.c > @@ -332,8 +332,7 @@ ppcfbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > set_gdbarch_return_value (gdbarch, ppcfbsd_return_value); > > set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); > - set_solib_svr4_fetch_link_map_offsets (gdbarch, > - svr4_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops); > > frame_unwind_append_unwinder (gdbarch, &ppcfbsd_sigtramp_frame_unwind); > set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpc"); > @@ -347,8 +346,7 @@ ppcfbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > ppc64_elf_make_msymbol_special); > > set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code); > - set_solib_svr4_fetch_link_map_offsets (gdbarch, > - svr4_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops); > set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpc"); > } > > diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c > index b3cc4d5485e2..8f93d468bf99 100644 > --- a/gdb/ppc-linux-tdep.c > +++ b/gdb/ppc-linux-tdep.c > @@ -48,6 +48,7 @@ > #include "arch-utils.h" > #include "xml-syscall.h" > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > #include "svr4-tls-tdep.h" > #include "linux-record.h" > #include "record-full.h" > @@ -86,8 +87,6 @@ > #include "features/rs6000/powerpc-e500l.c" > #include "dwarf2/frame.h" > > -/* Shared library operations for PowerPC-Linux. */ > -static solib_ops powerpc_so_ops; > > /* The syscall's XML filename for PPC and PPC64. */ > #define XML_SYSCALL_FILENAME_PPC "syscalls/ppc-linux.xml" > @@ -306,16 +305,33 @@ static const struct ppc_insn_pattern powerpc32_plt_stub_so_2[] = > /* The max number of insns we check using ppc_insns_match_pattern. */ > #define POWERPC32_PLT_CHECK_LEN (ARRAY_SIZE (powerpc32_plt_stub) - 1) > > -/* Check if PC is in PLT stub. For non-secure PLT, stub is in .plt > - section. For secure PLT, stub is in .text and we need to check > - instruction patterns. */ > +/* solib_ops for ILP32 PowerPC/Linux systems. */ > > -static bool > -powerpc_linux_in_dynsym_resolve_code (CORE_ADDR pc) > +struct ppc_linux_ilp32_svr4_solib_ops : public linux_ilp32_svr4_solib_ops > +{ > + /* Check if PC is in PLT stub. For non-secure PLT, stub is in .plt > + section. For secure PLT, stub is in .text and we need to check > + instruction patterns. */ > + > + bool in_dynsym_resolve_code (CORE_ADDR pc) const override; > +}; > + > +/* Return a new solib_ops for ILP32 PowerPC/Linux systems. */ > + > +static solib_ops_up > +new_ppc_linux_ilp32_svr4_solib_ops () > +{ > + return std::make_unique (); > +} > + > +/* See ppc_linux_ilp32_svr4_solib_ops. */ > + > +bool > +ppc_linux_ilp32_svr4_solib_ops::in_dynsym_resolve_code (CORE_ADDR pc) const > { > /* Check whether PC is in the dynamic linker. This also checks > whether it is in the .plt section, used by non-PIC executables. */ > - if (svr4_in_dynsym_resolve_code (pc)) > + if (linux_ilp32_svr4_solib_ops::in_dynsym_resolve_code (pc)) > return true; > > /* Check if we are in the resolver. */ > @@ -2265,8 +2281,6 @@ ppc_linux_init_abi (struct gdbarch_info info, > > /* Shared library handling. */ > set_gdbarch_skip_trampoline_code (gdbarch, ppc_skip_trampoline_code); > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, linux_ilp32_fetch_link_map_offsets); > > /* Setting the correct XML syscall filename. */ > set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_PPC); > @@ -2283,14 +2297,7 @@ ppc_linux_init_abi (struct gdbarch_info info, > else > set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpc"); > > - if (powerpc_so_ops.in_dynsym_resolve_code == NULL) > - { > - powerpc_so_ops = svr4_so_ops; > - /* Override dynamic resolve function. */ > - powerpc_so_ops.in_dynsym_resolve_code = > - powerpc_linux_in_dynsym_resolve_code; > - } > - set_gdbarch_so_ops (gdbarch, &powerpc_so_ops); > + set_solib_svr4_ops (gdbarch, new_ppc_linux_ilp32_svr4_solib_ops); > > set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver); > } > @@ -2317,8 +2324,7 @@ ppc_linux_init_abi (struct gdbarch_info info, > > /* Shared library handling. */ > set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code); > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, linux_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_lp64_svr4_solib_ops); > > /* Setting the correct XML syscall filename. */ > set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_PPC64); > diff --git a/gdb/ppc-netbsd-tdep.c b/gdb/ppc-netbsd-tdep.c > index 911c012983e6..b030f93a2525 100644 > --- a/gdb/ppc-netbsd-tdep.c > +++ b/gdb/ppc-netbsd-tdep.c > @@ -179,8 +179,7 @@ ppcnbsd_init_abi (struct gdbarch_info info, > set_gdbarch_return_value (gdbarch, ppcnbsd_return_value); > > /* NetBSD uses SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops); > > set_gdbarch_iterate_over_regset_sections > (gdbarch, ppcnbsd_iterate_over_regset_sections); > diff --git a/gdb/ppc-obsd-tdep.c b/gdb/ppc-obsd-tdep.c > index 5e271c1c7be3..dc00227a0c29 100644 > --- a/gdb/ppc-obsd-tdep.c > +++ b/gdb/ppc-obsd-tdep.c > @@ -254,8 +254,7 @@ ppcobsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > set_gdbarch_return_value (gdbarch, ppc_sysv_abi_broken_return_value); > > /* OpenBSD uses SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops); > > set_gdbarch_iterate_over_regset_sections > (gdbarch, ppcobsd_iterate_over_regset_sections); > diff --git a/gdb/progspace.h b/gdb/progspace.h > index abb448195d74..c84a95c96657 100644 > --- a/gdb/progspace.h > +++ b/gdb/progspace.h > @@ -21,6 +21,7 @@ > #ifndef GDB_PROGSPACE_H > #define GDB_PROGSPACE_H > > +#include "solib.h" > #include "target.h" > #include "gdb_bfd.h" > #include "registry.h" > @@ -234,19 +235,23 @@ struct program_space > /* Set this program space's solib provider. > > The solib provider must be unset prior to call this method. */ > - void set_solib_ops (const struct solib_ops &ops) > + void set_solib_ops (solib_ops_up ops) > { > gdb_assert (m_solib_ops == nullptr); > - m_solib_ops = &ops; > + m_solib_ops = std::move (ops); > }; > > - /* Unset this program space's solib provider. */ > + /* Unset and free this program space's solib provider. */ > void unset_solib_ops () > { m_solib_ops = nullptr; } > > + /* Unset and return this program space's solib provider. */ > + solib_ops_up release_solib_ops () > + { return std::move (m_solib_ops); } > + > /* Get this program space's solib provider. */ > - const struct solib_ops *solib_ops () const > - { return m_solib_ops; } > + struct solib_ops *solib_ops () const > + { return m_solib_ops.get (); } > > /* Return the list of all the solibs in this program space. */ > owning_intrusive_list &solibs () > @@ -373,7 +378,7 @@ struct program_space > owning_intrusive_list m_objfiles_list; > > /* solib_ops implementation used to provide solibs in this program space. */ > - const struct solib_ops *m_solib_ops = nullptr; > + solib_ops_up m_solib_ops; > > /* List of shared objects mapped into this space. Managed by > solib.c. */ > diff --git a/gdb/riscv-fbsd-tdep.c b/gdb/riscv-fbsd-tdep.c > index fcb91caf5fb6..69e14ac47e3a 100644 > --- a/gdb/riscv-fbsd-tdep.c > +++ b/gdb/riscv-fbsd-tdep.c > @@ -191,10 +191,9 @@ riscv_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > > set_gdbarch_software_single_step (gdbarch, riscv_software_single_step); > > - set_solib_svr4_fetch_link_map_offsets (gdbarch, > - (riscv_isa_xlen (gdbarch) == 4 > - ? svr4_ilp32_fetch_link_map_offsets > - : svr4_lp64_fetch_link_map_offsets)); > + set_solib_svr4_ops (gdbarch, (riscv_isa_xlen (gdbarch) == 4 > + ? new_svr4_ilp32_solib_ops > + : new_svr4_lp64_solib_ops)); > > tramp_frame_prepend_unwinder (gdbarch, &riscv_fbsd_sigframe); > > diff --git a/gdb/riscv-linux-tdep.c b/gdb/riscv-linux-tdep.c > index e1ea6158a45c..fb21fa0cfa1a 100644 > --- a/gdb/riscv-linux-tdep.c > +++ b/gdb/riscv-linux-tdep.c > @@ -20,6 +20,7 @@ > #include "osabi.h" > #include "glibc-tdep.h" > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > #include "svr4-tls-tdep.h" > #include "solib-svr4.h" > #include "regset.h" > @@ -512,10 +513,9 @@ riscv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > > set_gdbarch_software_single_step (gdbarch, riscv_software_single_step); > > - set_solib_svr4_fetch_link_map_offsets (gdbarch, > - (riscv_isa_xlen (gdbarch) == 4 > - ? linux_ilp32_fetch_link_map_offsets > - : linux_lp64_fetch_link_map_offsets)); > + set_solib_svr4_ops (gdbarch, (riscv_isa_xlen (gdbarch) == 4 > + ? new_linux_ilp32_svr4_solib_ops > + : new_linux_lp64_svr4_solib_ops)); > > /* GNU/Linux uses SVR4-style shared libraries. */ > set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); > diff --git a/gdb/rs6000-aix-tdep.c b/gdb/rs6000-aix-tdep.c > index ab9feb38fb78..214fb88c32cc 100644 > --- a/gdb/rs6000-aix-tdep.c > +++ b/gdb/rs6000-aix-tdep.c > @@ -1411,7 +1411,7 @@ rs6000_aix_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch) > set_gdbarch_wchar_signed (gdbarch, 0); > set_gdbarch_auto_wide_charset (gdbarch, rs6000_aix_auto_wide_charset); > > - set_gdbarch_so_ops (gdbarch, &solib_aix_so_ops); > + set_gdbarch_new_solib_ops (gdbarch, new_aix_solib_ops); > frame_unwind_append_unwinder (gdbarch, &aix_sighandle_frame_unwind); > } > > diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c > index bd1f42ca8d25..e22e1454bed6 100644 > --- a/gdb/s390-linux-tdep.c > +++ b/gdb/s390-linux-tdep.c > @@ -29,6 +29,7 @@ > #include "gdbcore.h" > #include "linux-record.h" > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > #include "svr4-tls-tdep.h" > #include "objfiles.h" > #include "osabi.h" > @@ -1214,8 +1215,7 @@ s390_linux_init_abi_31 (struct gdbarch_info info, struct gdbarch *gdbarch) > > s390_linux_init_abi_any (info, gdbarch); > > - set_solib_svr4_fetch_link_map_offsets (gdbarch, > - linux_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops); > set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_S390); > } > > @@ -1230,8 +1230,7 @@ s390_linux_init_abi_64 (struct gdbarch_info info, struct gdbarch *gdbarch) > > s390_linux_init_abi_any (info, gdbarch); > > - set_solib_svr4_fetch_link_map_offsets (gdbarch, > - linux_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_lp64_svr4_solib_ops); > set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_S390X); > } > > diff --git a/gdb/sh-linux-tdep.c b/gdb/sh-linux-tdep.c > index f0b35d3063a6..c28ec361eb05 100644 > --- a/gdb/sh-linux-tdep.c > +++ b/gdb/sh-linux-tdep.c > @@ -28,6 +28,7 @@ > #include "glibc-tdep.h" > #include "sh-tdep.h" > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > #include "gdbarch.h" > > #define REGSx16(base) \ > @@ -187,8 +188,7 @@ sh_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > > /* GNU/Linux uses SVR4-style shared libraries. */ > set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, linux_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops); > set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver); > > set_gdbarch_fetch_tls_load_module_address (gdbarch, > diff --git a/gdb/sh-netbsd-tdep.c b/gdb/sh-netbsd-tdep.c > index f99566f2fd59..685ba3c0585d 100644 > --- a/gdb/sh-netbsd-tdep.c > +++ b/gdb/sh-netbsd-tdep.c > @@ -68,8 +68,7 @@ shnbsd_init_abi (struct gdbarch_info info, > tdep->core_gregmap = (struct sh_corefile_regmap *)regmap; > tdep->sizeof_gregset = 84; > > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops); > } > > void _initialize_shnbsd_tdep (); > diff --git a/gdb/solib-aix.c b/gdb/solib-aix.c > index 17eeba940770..91cc1d8c66de 100644 > --- a/gdb/solib-aix.c > +++ b/gdb/solib-aix.c > @@ -24,6 +24,24 @@ > #include "xcoffread.h" > #include "observable.h" > > +/* solib_ops for AIX systems. */ > + > +struct aix_solib_ops : public solib_ops > +{ > + void relocate_section_addresses (solib &so, target_section *) const override; > + void create_inferior_hook (int from_tty) override; > + owning_intrusive_list current_sos () override; > + gdb_bfd_ref_ptr bfd_open (const char *pathname) override; > +}; > + > +/* See solib-aix.h. */ > + > +solib_ops_up > +new_aix_solib_ops () > +{ > + return std::make_unique (); > +} > + > /* Our private data in struct solib. */ > > struct lm_info_aix final : public lm_info > @@ -306,10 +324,9 @@ solib_aix_bss_data_overlap (bfd *abfd) > return 0; > } > > -/* Implement the "relocate_section_addresses" solib_ops method. */ > - > -static void > -solib_aix_relocate_section_addresses (solib &so, target_section *sec) > +void > +aix_solib_ops::relocate_section_addresses (solib &so, > + target_section *sec) const > { > struct bfd_section *bfd_sect = sec->the_bfd_section; > bfd *abfd = bfd_sect->owner; > @@ -410,10 +427,8 @@ solib_aix_get_section_offsets (struct objfile *objfile, > return offsets; > } > > -/* Implement the "solib_create_inferior_hook" solib_ops method. */ > - > -static void > -solib_aix_solib_create_inferior_hook (int from_tty) > +void > +aix_solib_ops::create_inferior_hook (int from_tty) > { > const char *warning_msg = "unable to relocate main executable"; > > @@ -441,10 +456,8 @@ solib_aix_solib_create_inferior_hook (int from_tty) > } > } > > -/* Implement the "current_sos" solib_ops method. */ > - > -static owning_intrusive_list > -solib_aix_current_sos () > +owning_intrusive_list > +aix_solib_ops::current_sos () > { > std::optional> &library_list > = solib_aix_get_library_list (current_inferior (), NULL); > @@ -480,7 +493,7 @@ solib_aix_current_sos () > } > > /* Add it to the list. */ > - auto &new_solib = sos.emplace_back (solib_aix_so_ops); > + auto &new_solib = sos.emplace_back (*this); > new_solib.original_name = so_name; > new_solib.name = so_name; > new_solib.lm_info = std::make_unique (info); > @@ -489,10 +502,8 @@ solib_aix_current_sos () > return sos; > } > > -/* Implement the "bfd_open" solib_ops method. */ > - > -static gdb_bfd_ref_ptr > -solib_aix_bfd_open (const char *pathname) > +gdb_bfd_ref_ptr > +aix_solib_ops::bfd_open (const char *pathname) > { > /* The pathname is actually a synthetic filename with the following > form: "/path/to/sharedlib(member.o)" (double-quotes excluded). > @@ -506,7 +517,7 @@ solib_aix_bfd_open (const char *pathname) > int found_file; > > if (pathname[path_len - 1] != ')') > - return solib_bfd_open (pathname); > + return solib_ops::bfd_open (pathname); > > /* Search for the associated parens. */ > sep = strrchr (pathname, '('); > @@ -516,7 +527,7 @@ solib_aix_bfd_open (const char *pathname) > to open pathname without decoding, possibly leading to > a failure), rather than triggering an assert failure). */ > warning (_("missing '(' in shared object pathname: %s"), pathname); > - return solib_bfd_open (pathname); > + return solib_ops::bfd_open (pathname); > } > filename_len = sep - pathname; > > @@ -659,24 +670,6 @@ solib_aix_normal_stop_observer (struct bpstat *unused_1, int unused_2) > data->library_list.reset (); > } > > -/* The solib_ops for AIX targets. */ > -const solib_ops solib_aix_so_ops = > -{ > - solib_aix_relocate_section_addresses, > - nullptr, > - nullptr, > - solib_aix_solib_create_inferior_hook, > - solib_aix_current_sos, > - nullptr, > - nullptr, > - solib_aix_bfd_open, > - nullptr, > - nullptr, > - nullptr, > - nullptr, > - default_find_solib_addr, > -}; > - > void _initialize_solib_aix (); > void > _initialize_solib_aix () > diff --git a/gdb/solib-aix.h b/gdb/solib-aix.h > index 7a1bc7b4b567..ac824e547cfa 100644 > --- a/gdb/solib-aix.h > +++ b/gdb/solib-aix.h > @@ -18,9 +18,12 @@ > #ifndef GDB_SOLIB_AIX_H > #define GDB_SOLIB_AIX_H > > -struct solib_ops; > -extern const solib_ops solib_aix_so_ops; > +#include "solib.h" > > extern CORE_ADDR solib_aix_get_toc_value (CORE_ADDR pc); > > +/* Return a new solib_ops for AIX systems. */ > + > +solib_ops_up new_aix_solib_ops (); > + > #endif /* GDB_SOLIB_AIX_H */ > diff --git a/gdb/solib-darwin.c b/gdb/solib-darwin.c > index 88a2962f5dd5..aece190a711d 100644 > --- a/gdb/solib-darwin.c > +++ b/gdb/solib-darwin.c > @@ -33,6 +33,25 @@ > #include "mach-o.h" > #include "mach-o/external.h" > > +/* solib_ops for Darwin systems. */ > + > +struct darwin_solib_ops : public solib_ops > +{ > + void relocate_section_addresses (solib &so, target_section *) const override; > + void clear_solib (program_space *pspace) override; > + void create_inferior_hook (int from_tty) override; > + owning_intrusive_list current_sos () override; > + gdb_bfd_ref_ptr bfd_open (const char *pathname) override; > +}; > + > +/* See solib-darwin.h. */ > + > +solib_ops_up > +new_darwin_solib_ops () > +{ > + return std::make_unique (); > +} > + > struct gdb_dyld_image_info > { > /* Base address (which corresponds to the Mach-O header). */ > @@ -188,10 +207,8 @@ find_program_interpreter (void) > return buf; > } > > -/* Build a list of currently loaded shared objects. See solib-svr4.c. */ > - > -static owning_intrusive_list > -darwin_current_sos () > +owning_intrusive_list > +darwin_solib_ops::current_sos () > { > type *ptr_type > = builtin_type (current_inferior ()->arch ())->builtin_data_ptr; > @@ -250,7 +267,7 @@ darwin_current_sos () > break; > > /* Create and fill the new struct solib element. */ > - auto &newobj = sos.emplace_back (darwin_so_ops); > + auto &newobj = sos.emplace_back (*this); > > auto li = std::make_unique (); > > @@ -457,10 +474,8 @@ darwin_solib_read_all_image_info_addr (struct darwin_info *info) > info->all_image_addr = extract_unsigned_integer (buf, len, BFD_ENDIAN_BIG); > } > > -/* Shared library startup support. See documentation in solib-svr4.c. */ > - > -static void > -darwin_solib_create_inferior_hook (int from_tty) > +void > +darwin_solib_ops::create_inferior_hook (int from_tty) > { > /* Everything below only makes sense if we have a running inferior. */ > if (!target_has_execution ()) > @@ -560,8 +575,8 @@ darwin_solib_create_inferior_hook (int from_tty) > create_solib_event_breakpoint (current_inferior ()->arch (), notifier); > } > > -static void > -darwin_clear_solib (program_space *pspace) > +void > +darwin_solib_ops::clear_solib (program_space *pspace) > { > darwin_info *info = get_darwin_info (pspace); > > @@ -572,8 +587,9 @@ darwin_clear_solib (program_space *pspace) > /* The section table is built from bfd sections using bfd VMAs. > Relocate these VMAs according to solib info. */ > > -static void > -darwin_relocate_section_addresses (solib &so, target_section *sec) > +void > +darwin_solib_ops::relocate_section_addresses (solib &so, > + target_section *sec) const > { > auto *li = gdb::checked_static_cast (so.lm_info.get ()); > > @@ -592,9 +608,9 @@ darwin_relocate_section_addresses (solib &so, target_section *sec) > if (sec->addr < so.addr_low) > so.addr_low = sec->addr; > } > - > -static gdb_bfd_ref_ptr > -darwin_bfd_open (const char *pathname) > + > +gdb_bfd_ref_ptr > +darwin_solib_ops::bfd_open (const char *pathname) > { > int found_file; > > @@ -622,20 +638,3 @@ darwin_bfd_open (const char *pathname) > > return res; > } > - > -const solib_ops darwin_so_ops = > -{ > - darwin_relocate_section_addresses, > - nullptr, > - darwin_clear_solib, > - darwin_solib_create_inferior_hook, > - darwin_current_sos, > - nullptr, > - nullptr, > - darwin_bfd_open, > - nullptr, > - nullptr, > - nullptr, > - nullptr, > - default_find_solib_addr, > -}; > diff --git a/gdb/solib-darwin.h b/gdb/solib-darwin.h > index b96e744669fb..09dac6bf52ba 100644 > --- a/gdb/solib-darwin.h > +++ b/gdb/solib-darwin.h > @@ -20,8 +20,10 @@ > #ifndef GDB_SOLIB_DARWIN_H > #define GDB_SOLIB_DARWIN_H > > -struct solib_ops; > +#include "solib.h" > > -extern const solib_ops darwin_so_ops; > +/* Return a new solib_ops for Darwin systems. */ > + > +extern solib_ops_up new_darwin_solib_ops (); > > #endif /* GDB_SOLIB_DARWIN_H */ > diff --git a/gdb/solib-dsbt.c b/gdb/solib-dsbt.c > index f6748b69353a..97e32d19e57d 100644 > --- a/gdb/solib-dsbt.c > +++ b/gdb/solib-dsbt.c > @@ -120,6 +120,25 @@ struct dbst_ext_link_map > ext_ptr l_next, l_prev; /* struct link_map *l_next, *l_prev; */ > }; > > +/* solib_ops for DSBT systems. */ > + > +struct dsbt_solib_ops : public solib_ops > +{ > + void relocate_section_addresses (solib &so, target_section *) const override; > + void clear_solib (program_space *pspace) override; > + void create_inferior_hook (int from_tty) override; > + owning_intrusive_list current_sos () override; > + bool in_dynsym_resolve_code (CORE_ADDR pc) const override; > +}; > + > +/* See solib-dsbt.h. */ > + > +solib_ops_up > +new_dsbt_solib_ops () > +{ > + return std::make_unique (); > +} > + > /* Link map info to include in an allocated solib entry */ > > struct lm_info_dsbt final : public lm_info > @@ -502,8 +521,8 @@ lm_base (void) > themselves. The declaration of `struct solib' says which fields > we provide values for. */ > > -static owning_intrusive_list > -dsbt_current_sos (void) > +owning_intrusive_list > +dsbt_solib_ops::current_sos () > { > bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ()); > CORE_ADDR lm_addr; > @@ -584,7 +603,7 @@ dsbt_current_sos (void) > break; > } > > - auto &sop = sos.emplace_back (dsbt_so_ops); > + auto &sop = sos.emplace_back (*this); > auto li = std::make_unique (); > li->map = loadmap; > /* Fetch the name. */ > @@ -623,8 +642,8 @@ dsbt_current_sos (void) > /* Return true if PC lies in the dynamic symbol resolution code of the > run time loader. */ > > -static bool > -dsbt_in_dynsym_resolve_code (CORE_ADDR pc) > +bool > +dsbt_solib_ops::in_dynsym_resolve_code (CORE_ADDR pc) const > { > dsbt_info *info = get_dsbt_info (current_program_space); > > @@ -840,8 +859,8 @@ dsbt_relocate_main_executable (void) > For the DSBT shared library, the main executable needs to be relocated. > The shared library breakpoints also need to be enabled. */ > > -static void > -dsbt_solib_create_inferior_hook (int from_tty) > +void > +dsbt_solib_ops::create_inferior_hook (int from_tty) > { > /* Relocate main executable. */ > dsbt_relocate_main_executable (); > @@ -854,8 +873,8 @@ dsbt_solib_create_inferior_hook (int from_tty) > } > } > > -static void > -dsbt_clear_solib (program_space *pspace) > +void > +dsbt_solib_ops::clear_solib (program_space *pspace) > { > dsbt_info *info = get_dsbt_info (pspace); > > @@ -866,8 +885,9 @@ dsbt_clear_solib (program_space *pspace) > info->main_executable_lm_info = NULL; > } > > -static void > -dsbt_relocate_section_addresses (solib &so, target_section *sec) > +void > +dsbt_solib_ops::relocate_section_addresses (solib &so, > + target_section *sec) const > { > int seg; > auto *li = gdb::checked_static_cast (so.lm_info.get ()); > @@ -893,23 +913,6 @@ show_dsbt_debug (struct ui_file *file, int from_tty, > gdb_printf (file, _("solib-dsbt debugging is %s.\n"), value); > } > > -const solib_ops dsbt_so_ops = > -{ > - dsbt_relocate_section_addresses, > - nullptr, > - dsbt_clear_solib, > - dsbt_solib_create_inferior_hook, > - dsbt_current_sos, > - nullptr, > - dsbt_in_dynsym_resolve_code, > - solib_bfd_open, > - nullptr, > - nullptr, > - nullptr, > - nullptr, > - default_find_solib_addr, > -}; > - > void _initialize_dsbt_solib (); > void > _initialize_dsbt_solib () > diff --git a/gdb/solib-dsbt.h b/gdb/solib-dsbt.h > index d5c52c69e432..47b03bba589b 100644 > --- a/gdb/solib-dsbt.h > +++ b/gdb/solib-dsbt.h > @@ -20,8 +20,10 @@ > #ifndef GDB_SOLIB_DSBT_H > #define GDB_SOLIB_DSBT_H > > -struct solib_ops; > +#include "solib.h" > > -extern const solib_ops dsbt_so_ops; > +/* Return a new solib_ops for DSBT systems. */ > + > +solib_ops_up new_dsbt_solib_ops (); > > #endif /* GDB_SOLIB_DSBT_H */ > diff --git a/gdb/solib-frv.c b/gdb/solib-frv.c > index 12d3140b513c..6ef83672577d 100644 > --- a/gdb/solib-frv.c > +++ b/gdb/solib-frv.c > @@ -26,6 +26,26 @@ > #include "elf/frv.h" > #include "gdb_bfd.h" > #include "inferior.h" > +#include "solib-frv.h" > + > +/* solib_ops for FR-V systems. */ > + > +struct frv_solib_ops : public solib_ops > +{ > + void relocate_section_addresses (solib &so, target_section *) const override; > + void clear_solib (program_space *pspace) override; > + void create_inferior_hook (int from_tty) override; > + owning_intrusive_list current_sos () override; > + bool in_dynsym_resolve_code (CORE_ADDR pc) const override; > +}; > + > +/* See solib-frv.h. */ > + > +solib_ops_up > +new_frv_solib_ops () > +{ > + return std::make_unique (); > +} > > /* FR-V pointers are four bytes wide. */ > enum { FRV_PTR_SIZE = 4 }; > @@ -293,11 +313,8 @@ lm_base (void) > return lm_base_cache; > } > > - > -/* Implement the "current_sos" solib_ops method. */ > - > -static owning_intrusive_list > -frv_current_sos () > +owning_intrusive_list > +frv_solib_ops::current_sos () > { > bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ()); > CORE_ADDR lm_addr, mgot; > @@ -367,7 +384,7 @@ frv_current_sos () > break; > } > > - auto &sop = sos.emplace_back (frv_so_ops); > + auto &sop = sos.emplace_back (*this); > auto li = std::make_unique (); > li->map = loadmap; > li->got_value = got_addr; > @@ -414,8 +431,8 @@ static CORE_ADDR interp_text_sect_high; > static CORE_ADDR interp_plt_sect_low; > static CORE_ADDR interp_plt_sect_high; > > -static bool > -frv_in_dynsym_resolve_code (CORE_ADDR pc) > +bool > +frv_solib_ops::in_dynsym_resolve_code (CORE_ADDR pc) const > { > return ((pc >= interp_text_sect_low && pc < interp_text_sect_high) > || (pc >= interp_plt_sect_low && pc < interp_plt_sect_high) > @@ -776,8 +793,8 @@ frv_relocate_main_executable (void) > to be relocated. The shared library breakpoints also need to be > enabled. */ > > -static void > -frv_solib_create_inferior_hook (int from_tty) > +void > +frv_solib_ops::create_inferior_hook (int from_tty) > { > /* Relocate main executable. */ > frv_relocate_main_executable (); > @@ -790,8 +807,8 @@ frv_solib_create_inferior_hook (int from_tty) > } > } > > -static void > -frv_clear_solib (program_space *pspace) > +void > +frv_solib_ops::clear_solib (program_space *pspace) > { > lm_base_cache = 0; > enable_break2_done = 0; > @@ -801,8 +818,9 @@ frv_clear_solib (program_space *pspace) > main_executable_lm_info = NULL; > } > > -static void > -frv_relocate_section_addresses (solib &so, target_section *sec) > +void > +frv_solib_ops::relocate_section_addresses (solib &so, > + target_section *sec) const > { > int seg; > auto *li = gdb::checked_static_cast (so.lm_info.get ()); > @@ -1063,20 +1081,3 @@ frv_fetch_objfile_link_map (struct objfile *objfile) > /* Not found! */ > return 0; > } > - > -const solib_ops frv_so_ops = > -{ > - frv_relocate_section_addresses, > - nullptr, > - frv_clear_solib, > - frv_solib_create_inferior_hook, > - frv_current_sos, > - nullptr, > - frv_in_dynsym_resolve_code, > - solib_bfd_open, > - nullptr, > - nullptr, > - nullptr, > - nullptr, > - default_find_solib_addr, > -}; > diff --git a/gdb/solib-frv.h b/gdb/solib-frv.h > new file mode 100644 > index 000000000000..0f43b39cd3e5 > --- /dev/null > +++ b/gdb/solib-frv.h > @@ -0,0 +1,28 @@ > +/* Handle FR-V (FDPIC) shared libraries for GDB, the GNU Debugger. > + Copyright (C) 2024 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 GDB_SOLIB_FRV_H > +#define GDB_SOLIB_FRV_H > + > +#include "solib.h" > + > +/* Return a new solib_ops for FR-V systems. */ > + > +solib_ops_up new_frv_solib_ops (); > + > +#endif /* GDB_SOLIB_FRV_H */ > diff --git a/gdb/solib-rocm.c b/gdb/solib-rocm.c > index a3599562e795..ab7dc3e66808 100644 > --- a/gdb/solib-rocm.c > +++ b/gdb/solib-rocm.c > @@ -26,6 +26,7 @@ > #include "event-top.h" > #include "gdbsupport/fileio.h" > #include "inferior.h" > +#include "linux-tdep.h" > #include "observable.h" > #include "solib.h" > #include "solib-svr4.h" > @@ -153,7 +154,69 @@ struct solib_info > /* Per-inferior data key. */ > static const registry::key rocm_solib_data; > > -static solib_ops rocm_solib_ops; > +/* solib_ops for ROCm systems. */ > + > +struct rocm_solib_ops : public solib_ops > +{ > + /* HOST_OPS is the host solib_ops that rocm_solib_ops hijacks / wraps, > + in order to provide support for ROCm code objects. */ > + explicit rocm_solib_ops (solib_ops_up host_ops) > + : m_host_ops (std::move (host_ops)) > + { > + } > + > + /* The methods implemented by rocm_solib_ops. */ > + owning_intrusive_list current_sos () override; > + void create_inferior_hook (int from_tty) override; > + gdb_bfd_ref_ptr bfd_open (const char *pathname) override; > + void relocate_section_addresses (solib &so, target_section *) const override; > + void handle_event () override; > + > + /* Implement the following methods just to forward the calls to the host > + solib_ops. We currently need to implement all the methods that > + svr4_solib_ops implements. */ > + void clear_so (const solib &so) const override > + { return m_host_ops->clear_so (so); } > + > + void clear_solib (program_space *pspace) override > + { return m_host_ops->clear_solib (pspace); } > + > + bool open_symbol_file_object (int from_tty) override > + { return m_host_ops->open_symbol_file_object (from_tty); } > + > + bool in_dynsym_resolve_code (CORE_ADDR pc) const override > + { return m_host_ops->in_dynsym_resolve_code (pc); } > + > + bool same (const solib &gdb, const solib &inferior) const override > + { return m_host_ops->same (gdb, inferior); } > + > + bool keep_data_in_core (CORE_ADDR vaddr, unsigned long size) override > + { return m_host_ops->keep_data_in_core (vaddr, size); } > + > + void update_breakpoints () const override > + { return m_host_ops->update_breakpoints (); } > + > + std::optional find_solib_addr (solib &so) const override > + { return m_host_ops->find_solib_addr (so); } > + > + bool supports_namespaces () const override > + { return true; } > + > + int find_solib_ns (const solib &so) const override > + { return m_host_ops->find_solib_ns (so); } > + > + int num_active_namespaces () const override > + { return m_host_ops->num_active_namespaces (); } > + > + std::vector get_solibs_in_ns (int nsid) const override > + { return m_host_ops->get_solibs_in_ns (nsid); } > + > +private: > + owning_intrusive_list > + solibs_from_rocm_sos (const std::vector &sos); > + > + solib_ops_up m_host_ops; > +}; > > /* Fetch the solib_info data for INF. */ > > @@ -170,13 +233,13 @@ get_solib_info (inferior *inf) > > /* Relocate section addresses. */ > > -static void > -rocm_solib_relocate_section_addresses (solib &so, > - struct target_section *sec) > +void > +rocm_solib_ops::relocate_section_addresses (solib &so, > + struct target_section *sec) const > { > if (!is_amdgpu_arch (gdbarch_from_bfd (so.abfd.get ()))) > { > - svr4_so_ops.relocate_section_addresses (so, sec); > + m_host_ops->relocate_section_addresses (so, sec); > return; > } > > @@ -187,30 +250,30 @@ rocm_solib_relocate_section_addresses (solib &so, > > static void rocm_update_solib_list (); > > -static void > -rocm_solib_handle_event () > +void > +rocm_solib_ops::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, > + /* Since we sit on top of a host solib_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 (); > + m_host_ops->handle_event (); > > rocm_update_solib_list (); > } > > /* Create solib objects from rocm_so objects in SOS. */ > > -static owning_intrusive_list > -solibs_from_rocm_sos (const std::vector &sos) > +owning_intrusive_list > +rocm_solib_ops::solibs_from_rocm_sos (const std::vector &sos) > { > owning_intrusive_list dst; > > for (const rocm_so &so : sos) > { > - auto &newobj = dst.emplace_back (rocm_solib_ops); > + auto &newobj = dst.emplace_back (*this); > > newobj.lm_info = std::make_unique (*so.lm_info); > newobj.name = so.name; > @@ -223,11 +286,11 @@ solibs_from_rocm_sos (const std::vector &sos) > /* Build a list of `struct solib' objects describing the shared > objects currently loaded in the inferior. */ > > -static owning_intrusive_list > -rocm_solib_current_sos () > +owning_intrusive_list > +rocm_solib_ops::current_sos () > { > /* First, retrieve the host-side shared library list. */ > - owning_intrusive_list sos = svr4_so_ops.current_sos (); > + owning_intrusive_list sos = m_host_ops->current_sos (); > > /* Then, the device-side shared library list. */ > std::vector &dev_sos = get_solib_info (current_inferior ())->solib_list; > @@ -579,12 +642,12 @@ rocm_bfd_iovec_open (bfd *abfd, inferior *inferior) > } > } > > -static gdb_bfd_ref_ptr > -rocm_solib_bfd_open (const char *pathname) > +gdb_bfd_ref_ptr > +rocm_solib_ops::bfd_open (const char *pathname) > { > /* Handle regular files with SVR4 open. */ > if (strstr (pathname, "://") == nullptr) > - return svr4_so_ops.bfd_open (pathname); > + return m_host_ops->bfd_open (pathname); > > auto open = [] (bfd *nbfd) -> gdb_bfd_iovec_base * > { > @@ -668,12 +731,12 @@ rocm_solib_bfd_open (const char *pathname) > return abfd; > } > > -static void > -rocm_solib_create_inferior_hook (int from_tty) > +void > +rocm_solib_ops::create_inferior_hook (int from_tty) > { > get_solib_info (current_inferior ())->solib_list.clear (); > > - svr4_so_ops.solib_create_inferior_hook (from_tty); > + m_host_ops->create_inferior_hook (from_tty); > } > > static void > @@ -736,22 +799,6 @@ rocm_update_solib_list () > > sos.emplace_back (uri_bytes, std::move (unique_name), std::move (li)); > } > - > - 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 ()->arch (), &rocm_solib_ops); > - } > } > > static void > @@ -759,6 +806,10 @@ rocm_solib_target_inferior_created (inferior *inf) > { > get_solib_info (inf)->solib_list.clear (); > > + auto prev_ops = inf->pspace->release_solib_ops (); > + auto rocm_ops = std::make_unique (std::move (prev_ops)); > + inf->pspace->set_solib_ops (std::move (rocm_ops)); > + > rocm_update_solib_list (); > > /* Force GDB to reload the solibs. */ > @@ -766,6 +817,21 @@ rocm_solib_target_inferior_created (inferior *inf) > solib_add (nullptr, 0, auto_solib_add); > } > > +static void > +rocm_solib_target_inferior_execd (inferior *exec_inf, inferior *follow_inf) > +{ > + /* Engage the ROCm so_ops, but only if dbgapi is attached to the inferior > + (avoiding remote inferiors and core file debugging). */ > + if (get_amd_dbgapi_process_id (follow_inf) == AMD_DBGAPI_PROCESS_NONE) > + return; > + > + auto prev_ops = follow_inf->pspace->release_solib_ops (); > + auto rocm_ops = std::make_unique (std::move (prev_ops)); > + follow_inf->pspace->set_solib_ops (std::move (rocm_ops)); > + > + get_solib_info (exec_inf)->solib_list.clear (); > +} > + > /* -Wmissing-prototypes */ > extern initialize_file_ftype _initialize_rocm_solib; > > @@ -779,4 +845,8 @@ _initialize_rocm_solib () > (rocm_solib_target_inferior_created, > "solib-rocm", > { &get_amd_dbgapi_target_inferior_created_observer_token () }); > + > + gdb::observers::inferior_execd.attach > + (rocm_solib_target_inferior_execd, "solib-rocm", > + { &get_amd_dbgapi_target_inferior_execd_observer_token () }); > } > diff --git a/gdb/solib-svr4-linux.c b/gdb/solib-svr4-linux.c > new file mode 100644 > index 000000000000..c4bd8d89cfab > --- /dev/null > +++ b/gdb/solib-svr4-linux.c > @@ -0,0 +1,98 @@ > +/* Target-dependent code for GNU/Linux using SVR4-style libraries. > + > + Copyright (C) 2025 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 "solib-svr4-linux.h" > + > +/* See solib-svr4-linux.h. */ > + > +solib_ops_up > +new_linux_ilp32_svr4_solib_ops () > +{ > + return std::make_unique (); > +} > + > +/* See solib-svr4-linux.h. */ > + > +link_map_offsets * > +linux_ilp32_svr4_solib_ops::fetch_link_map_offsets () const > +{ > + static link_map_offsets lmo; > + static link_map_offsets *lmp = nullptr; > + > + if (lmp == nullptr) > + { > + lmp = &lmo; > + > + lmo.r_version_offset = 0; > + lmo.r_version_size = 4; > + lmo.r_map_offset = 4; > + lmo.r_brk_offset = 8; > + lmo.r_ldsomap_offset = -1; > + lmo.r_next_offset = 20; > + > + /* Everything we need is in the first 20 bytes. */ > + lmo.link_map_size = 20; > + lmo.l_addr_offset = 0; > + lmo.l_name_offset = 4; > + lmo.l_ld_offset = 8; > + lmo.l_next_offset = 12; > + lmo.l_prev_offset = 16; > + } > + > + return lmp; > +} > + > +/* See solib-svr4-linux.h. */ > + > +solib_ops_up > +new_linux_lp64_svr4_solib_ops () > +{ > + return std::make_unique (); > +} > + > +/* See linux-tdep.h. */ > + > +link_map_offsets * > +linux_lp64_svr4_solib_ops::fetch_link_map_offsets () const > +{ > + static link_map_offsets lmo; > + static link_map_offsets *lmp = nullptr; > + > + if (lmp == nullptr) > + { > + lmp = &lmo; > + > + lmo.r_version_offset = 0; > + lmo.r_version_size = 4; > + lmo.r_map_offset = 8; > + lmo.r_brk_offset = 16; > + lmo.r_ldsomap_offset = -1; > + lmo.r_next_offset = 40; > + > + /* Everything we need is in the first 40 bytes. */ > + lmo.link_map_size = 40; > + lmo.l_addr_offset = 0; > + lmo.l_name_offset = 8; > + lmo.l_ld_offset = 16; > + lmo.l_next_offset = 24; > + lmo.l_prev_offset = 32; > + } > + > + return lmp; > +} > diff --git a/gdb/solib-svr4-linux.h b/gdb/solib-svr4-linux.h > new file mode 100644 > index 000000000000..885785fdfcba > --- /dev/null > +++ b/gdb/solib-svr4-linux.h > @@ -0,0 +1,47 @@ > +/* Target-dependent code for GNU/Linux using SVR4-style libraries. > + > + Copyright (C) 2025 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 GDB_SOLIB_SVR4_LINUX_H > +#define GDB_SOLIB_SVR4_LINUX_H > + > +#include "solib-svr4.h" > + > +/* solib_ops for ILP32 Linux systems. */ > + > +struct linux_ilp32_svr4_solib_ops : public svr4_solib_ops > +{ > + link_map_offsets *fetch_link_map_offsets () const override; > +}; > + > +/* solib_ops for LP64 Linux systems. */ > + > +struct linux_lp64_svr4_solib_ops : public svr4_solib_ops > +{ > + link_map_offsets *fetch_link_map_offsets () const override; > +}; > + > +/* Return a new solib_ops for ILP32 Linux systems. */ > + > +extern solib_ops_up new_linux_ilp32_svr4_solib_ops (); > + > +/* Return a new solib_ops for LP64 Linux systems. */ > + > +extern solib_ops_up new_linux_lp64_svr4_solib_ops (); > + > +#endif /* GDB_SOLIB_SVR4_LINUX_H */ > diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c > index deefc2578599..e9430281bca0 100644 > --- a/gdb/solib-svr4.c > +++ b/gdb/solib-svr4.c > @@ -47,7 +47,6 @@ > > #include > > -static struct link_map_offsets *svr4_fetch_link_map_offsets (void); > static void svr4_relocate_main_executable (void); > static void probes_table_remove_objfile_probes (struct objfile *objfile); > static void svr4_iterate_over_objfiles_in_search_order > @@ -89,27 +88,6 @@ static const char * const main_name_list[] = > NULL > }; > > -/* What to do when a probe stop occurs. */ > - > -enum probe_action > -{ > - /* Something went seriously wrong. Stop using probes and > - revert to using the older interface. */ > - PROBES_INTERFACE_FAILED, > - > - /* No action is required. The shared object list is still > - valid. */ > - DO_NOTHING, > - > - /* The shared object list should be reloaded entirely. */ > - FULL_RELOAD, > - > - /* Attempt to incrementally update the shared object list. If > - the update fails or is not possible, fall back to reloading > - the list in full. */ > - UPDATE_OR_RELOAD, > -}; > - > /* A probe's name and its associated action. */ > > struct probe_info > @@ -184,8 +162,8 @@ svr4_same (const char *gdb_name, const char *inferior_name, > return gdb_lm_info.l_addr_inferior == inferior_lm_info.l_addr_inferior; > } > > -static int > -svr4_same (const solib &gdb, const solib &inferior) > +bool > +svr4_solib_ops::same (const solib &gdb, const solib &inferior) const > { > auto *lmg > = gdb::checked_static_cast (gdb.lm_info.get ()); > @@ -196,10 +174,10 @@ svr4_same (const solib &gdb, const solib &inferior) > inferior.original_name.c_str (), *lmg, *lmi); > } > > -static lm_info_svr4_up > -lm_info_read (CORE_ADDR lm_addr) > +lm_info_svr4_up > +svr4_solib_ops::read_lm_info (CORE_ADDR lm_addr) const > { > - struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); > + link_map_offsets *lmo = this->fetch_link_map_offsets (); > lm_info_svr4_up lm_info; > > gdb::byte_vector lm (lmo->link_map_size); > @@ -229,16 +207,16 @@ lm_info_read (CORE_ADDR lm_addr) > return lm_info; > } > > -static int > -has_lm_dynamic_from_link_map (void) > +int > +svr4_solib_ops::has_lm_dynamic_from_link_map () const > { > - struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); > + link_map_offsets *lmo = this->fetch_link_map_offsets (); > > return lmo->l_ld_offset >= 0; > } > > -static CORE_ADDR > -lm_addr_check (const solib &so, bfd *abfd) > +CORE_ADDR > +svr4_solib_ops::lm_addr_check (const solib &so, bfd *abfd) const > { > auto *li = gdb::checked_static_cast (so.lm_info.get ()); > > @@ -249,7 +227,7 @@ lm_addr_check (const solib &so, bfd *abfd) > > l_addr = li->l_addr_inferior; > > - if (! abfd || ! has_lm_dynamic_from_link_map ()) > + if (!abfd || !this->has_lm_dynamic_from_link_map ()) > goto set_addr; > > l_dynaddr = li->l_ld; > @@ -475,8 +453,8 @@ svr4_is_default_namespace (const svr4_info *info, CORE_ADDR debug_base) > > /* Free the probes table. */ > > -static void > -free_probes_table (struct svr4_info *info) > +void > +svr4_solib_ops::free_probes_table (svr4_info *info) const > { > info->probes_table.reset (nullptr); > } > @@ -820,10 +798,10 @@ elf_locate_base (void) > checking r_version for a known version number, or r_state for > RT_CONSISTENT. */ > > -static CORE_ADDR > -solib_svr4_r_map (CORE_ADDR debug_base) > +CORE_ADDR > +svr4_solib_ops::read_r_map (CORE_ADDR debug_base) const > { > - struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); > + link_map_offsets *lmo = this->fetch_link_map_offsets (); > type *ptr_type > = builtin_type (current_inferior ()->arch ())->builtin_data_ptr; > CORE_ADDR addr = 0; > @@ -843,10 +821,10 @@ solib_svr4_r_map (CORE_ADDR debug_base) > > /* Find r_brk from the inferior's debug base. */ > > -static CORE_ADDR > -solib_svr4_r_brk (struct svr4_info *info) > +CORE_ADDR > +svr4_solib_ops::find_r_brk (svr4_info *info) const > { > - struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); > + link_map_offsets *lmo = this->fetch_link_map_offsets (); > type *ptr_type > = builtin_type (current_inferior ()->arch ())->builtin_data_ptr; > > @@ -857,10 +835,10 @@ solib_svr4_r_brk (struct svr4_info *info) > /* Find the link map for the dynamic linker (if it is not in the > normal list of loaded shared objects). */ > > -static CORE_ADDR > -solib_svr4_r_ldsomap (struct svr4_info *info) > +CORE_ADDR > +svr4_solib_ops::find_r_ldsomap (svr4_info *info) const > { > - struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); > + link_map_offsets *lmo = this->fetch_link_map_offsets (); > type *ptr_type > = builtin_type (current_inferior ()->arch ())->builtin_data_ptr; > enum bfd_endian byte_order = type_byte_order (ptr_type); > @@ -888,10 +866,10 @@ solib_svr4_r_ldsomap (struct svr4_info *info) > > /* Find the next namespace from the r_next field. */ > > -static CORE_ADDR > -solib_svr4_r_next (CORE_ADDR debug_base) > +CORE_ADDR > +svr4_solib_ops::read_r_next (CORE_ADDR debug_base) const > { > - link_map_offsets *lmo = svr4_fetch_link_map_offsets (); > + link_map_offsets *lmo = this->fetch_link_map_offsets (); > type *ptr_type > = builtin_type (current_inferior ()->arch ())->builtin_data_ptr; > bfd_endian byte_order = type_byte_order (ptr_type); > @@ -923,8 +901,8 @@ solib_svr4_r_next (CORE_ADDR debug_base) > memory areas containing the l_name string are saved in the core > file. */ > > -static int > -svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size) > +bool > +svr4_solib_ops::keep_data_in_core (CORE_ADDR vaddr, unsigned long size) > { > struct svr4_info *info; > CORE_ADDR ldsomap; > @@ -934,13 +912,13 @@ svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size) > > info->debug_base = elf_locate_base (); > if (info->debug_base == 0) > - return 0; > + return false; > > - ldsomap = solib_svr4_r_ldsomap (info); > + ldsomap = this->find_r_ldsomap (info); > if (!ldsomap) > - return 0; > + return false; > > - std::unique_ptr li = lm_info_read (ldsomap); > + std::unique_ptr li = this->read_lm_info (ldsomap); > name_lm = li != NULL ? li->l_name : 0; > > return (name_lm >= vaddr && name_lm < vaddr + size); > @@ -948,11 +926,11 @@ svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size) > > /* See solib.h. */ > > -static int > -open_symbol_file_object (int from_tty) > +bool > +svr4_solib_ops::open_symbol_file_object (int from_tty) > { > CORE_ADDR lm, l_name; > - struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); > + link_map_offsets *lmo = this->fetch_link_map_offsets (); > type *ptr_type > = builtin_type (current_inferior ()->arch ())->builtin_data_ptr; > int l_name_size = ptr_type->length (); > @@ -965,17 +943,17 @@ open_symbol_file_object (int from_tty) > > if (current_program_space->symfile_object_file) > if (!query (_("Attempt to reload symbols from process? "))) > - return 0; > + return false; > > /* Always locate the debug struct, in case it has moved. */ > info->debug_base = elf_locate_base (); > if (info->debug_base == 0) > - return 0; /* failed somehow... */ > + return false; /* failed somehow... */ > > /* First link map member should be the executable. */ > - lm = solib_svr4_r_map (info->debug_base); > + lm = this->read_r_map (info->debug_base); > if (lm == 0) > - return 0; /* failed somehow... */ > + return false; /* failed somehow... */ > > /* Read address of name from target memory to GDB. */ > read_memory (lm + lmo->l_name_offset, l_name_buf.data (), l_name_size); > @@ -984,7 +962,7 @@ open_symbol_file_object (int from_tty) > l_name = extract_typed_address (l_name_buf.data (), ptr_type); > > if (l_name == 0) > - return 0; /* No filename. */ > + return false; /* No filename. */ > > /* Now fetch the filename from target memory. */ > gdb::unique_xmalloc_ptr filename > @@ -993,13 +971,13 @@ open_symbol_file_object (int from_tty) > if (filename == nullptr) > { > warning (_("failed to read exec filename from attached file")); > - return 0; > + return false; > } > > /* Have a pathname: read the symbol file. */ > symbol_file_add_main (filename.get (), add_flags); > > - return 1; > + return true; > } > > /* Data exchange structure for the XML parser as returned by > @@ -1032,8 +1010,8 @@ svr4_free_objfile_observer (struct objfile *objfile) > > /* Implement solib_ops.clear_so. */ > > -static void > -svr4_clear_so (const solib &so) > +void > +svr4_solib_ops::clear_so (const solib &so) const > { > auto *li = gdb::checked_static_cast (so.lm_info.get ()); > > @@ -1043,14 +1021,14 @@ svr4_clear_so (const solib &so) > > /* Create the solib objects equivalent to the svr4_sos in SOS. */ > > -static owning_intrusive_list > -solib_from_svr4_sos (const std::vector &sos) > +owning_intrusive_list > +svr4_solib_ops::solibs_from_svr4_sos (const std::vector &sos) > { > owning_intrusive_list dst; > > for (const svr4_so &so : sos) > { > - auto &newobj = dst.emplace_back (svr4_so_ops); > + auto &newobj = dst.emplace_back (*this); > > newobj.name = so.name; > newobj.original_name = so.name; > @@ -1237,8 +1215,8 @@ svr4_current_sos_via_xfer_libraries (struct svr4_library_list *list, > /* If no shared library information is available from the dynamic > linker, build a fallback list from other sources. */ > > -static owning_intrusive_list > -svr4_default_sos (svr4_info *info) > +owning_intrusive_list > +svr4_solib_ops::default_sos (svr4_info *info) > { > if (!info->debug_loader_offset_p) > return {}; > @@ -1250,7 +1228,7 @@ svr4_default_sos (svr4_info *info) > li->l_addr_p = 1; > > owning_intrusive_list sos; > - auto &newobj = sos.emplace_back (svr4_so_ops); > + auto &newobj = sos.emplace_back (*this); > > newobj.lm_info = std::move (li); > newobj.name = info->debug_loader_name; > @@ -1266,16 +1244,16 @@ svr4_default_sos (svr4_info *info) > is returned the entries stored to LINK_PTR_PTR are still valid although they may > represent only part of the inferior library list. */ > > -static int > -svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm, > - std::vector &sos, int ignore_first) > +int > +svr4_solib_ops::read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm, > + std::vector &sos, int ignore_first) const > { > CORE_ADDR first_l_name = 0; > CORE_ADDR next_lm; > > for (; lm != 0; prev_lm = lm, lm = next_lm) > { > - lm_info_svr4_up li = lm_info_read (lm); > + lm_info_svr4_up li = this->read_lm_info (lm); > if (li == NULL) > return 0; > > @@ -1331,8 +1309,8 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm, > stored by the probes interface. Handle special cases relating > to the first elements of the list in default namespace. */ > > -static void > -svr4_current_sos_direct (struct svr4_info *info) > +void > +svr4_solib_ops::current_sos_direct (svr4_info *info) const > { > CORE_ADDR lm; > bool ignore_first; > @@ -1398,15 +1376,15 @@ svr4_current_sos_direct (struct svr4_info *info) > /* Collect the sos in each namespace. */ > CORE_ADDR debug_base = info->debug_base; > for (; debug_base != 0; > - ignore_first = false, debug_base = solib_svr4_r_next (debug_base)) > + ignore_first = false, debug_base = this->read_r_next (debug_base)) > { > /* Walk the inferior's link map list, and build our so_list list. */ > - lm = solib_svr4_r_map (debug_base); > + lm = this->read_r_map (debug_base); > if (lm != 0) > { > svr4_maybe_add_namespace (info, debug_base); > - svr4_read_so_list (info, lm, 0, info->solib_lists[debug_base], > - ignore_first); > + this->read_so_list (info, lm, 0, info->solib_lists[debug_base], > + ignore_first); > } > } > > @@ -1419,15 +1397,15 @@ svr4_current_sos_direct (struct svr4_info *info) > r_debug object. If we added it to the default namespace (as it was), > we would probably run into inconsistencies with the load map's > prev/next links (I wonder if we did). */ > - debug_base = solib_svr4_r_ldsomap (info); > + debug_base = this->find_r_ldsomap (info); > if (debug_base != 0) > { > /* Add the dynamic linker's namespace unless we already did. */ > if (info->solib_lists.find (debug_base) == info->solib_lists.end ()) > { > svr4_maybe_add_namespace (info, debug_base); > - svr4_read_so_list (info, debug_base, 0, info->solib_lists[debug_base], > - 0); > + this->read_so_list (info, debug_base, 0, > + info->solib_lists[debug_base], 0); > } > } > > @@ -1436,15 +1414,15 @@ svr4_current_sos_direct (struct svr4_info *info) > > /* Collect sos read and stored by the probes interface. */ > > -static owning_intrusive_list > -svr4_collect_probes_sos (svr4_info *info) > +owning_intrusive_list > +svr4_solib_ops::collect_probes_sos (svr4_info *info) > { > owning_intrusive_list res; > > for (const auto &tuple : info->solib_lists) > { > const std::vector &sos = tuple.second; > - res.splice (solib_from_svr4_sos (sos)); > + res.splice (this->solibs_from_svr4_sos (sos)); > } > > return res; > @@ -1453,26 +1431,26 @@ svr4_collect_probes_sos (svr4_info *info) > /* Implement the main part of the "current_sos" solib_ops > method. */ > > -static owning_intrusive_list > -svr4_current_sos_1 (svr4_info *info) > +owning_intrusive_list > +svr4_solib_ops::current_sos_1 (svr4_info *info) > { > owning_intrusive_list sos; > > /* If we're using the probes interface, we can use the cache as it will > be maintained by probe update/reload actions. */ > if (info->probes_table != nullptr) > - sos = svr4_collect_probes_sos (info); > + sos = this->collect_probes_sos (info); > > /* If we're not using the probes interface or if we didn't cache > anything, read the sos to fill the cache, then collect them from the > cache. */ > if (sos.empty ()) > { > - svr4_current_sos_direct (info); > + this->current_sos_direct (info); > > - sos = svr4_collect_probes_sos (info); > + sos = this->collect_probes_sos (info); > if (sos.empty ()) > - sos = svr4_default_sos (info); > + sos = this->default_sos (info); > } > > return sos; > @@ -1480,11 +1458,11 @@ svr4_current_sos_1 (svr4_info *info) > > /* Implement the "current_sos" solib_ops method. */ > > -static owning_intrusive_list > -svr4_current_sos () > +owning_intrusive_list > +svr4_solib_ops::current_sos () > { > svr4_info *info = get_svr4_info (current_program_space); > - owning_intrusive_list sos = svr4_current_sos_1 (info); > + owning_intrusive_list sos = this->current_sos_1 (info); > struct mem_range vsyscall_range; > > /* Filter out the vDSO module, if present. Its symbol file would > @@ -1731,7 +1709,11 @@ tls_maybe_fill_slot (solib &so) > { > /* Cause svr4_current_sos() to be run if it hasn't been already. */ > if (info->main_lm_addr == 0) > - svr4_current_sos_direct (info); > + { > + auto &ops > + = gdb::checked_static_cast (so.ops ()); > + ops.current_sos_direct (info); > + } > > /* Quit early when main_lm_addr is still 0. */ > if (info->main_lm_addr == 0) > @@ -1802,7 +1784,7 @@ match_main (const char *soname) > SVR4 run time loader. */ > > bool > -svr4_in_dynsym_resolve_code (CORE_ADDR pc) > +svr4_solib_ops::in_dynsym_resolve_code (CORE_ADDR pc) const > { > struct svr4_info *info = get_svr4_info (current_program_space); > > @@ -2001,12 +1983,10 @@ solib_event_probe_action (struct probe_and_action *pa) > shared objects from the inferior. Handle special cases relating > to the first elements of the list. Returns nonzero on success. */ > > -static int > -solist_update_full (struct svr4_info *info) > +void > +svr4_solib_ops::update_full (svr4_info *info) const > { > - svr4_current_sos_direct (info); > - > - return 1; > + this->current_sos_direct (info); > } > > /* Update the shared object list starting from the link-map entry > @@ -2014,9 +1994,9 @@ solist_update_full (struct svr4_info *info) > nonzero if the list was successfully updated, or zero to indicate > failure. */ > > -static int > -solist_update_incremental (svr4_info *info, CORE_ADDR debug_base, > - CORE_ADDR lm) > +int > +svr4_solib_ops::update_incremental (svr4_info *info, CORE_ADDR debug_base, > + CORE_ADDR lm) const > { > /* Fall back to a full update if we are using a remote target > that does not support incremental transfers. */ > @@ -2094,7 +2074,7 @@ solist_update_incremental (svr4_info *info, CORE_ADDR debug_base, > above check and deferral to solist_update_full ensures > that this call to svr4_read_so_list will never see the > first element. */ > - if (!svr4_read_so_list (info, lm, prev_lm, solist, 0)) > + if (!this->read_so_list (info, lm, prev_lm, solist, 0)) > return 0; > } > > @@ -2105,8 +2085,8 @@ solist_update_incremental (svr4_info *info, CORE_ADDR debug_base, > original interface. We don't reset the breakpoints as the > ones set up for the probes-based interface are adequate. */ > > -static void > -disable_probes_interface (svr4_info *info) > +void > +svr4_solib_ops::disable_probes_interface (svr4_info *info) const > { > warning (_("Probes-based dynamic linker interface failed.\n" > "Reverting to original interface.")); > @@ -2121,8 +2101,8 @@ disable_probes_interface (svr4_info *info) > probes-based linker interface. Do nothing if using the > standard interface. */ > > -static void > -svr4_handle_solib_event (void) > +void > +svr4_solib_ops::handle_event () > { > struct svr4_info *info = get_svr4_info (current_program_space); > struct probe_and_action *pa; > @@ -2147,9 +2127,9 @@ svr4_handle_solib_event (void) > > /* If anything goes wrong we revert to the original linker > interface. */ > - auto cleanup = make_scope_exit ([info] () > + auto cleanup = make_scope_exit ([this, info] () > { > - disable_probes_interface (info); > + this->disable_probes_interface (info); > }); > > action = solib_event_probe_action (pa); > @@ -2251,15 +2231,12 @@ svr4_handle_solib_event (void) > > if (action == UPDATE_OR_RELOAD) > { > - if (!solist_update_incremental (info, debug_base, lm)) > + if (!this->update_incremental (info, debug_base, lm)) > action = FULL_RELOAD; > } > > if (action == FULL_RELOAD) > - { > - if (!solist_update_full (info)) > - return; > - } > + this->update_full (info); > > cleanup.release (); > } > @@ -2306,8 +2283,8 @@ svr4_update_solib_event_breakpoint (struct breakpoint *b) > /* Enable or disable optional solib event breakpoints as appropriate. > Called whenever stop_on_solib_events is changed. */ > > -static void > -svr4_update_solib_event_breakpoints (void) > +void > +svr4_solib_ops::update_breakpoints () const > { > for (breakpoint &bp : all_breakpoints_safe ()) > svr4_update_solib_event_breakpoint (&bp); > @@ -2318,10 +2295,10 @@ svr4_update_solib_event_breakpoints (void) > solib event breakpoint will be created and registered for each > probe. */ > > -static void > -svr4_create_probe_breakpoints (svr4_info *info, struct gdbarch *gdbarch, > - const std::vector *probes, > - struct objfile *objfile) > +void > +svr4_solib_ops::create_probe_breakpoints (svr4_info *info, gdbarch *gdbarch, > + const std::vector *probes, > + objfile *objfile) const > { > for (int i = 0; i < NUM_PROBES; i++) > { > @@ -2339,17 +2316,17 @@ svr4_create_probe_breakpoints (svr4_info *info, struct gdbarch *gdbarch, > } > } > > - svr4_update_solib_event_breakpoints (); > + this->update_breakpoints (); > } > > /* Find all the glibc named probes. Only if all of the probes are found, then > create them and return true. Otherwise return false. If WITH_PREFIX is set > then add "rtld" to the front of the probe names. */ > -static bool > -svr4_find_and_create_probe_breakpoints (svr4_info *info, > - struct gdbarch *gdbarch, > - struct obj_section *os, > - bool with_prefix) > +bool > +svr4_solib_ops::find_and_create_probe_breakpoints (svr4_info *info, > + gdbarch *gdbarch, > + obj_section *os, > + bool with_prefix) const > { > SOLIB_SCOPED_DEBUG_START_END ("objfile=%s, with_prefix=%d", > os->objfile->original_name, with_prefix); > @@ -2427,7 +2404,7 @@ svr4_find_and_create_probe_breakpoints (svr4_info *info, > > /* All probes found. Now create them. */ > solib_debug_printf ("using probes interface"); > - svr4_create_probe_breakpoints (info, gdbarch, probes, os->objfile); > + this->create_probe_breakpoints (info, gdbarch, probes, os->objfile); > return true; > } > > @@ -2443,15 +2420,16 @@ svr4_find_and_create_probe_breakpoints (svr4_info *info, > probes aren't found, a single breakpoint is set on the original > marker function. */ > > -static void > -svr4_create_solib_event_breakpoints (svr4_info *info, struct gdbarch *gdbarch, > - CORE_ADDR address) > +void > +svr4_solib_ops::create_event_breakpoints (svr4_info *info, gdbarch *gdbarch, > + CORE_ADDR address) const > { > struct obj_section *os = find_pc_section (address); > > if (os == nullptr > - || (!svr4_find_and_create_probe_breakpoints (info, gdbarch, os, false) > - && !svr4_find_and_create_probe_breakpoints (info, gdbarch, os, true))) > + || (!this->find_and_create_probe_breakpoints (info, gdbarch, os, false) > + && !this->find_and_create_probe_breakpoints (info, gdbarch, os, > + true))) > { > solib_debug_printf ("falling back to r_brk breakpoint: addr=%s", > paddress (gdbarch, address)); > @@ -2491,8 +2469,8 @@ svr4_create_solib_event_breakpoints (svr4_info *info, struct gdbarch *gdbarch, > depending upon whether or not the library is being mapped or unmapped, > and then set to RT_CONSISTENT after the library is mapped/unmapped. */ > > -static int > -enable_break (struct svr4_info *info, int from_tty) > +int > +svr4_solib_ops::enable_break (svr4_info *info, int from_tty) const > { > const char * const *bkpt_namep; > asection *interp_sect; > @@ -2508,8 +2486,8 @@ enable_break (struct svr4_info *info, int from_tty) > > solib_add (NULL, from_tty, auto_solib_add); > sym_addr = 0; > - if (info->debug_base && solib_svr4_r_map (info->debug_base) != 0) > - sym_addr = solib_svr4_r_brk (info); > + if (info->debug_base && this->read_r_map (info->debug_base) != 0) > + sym_addr = this->find_r_brk (info); > > if (sym_addr != 0) > { > @@ -2568,8 +2546,8 @@ enable_break (struct svr4_info *info, int from_tty) > = info->interp_plt_sect_low + bfd_section_size (interp_sect); > } > > - svr4_create_solib_event_breakpoints > - (info, current_inferior ()->arch (), sym_addr); > + this->create_event_breakpoints (info, current_inferior ()->arch (), > + sym_addr); > return 1; > } > } > @@ -2621,7 +2599,7 @@ enable_break (struct svr4_info *info, int from_tty) > { > load_addr_found = 1; > loader_found_in_list = 1; > - load_addr = lm_addr_check (so, tmp_bfd.get ()); > + load_addr = this->lm_addr_check (so, tmp_bfd.get ()); > break; > } > } > @@ -2728,9 +2706,8 @@ enable_break (struct svr4_info *info, int from_tty) > > if (sym_addr != 0) > { > - svr4_create_solib_event_breakpoints (info, > - current_inferior ()->arch (), > - load_addr + sym_addr); > + this->create_event_breakpoints (info, current_inferior ()->arch (), > + load_addr + sym_addr); > return 1; > } > > @@ -2757,9 +2734,8 @@ enable_break (struct svr4_info *info, int from_tty) > sym_addr = gdbarch_convert_from_func_ptr_addr > (current_inferior ()->arch (), sym_addr, > current_inferior ()->top_target ()); > - svr4_create_solib_event_breakpoints (info, > - current_inferior ()->arch (), > - sym_addr); > + this->create_event_breakpoints (info, current_inferior ()->arch (), > + sym_addr); > return 1; > } > } > @@ -2777,8 +2753,9 @@ enable_break (struct svr4_info *info, int from_tty) > sym_addr = gdbarch_convert_from_func_ptr_addr > (current_inferior ()->arch (), sym_addr, > current_inferior ()->top_target ()); > - svr4_create_solib_event_breakpoints > - (info, current_inferior ()->arch (), sym_addr); > + this->create_event_breakpoints (info, > + current_inferior ()->arch (), > + sym_addr); > return 1; > } > } > @@ -3302,15 +3279,15 @@ svr4_relocate_main_executable (void) > addresses, and saving sufficient information about them to allow > their symbols to be read at a later time. */ > > -static void > -svr4_solib_create_inferior_hook (int from_tty) > +void > +svr4_solib_ops::create_inferior_hook (int from_tty) > { > struct svr4_info *info; > > info = get_svr4_info (current_program_space); > > /* Clear the probes-based interface's state. */ > - free_probes_table (info); > + this->free_probes_table (info); > info->solib_lists.clear (); > info->namespace_id.clear (); > info->active_namespaces.clear (); > @@ -3323,12 +3300,12 @@ svr4_solib_create_inferior_hook (int from_tty) > if (!target_has_execution ()) > return; > > - if (!enable_break (info, from_tty)) > + if (!this->enable_break (info, from_tty)) > return; > } > > -static void > -svr4_clear_solib (program_space *pspace) > +void > +svr4_solib_ops::clear_solib (program_space *pspace) > { > svr4_info *info = get_svr4_info (pspace); > info->debug_base = 0; > @@ -3391,15 +3368,15 @@ find_loadable_elf_internal_phdr (bfd *abfd, bfd_section *asect) > return nullptr; > } > > -/* Implement solib_ops::relocate_section_addresses() for svr4 targets. */ > - > -static void > -svr4_relocate_section_addresses (solib &so, target_section *sec) > +void > +svr4_solib_ops::relocate_section_addresses (solib &so, > + target_section *sec) const > { > bfd *abfd = sec->the_bfd_section->owner; > > - sec->addr = svr4_truncate_ptr (sec->addr + lm_addr_check (so, abfd)); > - sec->endaddr = svr4_truncate_ptr (sec->endaddr + lm_addr_check (so, abfd)); > + sec->addr = svr4_truncate_ptr (sec->addr + this->lm_addr_check (so, abfd)); > + sec->endaddr > + = svr4_truncate_ptr (sec->endaddr + this->lm_addr_check (so, abfd)); > > struct bfd_section *asect = sec->the_bfd_section; > gdb_assert (asect != nullptr); > @@ -3469,56 +3446,23 @@ svr4_relocate_section_addresses (solib &so, target_section *sec) > } > } > } > - > > -/* Architecture-specific operations. */ > - > -struct solib_svr4_ops > -{ > - /* Return a description of the layout of `struct link_map'. */ > - struct link_map_offsets *(*fetch_link_map_offsets)(void) = nullptr; > -}; > - > -/* Per-architecture data key. */ > -static const registry::key solib_svr4_data; > - > -/* Return a default for the architecture-specific operations. */ > - > -static struct solib_svr4_ops * > -get_ops (struct gdbarch *gdbarch) > -{ > - struct solib_svr4_ops *ops = solib_svr4_data.get (gdbarch); > - if (ops == nullptr) > - ops = solib_svr4_data.emplace (gdbarch); > - return ops; > -} > - > -/* Set the architecture-specific `struct link_map_offsets' fetcher for > - GDBARCH to FLMO. Also, install SVR4 solib_ops into GDBARCH. */ > +/* See solib-svr4.h. */ > > void > -set_solib_svr4_fetch_link_map_offsets (struct gdbarch *gdbarch, > - struct link_map_offsets *(*flmo) (void)) > +set_solib_svr4_ops (gdbarch *gdbarch, gdbarch_new_solib_ops_ftype new_solib_ops) > { > - struct solib_svr4_ops *ops = get_ops (gdbarch); > - > - ops->fetch_link_map_offsets = flmo; > - > - set_gdbarch_so_ops (gdbarch, &svr4_so_ops); > + set_gdbarch_new_solib_ops (gdbarch, new_solib_ops); > set_gdbarch_iterate_over_objfiles_in_search_order > (gdbarch, svr4_iterate_over_objfiles_in_search_order); > } > > -/* Fetch a link_map_offsets structure using the architecture-specific > - `struct link_map_offsets' fetcher. */ > +/* See solib-svr4.h. */ > > -static struct link_map_offsets * > -svr4_fetch_link_map_offsets (void) > +solib_ops_up > +new_svr4_ilp32_solib_ops () > { > - struct solib_svr4_ops *ops = get_ops (current_inferior ()->arch ()); > - > - gdb_assert (ops->fetch_link_map_offsets); > - return ops->fetch_link_map_offsets (); > + return std::make_unique (); > } > > /* Most OS'es that have SVR4-style ELF dynamic libraries define a > @@ -3528,8 +3472,8 @@ svr4_fetch_link_map_offsets (void) > /* Fetch (and possibly build) an appropriate `struct link_map_offsets' > for an ILP32 SVR4 system. */ > > -struct link_map_offsets * > -svr4_ilp32_fetch_link_map_offsets (void) > +link_map_offsets * > +ilp32_svr4_solib_ops::fetch_link_map_offsets () const > { > static struct link_map_offsets lmo; > static struct link_map_offsets *lmp = NULL; > @@ -3557,11 +3501,26 @@ svr4_ilp32_fetch_link_map_offsets (void) > return lmp; > } > > +/* solib_ops for LP64 SVR4 systems. */ > + > +struct lp64_svr4_solib_ops : public svr4_solib_ops > +{ > + link_map_offsets *fetch_link_map_offsets () const override; > +}; > + > +/* See solib-svr4.h. */ > + > +solib_ops_up > +new_svr4_lp64_solib_ops () > +{ > + return std::make_unique (); > +} > + > /* Fetch (and possibly build) an appropriate `struct link_map_offsets' > for an LP64 SVR4 system. */ > > -struct link_map_offsets * > -svr4_lp64_fetch_link_map_offsets (void) > +link_map_offsets * > +lp64_svr4_solib_ops::fetch_link_map_offsets () const > { > static struct link_map_offsets lmo; > static struct link_map_offsets *lmp = NULL; > @@ -3708,19 +3667,15 @@ svr4_iterate_over_objfiles_in_search_order > } > } > > -/* See solib_ops::find_solib_addr in solist.h. */ > - > -static std::optional > -svr4_find_solib_addr (solib &so) > +std::optional > +svr4_solib_ops::find_solib_addr (solib &so) const > { > auto *li = gdb::checked_static_cast (so.lm_info.get ()); > return li->l_addr_inferior; > } > > -/* See solib_ops::find_solib_ns in solist.h. */ > - > -static int > -svr4_find_solib_ns (const solib &so) > +int > +svr4_solib_ops::find_solib_ns (const solib &so) const > { > CORE_ADDR debug_base = find_debug_base_for_solib (&so); > svr4_info *info = get_svr4_info (current_program_space); > @@ -3735,17 +3690,15 @@ svr4_find_solib_ns (const solib &so) > error (_("No namespace found")); > } > > -/* see solib_ops::num_active_namespaces in solist.h. */ > -static int > -svr4_num_active_namespaces () > +int > +svr4_solib_ops::num_active_namespaces () const > { > svr4_info *info = get_svr4_info (current_program_space); > return info->active_namespaces.size (); > } > > -/* See solib_ops::get_solibs_in_ns in solist.h. */ > -static std::vector > -svr4_get_solibs_in_ns (int nsid) > +std::vector > +svr4_solib_ops::get_solibs_in_ns (int nsid) const > { > std::vector ns_solibs; > svr4_info *info = get_svr4_info (current_program_space); > @@ -3791,26 +3744,6 @@ svr4_get_solibs_in_ns (int nsid) > return ns_solibs; > } > > -const struct solib_ops svr4_so_ops = > -{ > - svr4_relocate_section_addresses, > - svr4_clear_so, > - svr4_clear_solib, > - svr4_solib_create_inferior_hook, > - svr4_current_sos, > - open_symbol_file_object, > - svr4_in_dynsym_resolve_code, > - solib_bfd_open, > - svr4_same, > - svr4_keep_data_in_core, > - svr4_update_solib_event_breakpoints, > - svr4_handle_solib_event, > - svr4_find_solib_addr, > - svr4_find_solib_ns, > - svr4_num_active_namespaces, > - svr4_get_solibs_in_ns, > -}; > - > void _initialize_svr4_solib (); > void > _initialize_svr4_solib () > diff --git a/gdb/solib-svr4.h b/gdb/solib-svr4.h > index 1ff9be78a43d..a7be4c902e75 100644 > --- a/gdb/solib-svr4.h > +++ b/gdb/solib-svr4.h > @@ -20,12 +20,15 @@ > #ifndef GDB_SOLIB_SVR4_H > #define GDB_SOLIB_SVR4_H > > +#include "gdbarch.h" > #include "solib.h" > > struct objfile; > -struct solib_ops; > - > -extern const solib_ops svr4_so_ops; > +struct link_map_offsets; > +struct probe_and_action; > +struct svr4_info; > +struct svr4_library_list; > +struct svr4_so; > > /* Link map info to include in an allocated solib entry. */ > > @@ -50,6 +53,101 @@ struct lm_info_svr4 final : public lm_info > > using lm_info_svr4_up = std::unique_ptr; > > +/* What to do when a probe stop occurs. */ > + > +enum probe_action > +{ > + /* Something went seriously wrong. Stop using probes and > + revert to using the older interface. */ > + PROBES_INTERFACE_FAILED, > + > + /* No action is required. The shared object list is still > + valid. */ > + DO_NOTHING, > + > + /* The shared object list should be reloaded entirely. */ > + FULL_RELOAD, > + > + /* Attempt to incrementally update the shared object list. If > + the update fails or is not possible, fall back to reloading > + the list in full. */ > + UPDATE_OR_RELOAD, > +}; > + > +/* solib_ops for SVR4 systems. */ > + > +struct svr4_solib_ops : public solib_ops > +{ > + void relocate_section_addresses (solib &so, target_section *) const override; > + void clear_so (const solib &so) const override; > + void clear_solib (program_space *pspace) override; > + void create_inferior_hook (int from_tty) override; > + owning_intrusive_list current_sos () override; > + bool open_symbol_file_object (int from_tty) override; > + bool in_dynsym_resolve_code (CORE_ADDR pc) const override; > + bool same (const solib &gdb, const solib &inferior) const override; > + bool keep_data_in_core (CORE_ADDR vaddr, unsigned long size) override; > + void update_breakpoints () const override; > + void handle_event () override; > + std::optional find_solib_addr (solib &so) const override; > + bool supports_namespaces () const override { return true; } > + int find_solib_ns (const solib &so) const override; > + int num_active_namespaces () const override; > + std::vector get_solibs_in_ns (int nsid) const override; > + > + /* Return the appropriate link map offsets table for the architecture. */ > + virtual link_map_offsets *fetch_link_map_offsets () const = 0; > + > + /* This needs to be public because it's accessed from an observer. */ > + void current_sos_direct (svr4_info *info) const; > + > +private: > + void create_probe_breakpoints (svr4_info *info, gdbarch *gdbarch, > + const std::vector *probes, > + objfile *objfile) const; > + bool find_and_create_probe_breakpoints (svr4_info *info, gdbarch *gdbarch, > + obj_section *os, > + bool with_prefix) const; > + void create_event_breakpoints (svr4_info *info, gdbarch *gdbarch, > + CORE_ADDR address) const; > + int enable_break (svr4_info *info, int from_tty) const; > + bool is_default_namespace (CORE_ADDR debug_base) const; > + void free_probes_table (svr4_info *info) const; > + CORE_ADDR find_r_brk (svr4_info *info) const; > + CORE_ADDR find_r_ldsomap (svr4_info *info) const; > + owning_intrusive_list default_sos (svr4_info *info); > + int read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm, > + std::vector &sos, int ignore_first) const; > + lm_info_svr4_up read_lm_info (CORE_ADDR lm_addr) const; > + int has_lm_dynamic_from_link_map () const; > + CORE_ADDR lm_addr_check (const solib &so, bfd *abfd) const; > + CORE_ADDR read_r_next (CORE_ADDR debug_base) const; > + CORE_ADDR read_r_map (CORE_ADDR debug_base) const; > + int parse_libraries (const char *document, svr4_library_list *list); > + int current_sos_via_xfer_libraries (svr4_library_list *list, > + const char *annex) const; > + owning_intrusive_list collect_probes_sos (svr4_info *info); > + owning_intrusive_list current_sos_1 (svr4_info *info); > + owning_intrusive_list solibs_from_svr4_sos > + (const std::vector &sos); > + void register_event_probe (objfile *objfile, probe *prob, CORE_ADDR address, > + enum probe_action action) const; > + void disable_probes_interface (svr4_info *info) const; > + probe_and_action *event_probe_at (CORE_ADDR address) const; > + void update_full (svr4_info *info) const; > + int update_incremental (svr4_info *info, CORE_ADDR debug_base, > + CORE_ADDR lm) const; > + bool update_event_breakpoint (breakpoint *b) const; > + CORE_ADDR find_debug_base (const solib *solib) const; > +}; > + > +/* solib_ops for ILP32 SVR4 systems. */ > + > +struct ilp32_svr4_solib_ops : public svr4_solib_ops > +{ > + link_map_offsets *fetch_link_map_offsets () const override; > +}; > + > /* Critical offsets and sizes which describe struct r_debug and > struct link_map on SVR4-like targets. All offsets and sizes are > in bytes unless otherwise specified. */ > @@ -91,26 +189,22 @@ struct link_map_offsets > int l_name_offset; > }; > > -/* set_solib_svr4_fetch_link_map_offsets() is intended to be called by > - a _gdbarch_init() function. It is used to establish an > - architecture specific link_map_offsets fetcher for the architecture > - being defined. */ > +/* Set the gdbarch methods for SVR4 systems. */ > > -extern void set_solib_svr4_fetch_link_map_offsets > - (struct gdbarch *gdbarch, struct link_map_offsets *(*func) (void)); > +extern void set_solib_svr4_ops (gdbarch *gdbarch, > + gdbarch_new_solib_ops_ftype new_solib_ops); > > /* This function is called by thread_db.c. Return the address of the > link map for the given objfile. */ > extern CORE_ADDR svr4_fetch_objfile_link_map (struct objfile *objfile); > > -/* Fetch (and possibly build) an appropriate `struct link_map_offsets' > - for ILP32 and LP64 SVR4 systems. */ > -extern struct link_map_offsets *svr4_ilp32_fetch_link_map_offsets (void); > -extern struct link_map_offsets *svr4_lp64_fetch_link_map_offsets (void); > +/* Return a new solib_ops for ILP32 SVR4 systems. */ > > -/* Return true if PC lies in the dynamic symbol resolution code of the > - SVR4 run time loader. */ > -bool svr4_in_dynsym_resolve_code (CORE_ADDR pc); > +extern solib_ops_up new_svr4_ilp32_solib_ops (); > + > +/* Return a new solib_ops for LP64 SVR4 systems. */ > + > +extern solib_ops_up new_svr4_lp64_solib_ops (); > > /* For the MUSL C library, given link map address LM_ADDR, return the > corresponding TLS module id, or 0 if not found. */ > diff --git a/gdb/solib-target.c b/gdb/solib-target.c > index 61b841928ff8..5b26f5be34a8 100644 > --- a/gdb/solib-target.c > +++ b/gdb/solib-target.c > @@ -209,6 +209,14 @@ static const struct gdb_xml_element library_list_elements[] = { > { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } > }; > > +/* See solib-target.h. */ > + > +solib_ops_up > +new_target_solib_ops () > +{ > + return std::make_unique (); > +} > + > static std::vector > solib_target_parse_libraries (const char *library) > { > @@ -226,8 +234,8 @@ solib_target_parse_libraries (const char *library) > } > #endif > > -static owning_intrusive_list > -solib_target_current_sos (void) > +owning_intrusive_list > +target_solib_ops::current_sos () > { > owning_intrusive_list sos; > > @@ -245,7 +253,7 @@ solib_target_current_sos (void) > /* Build a struct solib for each entry on the list. */ > for (lm_info_target_up &info : library_list) > { > - auto &new_solib = sos.emplace_back (solib_target_so_ops); > + auto &new_solib = sos.emplace_back (*this); > > /* We don't need a copy of the name in INFO anymore. */ > new_solib.name = std::move (info->name); > @@ -256,8 +264,9 @@ solib_target_current_sos (void) > return sos; > } > > -static void > -solib_target_relocate_section_addresses (solib &so, target_section *sec) > +void > +target_solib_ops::relocate_section_addresses (solib &so, > + target_section *sec) const > { > CORE_ADDR offset; > auto *li = gdb::checked_static_cast (so.lm_info.get ()); > @@ -376,28 +385,11 @@ Could not relocate shared library \"%s\": bad offsets"), so.name.c_str ()); > sec->endaddr += offset; > } > > -static bool > -solib_target_in_dynsym_resolve_code (CORE_ADDR pc) > +bool > +target_solib_ops::in_dynsym_resolve_code (CORE_ADDR pc) const > { > /* We don't have a range of addresses for the dynamic linker; there > may not be one in the program's address space. So only report > PLT entries (which may be import stubs). */ > return in_plt_section (pc); > } > - > -const solib_ops solib_target_so_ops = > -{ > - solib_target_relocate_section_addresses, > - nullptr, > - nullptr, > - nullptr, > - solib_target_current_sos, > - nullptr, > - solib_target_in_dynsym_resolve_code, > - solib_bfd_open, > - nullptr, > - nullptr, > - nullptr, > - nullptr, > - default_find_solib_addr, > -}; > diff --git a/gdb/solib-target.h b/gdb/solib-target.h > index f8a22fd6f6ad..8a5f8432345b 100644 > --- a/gdb/solib-target.h > +++ b/gdb/solib-target.h > @@ -20,7 +20,19 @@ > #ifndef GDB_SOLIB_TARGET_H > #define GDB_SOLIB_TARGET_H > > -struct solib_ops; > -extern const solib_ops solib_target_so_ops; > +#include "solib.h" > + > +/* solib_ops for systems fetching solibs from the target. */ > + > +struct target_solib_ops : solib_ops > +{ > + void relocate_section_addresses (solib &so, target_section *) const override; > + owning_intrusive_list current_sos () override; > + bool in_dynsym_resolve_code (CORE_ADDR pc) const override; > +}; > + > +/* Return a new solib_ops for systems fetching solibs from the target. */ > + > +solib_ops_up new_target_solib_ops (); > > #endif /* GDB_SOLIB_TARGET_H */ > diff --git a/gdb/solib.c b/gdb/solib.c > index dceab2b865bf..c0e5f803882a 100644 > --- a/gdb/solib.c > +++ b/gdb/solib.c > @@ -467,6 +467,12 @@ solib_bfd_open (const char *pathname) > return abfd; > } > > +gdb_bfd_ref_ptr > +solib_ops::bfd_open (const char *pathname) > +{ > + return solib_bfd_open (pathname); > +} > + > /* Given a pointer to one of the shared objects in our list of mapped > objects, use the recorded name to open a bfd descriptor for the > object, build a section table, relocate all the section addresses > @@ -598,8 +604,7 @@ solib::clear () > this->name = this->original_name; > > /* Do the same for target-specific data. */ > - if (this->ops ().clear_so != NULL) > - this->ops ().clear_so (*this); > + this->ops ().clear_so (*this); > } > > lm_info::~lm_info () = default; > @@ -707,7 +712,7 @@ notify_solib_unloaded (program_space *pspace, const solib &so, > void > update_solib_list (int from_tty) > { > - const solib_ops *ops = current_program_space->solib_ops (); > + solib_ops *ops = current_program_space->solib_ops (); > > if (ops == nullptr) > return; > @@ -722,8 +727,7 @@ update_solib_list (int from_tty) > have not opened a symbol file, we may be able to get its > symbols now! */ > if (inf->attach_flag > - && current_program_space->symfile_object_file == nullptr > - && ops->open_symbol_file_object != nullptr) > + && current_program_space->symfile_object_file == nullptr) > { > try > { > @@ -772,19 +776,8 @@ update_solib_list (int from_tty) > /* Check to see whether the shared object *gdb also appears in > the inferior's current list. */ > for (; inferior_iter != inferior.end (); ++inferior_iter) > - { > - if (ops->same) > - { > - if (ops->same (*gdb_iter, *inferior_iter)) > - break; > - } > - else > - { > - if (!filename_cmp (gdb_iter->original_name.c_str (), > - inferior_iter->original_name.c_str ())) > - break; > - } > - } > + if (ops->same (*gdb_iter, *inferior_iter)) > + break; > > /* If the shared object appears on the inferior's list too, then > it's still loaded, so we don't need to do anything. Delete > @@ -1032,8 +1025,8 @@ print_solib_list_table (std::vector solib_list, > first PRINT_NAMESPACE has to be true, second the solib_ops has to > support multiple namespaces, and third there must be more than one > active namespace. Fold all these into the PRINT_NAMESPACE condition. */ > - print_namespace = print_namespace && ops->num_active_namespaces != nullptr > - && ops->num_active_namespaces () > 1; > + print_namespace = (print_namespace && ops->supports_namespaces () > + && ops->num_active_namespaces () > 1); > > int num_cols = 4; > if (print_namespace) > @@ -1162,7 +1155,7 @@ info_linker_namespace_command (const char *pattern, int from_tty) > > /* This command only really makes sense for inferiors that support > linker namespaces, so we can leave early. */ > - if (ops->num_active_namespaces == nullptr) > + if (!ops->supports_namespaces ()) > error (_("Current inferior does not support linker namespaces." \ > "Use \"info sharedlibrary\" instead")); > > @@ -1272,17 +1265,21 @@ solib_name_from_address (struct program_space *pspace, CORE_ADDR address) > return nullptr; > } > > +bool > +solib_ops::same (const solib &a, const solib &b) const > +{ > + return (filename_cmp (a.original_name.c_str (), b.original_name.c_str ()) > + == 0); > +} > + > /* See solib.h. */ > > bool > solib_keep_data_in_core (CORE_ADDR vaddr, unsigned long size) > { > - const solib_ops *ops = current_program_space->solib_ops (); > + solib_ops *ops = current_program_space->solib_ops (); > > - if (ops != nullptr && ops->keep_data_in_core != nullptr) > - return ops->keep_data_in_core (vaddr, size) != 0; > - else > - return false; > + return ops != nullptr && ops->keep_data_in_core (vaddr, size); > } > > /* See solib.h. */ > @@ -1301,9 +1298,8 @@ clear_solib (program_space *pspace) > > pspace->solibs ().clear (); > > - const solib_ops *ops = pspace->solib_ops (); > - > - if (ops != nullptr && ops->clear_solib != nullptr) > + if (solib_ops *ops = pspace->solib_ops (); > + ops != nullptr) > ops->clear_solib (pspace); > } > > @@ -1315,10 +1311,9 @@ clear_solib (program_space *pspace) > void > solib_create_inferior_hook (int from_tty) > { > - const solib_ops *ops = current_program_space->solib_ops (); > - > - if (ops != nullptr && ops->solib_create_inferior_hook != nullptr) > - ops->solib_create_inferior_hook (from_tty); > + if (solib_ops *ops = current_program_space->solib_ops (); > + ops != nullptr) > + ops->create_inferior_hook (from_tty); > } > > /* See solib.h. */ > @@ -1328,8 +1323,7 @@ in_solib_dynsym_resolve_code (CORE_ADDR pc) > { > const solib_ops *ops = current_program_space->solib_ops (); > > - return (ops != nullptr && ops->in_dynsym_resolve_code != nullptr > - && ops->in_dynsym_resolve_code (pc)); > + return ops != nullptr && ops->in_dynsym_resolve_code (pc); > } > > /* Implements the "sharedlibrary" command. */ > @@ -1373,7 +1367,7 @@ update_solib_breakpoints (void) > { > const solib_ops *ops = current_program_space->solib_ops (); > > - if (ops != nullptr && ops->update_breakpoints != nullptr) > + if (ops != nullptr) > ops->update_breakpoints (); > } > > @@ -1382,9 +1376,8 @@ update_solib_breakpoints (void) > void > handle_solib_event (void) > { > - const solib_ops *ops = current_program_space->solib_ops (); > - > - if (ops != nullptr && ops->handle_event != nullptr) > + if (solib_ops *ops = current_program_space->solib_ops (); > + ops != nullptr) > ops->handle_event (); > > current_inferior ()->pspace->clear_solib_cache (); > @@ -1417,7 +1410,8 @@ reload_shared_libraries_1 (int from_tty) > > gdb::unique_xmalloc_ptr filename ( > tilde_expand (so.original_name.c_str ())); > - gdb_bfd_ref_ptr abfd (solib_bfd_open (filename.get ())); > + > + gdb_bfd_ref_ptr abfd = so.ops ().bfd_open (filename.get ()); > if (abfd != NULL) > found_pathname = bfd_get_filename (abfd.get ()); > > @@ -1479,11 +1473,10 @@ reload_shared_libraries (const char *ignored, int from_tty, > about ld.so. */ > if (target_has_execution ()) > { > - const solib_ops *ops = current_program_space->solib_ops (); > - > /* Reset or free private data structures not associated with > solib entries. */ > - if (ops != nullptr && ops->clear_solib != nullptr) > + if (solib_ops *ops = current_program_space->solib_ops (); > + ops != nullptr) > ops->clear_solib (current_program_space); > > /* Remove any previous solib event breakpoint. This is usually > @@ -1810,15 +1803,8 @@ remove_user_added_objfile (struct objfile *objfile) > } > } > > -/* See solist.h. */ > - > -std::optional > -default_find_solib_addr (solib &so) > -{ > - return {}; > -} > - > /* Implementation of the linker_namespace convenience variable. > + > This returns the GDB internal identifier of the linker namespace, > for the selected frame, as an integer. If the inferior doesn't support > linker namespaces, this always returns 0. */ > @@ -1833,7 +1819,7 @@ linker_namespace_make_value (gdbarch *gdbarch, internalvar *var, > for (const solib &so : current_program_space->solibs ()) > if (solib_contains_address_p (so, curr_pc)) > { > - if (so.ops ().find_solib_ns != nullptr) > + if (so.ops ().supports_namespaces ()) > nsid = so.ops ().find_solib_ns (so); > > break; > diff --git a/gdb/solib.h b/gdb/solib.h > index 09d56c08b953..a3104e47e40e 100644 > --- a/gdb/solib.h > +++ b/gdb/solib.h > @@ -61,10 +61,10 @@ struct solib : intrusive_list_node > /* Constructor > > OPS is the solib_ops implementation providing this solib. */ > - explicit solib (const solib_ops &ops) : m_ops (&ops) {} > + explicit solib (solib_ops &ops) : m_ops (&ops) {} > > /* Return the solib_ops implementation providing this solib. */ > - const solib_ops &ops () const > + solib_ops &ops () const > { return *m_ops; } > > /* Free symbol-file related contents of SO and reset for possible reloading > @@ -125,7 +125,7 @@ struct solib : intrusive_list_node > > private: > /* The solib_ops responsible for this solib. */ > - const solib_ops *m_ops; > + solib_ops *m_ops; > }; > > /* A unique pointer to an solib. */ > @@ -133,22 +133,31 @@ using solib_up = std::unique_ptr; > > struct solib_ops > { > + virtual ~solib_ops () = default; > + > /* Adjust the section binding addresses by the base address at > which the object was actually mapped. */ > - void (*relocate_section_addresses) (solib &so, target_section *); > + virtual void relocate_section_addresses (solib &so, target_section *) const > + = 0; > > /* Reset private data structures associated with SO. > This is called when SO is about to be reloaded. > - It is also called when SO is about to be freed. */ > - void (*clear_so) (const solib &so); > + It is also called when SO is about to be freed. > + > + Defaults to no-op. */ > + virtual void clear_so (const solib &so) const {} > > /* Free private data structures associated to PSPACE. This method > should not free resources associated to individual solib entries, > - those are cleared by the clear_so method. */ > - void (*clear_solib) (program_space *pspace); > + those are cleared by the clear_so method. > > - /* Target dependent code to run after child process fork. */ > - void (*solib_create_inferior_hook) (int from_tty); > + Defaults to no-op. */ > + virtual void clear_solib (program_space *pspace) {} > + > + /* Target dependent code to run after child process fork. > + > + Defaults to no-op. */ > + virtual void create_inferior_hook (int from_tty) {}; > > /* Construct a list of the currently loaded shared objects. This > list does not include an entry for the main executable file. > @@ -157,45 +166,51 @@ struct solib_ops > inferior --- we don't examine any of the shared library files > themselves. The declaration of `struct solib' says which fields > we provide values for. */ > - owning_intrusive_list (*current_sos) (); > + virtual owning_intrusive_list current_sos () = 0; > > /* Find, open, and read the symbols for the main executable. If > - FROM_TTY is non-zero, allow messages to be printed. */ > - int (*open_symbol_file_object) (int from_ttyp); > + FROM_TTY is non-zero, allow messages to be printed. > + > + Return true if this was done successfully. Defaults to false. */ > + virtual bool open_symbol_file_object (int from_tty) { return false; } > > /* Determine if PC lies in the dynamic symbol resolution code of > - the run time loader. */ > - bool (*in_dynsym_resolve_code) (CORE_ADDR pc); > + the run time loader. > + > + Defaults to false. */ > + virtual bool in_dynsym_resolve_code (CORE_ADDR pc) const > + { return false; }; > > /* Find and open shared library binary file. */ > - gdb_bfd_ref_ptr (*bfd_open) (const char *pathname); > + virtual gdb_bfd_ref_ptr bfd_open (const char *pathname); > > - /* Given two solib objects, one from the GDB thread list > - and another from the list returned by current_sos, return 1 > - if they represent the same library. > - Falls back to using strcmp on ORIGINAL_NAME when set to nullptr. */ > - int (*same) (const solib &gdb, const solib &inferior); > + /* Given two solib objects, GDB from the GDB thread list and INFERIOR from the > + list returned by current_sos, return true if they represent the same library. > + > + Defaults to comparing the solib original names using filename_cmp. */ > + virtual bool same (const solib &gdb, const solib &inferior) const; > > /* Return whether a region of memory must be kept in a core file > for shared libraries loaded before "gcore" is used to be > handled correctly when the core file is loaded. This only > applies when the section would otherwise not be kept in the > - core file (in particular, for readonly sections). */ > - int (*keep_data_in_core) (CORE_ADDR vaddr, > - unsigned long size); > + core file (in particular, for readonly sections). > > - /* Enable or disable optional solib event breakpoints as > - appropriate. This should be called whenever > - stop_on_solib_events is changed. This pointer can be > - NULL, in which case no enabling or disabling is necessary > - for this target. */ > - void (*update_breakpoints) (void); > + Defaults to false. */ > + virtual bool keep_data_in_core (CORE_ADDR vaddr, unsigned long size) > + { return false; }; > > - /* Target-specific processing of solib events that will be > - performed before solib_add is called. This pointer can be > - NULL, in which case no specific preprocessing is necessary > - for this target. */ > - void (*handle_event) (void); > + /* Enable or disable optional solib event breakpoints as appropriate. This > + should be called whenever stop_on_solib_events is changed. > + > + Defaults to no-op. */ > + virtual void update_breakpoints () const {}; > + > + /* Target-specific processing of solib events that will be performed before > + solib_add is called. > + > + Defaults to no-op. */ > + virtual void handle_event () {}; > > /* Return an address within the inferior's address space which is known > to be part of SO. If there is no such address, or GDB doesn't know > @@ -210,28 +225,45 @@ struct solib_ops > mapped file, and thus to a build-id. GDB can then use this > information to help locate the shared library objfile, if the objfile > is not in the expected place (as defined by the shared libraries file > - name). */ > - std::optional (*find_solib_addr) (solib &so); > + name). > > - /* Return which linker namespace contains the current so. > - If the linker or libc does not support linkage namespaces at all > - (which is basically all of them but solib-svr4), this function should > - be set to nullptr, so that "info shared" won't add an unnecessary > - column. > + The default implementation of returns an empty option, indicating GDB is > + unable to find an address within the library SO. */ > + virtual std::optional find_solib_addr (solib &so) const > + { return {}; }; > > - If the namespace can not be determined (such as when we're stepping > - though the dynamic linker), this function should throw a > - gdb_exception_error. */ > - int (*find_solib_ns) (const solib &so); > + /* Return true if the linker or libc supports linkage namespaces. > > - /* Returns the number of active namespaces in the inferior. */ > - int (*num_active_namespaces) (); > + Defaults to false. */ > + virtual bool supports_namespaces () const { return false; } > + > + /* Return which linker namespace contains SO. > + > + The supports_namespaces method must return true for this to be > + called. > + > + Throw an error if the namespace can not be determined (such as when we're > + stepping though the dynamic linker). */ > + virtual int find_solib_ns (const solib &so) const > + { gdb_assert_not_reached ("namespaces not supported"); } > + > + /* Returns the number of active namespaces in the inferior. > + > + The supports_namespaces method must return true for this to be called. */ > + virtual int num_active_namespaces () const > + { gdb_assert_not_reached ("namespaces not supported"); } > > /* Returns all solibs for a given namespace. If the namespace is not > - active, returns an empty vector. */ > - std::vector (*get_solibs_in_ns) (int ns); > + active, returns an empty vector. > + > + The supports_namespaces method must return true for this to be called. */ > + virtual std::vector get_solibs_in_ns (int ns) const > + { gdb_assert_not_reached ("namespaces not supported"); } > }; > > +/* A unique pointer to an solib_ops. */ > +using solib_ops_up = std::unique_ptr; > + > /* Find main executable binary file. */ > extern gdb::unique_xmalloc_ptr exec_file_find (const char *in_pathname, > int *fd); > @@ -246,11 +278,6 @@ extern gdb_bfd_ref_ptr solib_bfd_fopen (const char *pathname, int fd); > /* Find solib binary file and open it. */ > extern gdb_bfd_ref_ptr solib_bfd_open (const char *in_pathname); > > -/* A default implementation of the solib_ops::find_solib_addr callback. > - This just returns an empty std::optional indicating GDB is > - unable to find an address within the library SO. */ > -extern std::optional default_find_solib_addr (solib &so); > - > /* Called when we free all symtabs of PSPACE, to free the shared library > information as well. */ > > diff --git a/gdb/sparc-linux-tdep.c b/gdb/sparc-linux-tdep.c > index 27706b72c7ef..06f6e06ecc9b 100644 > --- a/gdb/sparc-linux-tdep.c > +++ b/gdb/sparc-linux-tdep.c > @@ -33,6 +33,7 @@ > #include "tramp-frame.h" > #include "xml-syscall.h" > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > > /* The syscall's XML filename for sparc 32-bit. */ > #define XML_SYSCALL_FILENAME_SPARC32 "syscalls/sparc-linux.xml" > @@ -436,8 +437,7 @@ sparc32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > > /* GNU/Linux has SVR4-style shared libraries... */ > set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, linux_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops); > > /* ...which means that we need some special handling when doing > prologue analysis. */ > diff --git a/gdb/sparc-netbsd-tdep.c b/gdb/sparc-netbsd-tdep.c > index 84e3a979c6cd..1e9305440d76 100644 > --- a/gdb/sparc-netbsd-tdep.c > +++ b/gdb/sparc-netbsd-tdep.c > @@ -313,8 +313,7 @@ sparc32nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > > frame_unwind_append_unwinder (gdbarch, &sparc32nbsd_sigcontext_frame_unwind); > > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops); > } > > void _initialize_sparcnbsd_tdep (); > diff --git a/gdb/sparc-sol2-tdep.c b/gdb/sparc-sol2-tdep.c > index 5c6085acabbf..51d93910630c 100644 > --- a/gdb/sparc-sol2-tdep.c > +++ b/gdb/sparc-sol2-tdep.c > @@ -207,8 +207,7 @@ sparc32_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > > /* Solaris has SVR4-style shared libraries... */ > set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops); > > /* ...which means that we need some special handling when doing > prologue analysis. */ > diff --git a/gdb/sparc64-fbsd-tdep.c b/gdb/sparc64-fbsd-tdep.c > index 738c3d11c59c..9adbcce01b77 100644 > --- a/gdb/sparc64-fbsd-tdep.c > +++ b/gdb/sparc64-fbsd-tdep.c > @@ -238,8 +238,7 @@ sparc64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > > /* FreeBSD/sparc64 has SVR4-style shared libraries. */ > set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops); > } > > void _initialize_sparc64fbsd_tdep (); > diff --git a/gdb/sparc64-linux-tdep.c b/gdb/sparc64-linux-tdep.c > index 6e7281c91882..af15175b0795 100644 > --- a/gdb/sparc64-linux-tdep.c > +++ b/gdb/sparc64-linux-tdep.c > @@ -32,6 +32,7 @@ > #include "tramp-frame.h" > #include "xml-syscall.h" > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > > /* ADI specific si_code */ > #ifndef SEGV_ACCADI > @@ -383,8 +384,7 @@ sparc64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > > /* GNU/Linux has SVR4-style shared libraries... */ > set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, linux_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_lp64_svr4_solib_ops); > > /* ...which means that we need some special handling when doing > prologue analysis. */ > diff --git a/gdb/sparc64-netbsd-tdep.c b/gdb/sparc64-netbsd-tdep.c > index 19195987451c..8b3e013be562 100644 > --- a/gdb/sparc64-netbsd-tdep.c > +++ b/gdb/sparc64-netbsd-tdep.c > @@ -266,8 +266,7 @@ sparc64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > > /* NetBSD/sparc64 has SVR4-style shared libraries. */ > set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops); > } > > void _initialize_sparc64nbsd_tdep (); > diff --git a/gdb/sparc64-obsd-tdep.c b/gdb/sparc64-obsd-tdep.c > index 657f548537e7..cd8f3288995b 100644 > --- a/gdb/sparc64-obsd-tdep.c > +++ b/gdb/sparc64-obsd-tdep.c > @@ -440,8 +440,7 @@ sparc64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > obsd_init_abi (info, gdbarch); > > /* OpenBSD/sparc64 has SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops); > set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver); > > /* OpenBSD provides a user-level threads implementation. */ > diff --git a/gdb/sparc64-sol2-tdep.c b/gdb/sparc64-sol2-tdep.c > index 72a07ecef8ce..bb906efd29b4 100644 > --- a/gdb/sparc64-sol2-tdep.c > +++ b/gdb/sparc64-sol2-tdep.c > @@ -214,8 +214,7 @@ sparc64_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > > /* Solaris has SVR4-style shared libraries... */ > set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops); > > /* ...which means that we need some special handling when doing > prologue analysis. */ > diff --git a/gdb/tic6x-linux-tdep.c b/gdb/tic6x-linux-tdep.c > index 280d46dc487b..4dfb6f280bb7 100644 > --- a/gdb/tic6x-linux-tdep.c > +++ b/gdb/tic6x-linux-tdep.c > @@ -169,7 +169,7 @@ tic6x_uclinux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > linux_init_abi (info, gdbarch, 0); > > /* Shared library handling. */ > - set_gdbarch_so_ops (gdbarch, &dsbt_so_ops); > + set_gdbarch_new_solib_ops (gdbarch, new_dsbt_solib_ops); > > tdep->syscall_next_pc = tic6x_linux_syscall_next_pc; > > diff --git a/gdb/tilegx-linux-tdep.c b/gdb/tilegx-linux-tdep.c > index a0e69543f88b..92e5d0418b12 100644 > --- a/gdb/tilegx-linux-tdep.c > +++ b/gdb/tilegx-linux-tdep.c > @@ -19,6 +19,7 @@ > > #include "osabi.h" > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > #include "glibc-tdep.h" > #include "solib-svr4.h" > #include "symtab.h" > @@ -119,11 +120,9 @@ tilegx_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > > /* GNU/Linux uses SVR4-style shared libraries. */ > if (arch_size == 32) > - set_solib_svr4_fetch_link_map_offsets (gdbarch, > - linux_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops); > else > - set_solib_svr4_fetch_link_map_offsets (gdbarch, > - linux_lp64_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_lp64_svr4_solib_ops); > > /* Enable TLS support. */ > set_gdbarch_fetch_tls_load_module_address (gdbarch, > diff --git a/gdb/vax-netbsd-tdep.c b/gdb/vax-netbsd-tdep.c > index 34a9150fdb27..fabd98218d4b 100644 > --- a/gdb/vax-netbsd-tdep.c > +++ b/gdb/vax-netbsd-tdep.c > @@ -32,8 +32,7 @@ vaxnbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > nbsd_init_abi (info, gdbarch); > > /* NetBSD ELF uses SVR4-style shared libraries. */ > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops); > } > > void _initialize_vaxnbsd_tdep (); > diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c > index d8858a7f1450..75437a145d6a 100644 > --- a/gdb/windows-tdep.c > +++ b/gdb/windows-tdep.c > @@ -862,10 +862,25 @@ windows_get_siginfo_type (struct gdbarch *gdbarch) > return siginfo_type; > } > > +/* solib_ops for Windows systems. */ > + > +struct windows_solib_ops : target_solib_ops > +{ > + void create_inferior_hook (int from_tty) override; > +}; > + > +/* Return a new solib_ops for Windows systems. */ > + > +static solib_ops_up > +new_windows_solib_ops () > +{ > + return std::make_unique (); > +} > + > /* Implement the "solib_create_inferior_hook" solib_ops method. */ > > -static void > -windows_solib_create_inferior_hook (int from_tty) > +void > +windows_solib_ops::create_inferior_hook (int from_tty) > { > CORE_ADDR exec_base = 0; > > @@ -910,8 +925,6 @@ windows_solib_create_inferior_hook (int from_tty) > } > } > > -static solib_ops windows_so_ops; > - > /* Common parts for gdbarch initialization for the Windows and Cygwin OS > ABIs. */ > > @@ -928,10 +941,7 @@ windows_init_abi_common (struct gdbarch_info info, struct gdbarch *gdbarch) > set_gdbarch_iterate_over_objfiles_in_search_order > (gdbarch, windows_iterate_over_objfiles_in_search_order); > > - windows_so_ops = solib_target_so_ops; > - windows_so_ops.solib_create_inferior_hook > - = windows_solib_create_inferior_hook; > - set_gdbarch_so_ops (gdbarch, &windows_so_ops); > + set_gdbarch_new_solib_ops (gdbarch, new_windows_solib_ops); > > set_gdbarch_get_siginfo_type (gdbarch, windows_get_siginfo_type); > } > diff --git a/gdb/xtensa-linux-tdep.c b/gdb/xtensa-linux-tdep.c > index b72d683b3b40..eaa46cf788ab 100644 > --- a/gdb/xtensa-linux-tdep.c > +++ b/gdb/xtensa-linux-tdep.c > @@ -20,6 +20,7 @@ > #include "xtensa-tdep.h" > #include "osabi.h" > #include "linux-tdep.h" > +#include "solib-svr4-linux.h" > #include "solib-svr4.h" > #include "symtab.h" > #include "gdbarch.h" > @@ -111,8 +112,7 @@ xtensa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > > linux_init_abi (info, gdbarch, 0); > > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, linux_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops); > > set_gdbarch_gdb_signal_from_target (gdbarch, > xtensa_linux_gdb_signal_from_target); > diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c > index a4bbffb8f114..85a6bee5b6f5 100644 > --- a/gdb/xtensa-tdep.c > +++ b/gdb/xtensa-tdep.c > @@ -3238,8 +3238,7 @@ xtensa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) > set_gdbarch_iterate_over_regset_sections > (gdbarch, xtensa_iterate_over_regset_sections); > > - set_solib_svr4_fetch_link_map_offsets > - (gdbarch, svr4_ilp32_fetch_link_map_offsets); > + set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops); > > /* Hook in the ABI-specific overrides, if they have been registered. */ > gdbarch_init_osabi (info, gdbarch);