[04/24] gdb: replace some so_list parameters to use references

Message ID 20231010204213.111285-5-simon.marchi@efficios.com
State New
Headers
Series C++ification of struct so_list |

Commit Message

Simon Marchi Oct. 10, 2023, 8:39 p.m. UTC
  From: Simon Marchi <simon.marchi@polymtl.ca>

A subsequent patch changes so_list to be linked using
intrusive_list.  Iterating an intrusive_list yields some references to
the list elements.  Convert some functions accepting so_list objects to
take references, to make things easier and more natural.  Add const
where possible and convenient.

Change-Id: Id5ab5339c3eb6432e809ad14782952d6a45806f3
---
 gdb/breakpoint.c     |   5 +-
 gdb/bsd-uthread.c    |  12 ++---
 gdb/exec.c           |   4 +-
 gdb/interps.c        |   4 +-
 gdb/interps.h        |   8 +--
 gdb/mi/mi-cmd-file.c |   2 +-
 gdb/mi/mi-interp.c   |  26 ++++-----
 gdb/mi/mi-interp.h   |   6 +--
 gdb/nto-tdep.c       |   6 +--
 gdb/nto-tdep.h       |   3 +-
 gdb/observable.h     |   5 +-
 gdb/progspace.h      |   4 +-
 gdb/solib-aix.c      |  11 ++--
 gdb/solib-darwin.c   |  23 ++++----
 gdb/solib-dsbt.c     |   9 ++--
 gdb/solib-frv.c      |   9 ++--
 gdb/solib-rocm.c     |   8 +--
 gdb/solib-svr4.c     |  35 ++++++------
 gdb/solib-target.c   |  49 +++++++++--------
 gdb/solib.c          | 126 +++++++++++++++++++++----------------------
 gdb/solib.h          |   4 +-
 gdb/solist.h         |  13 +++--
 gdb/target-section.h |   2 +-
 23 files changed, 183 insertions(+), 191 deletions(-)
  

Comments

Lancelot SIX Oct. 19, 2023, 11:07 a.m. UTC | #1
Hi Simon,

Some minor remarks below.

On Tue, Oct 10, 2023 at 04:39:59PM -0400, Simon Marchi wrote:
> From: Simon Marchi <simon.marchi@polymtl.ca>
> 
> A subsequent patch changes so_list to be linked using
> intrusive_list.  Iterating an intrusive_list yields some references to
> the list elements.  Convert some functions accepting so_list objects to
> take references, to make things easier and more natural.  Add const
> where possible and convenient.
> 
> Change-Id: Id5ab5339c3eb6432e809ad14782952d6a45806f3
> ---
>  gdb/breakpoint.c     |   5 +-
>  gdb/bsd-uthread.c    |  12 ++---
>  gdb/exec.c           |   4 +-
>  gdb/interps.c        |   4 +-
>  gdb/interps.h        |   8 +--
>  gdb/mi/mi-cmd-file.c |   2 +-
>  gdb/mi/mi-interp.c   |  26 ++++-----
>  gdb/mi/mi-interp.h   |   6 +--
>  gdb/nto-tdep.c       |   6 +--
>  gdb/nto-tdep.h       |   3 +-
>  gdb/observable.h     |   5 +-
>  gdb/progspace.h      |   4 +-
>  gdb/solib-aix.c      |  11 ++--
>  gdb/solib-darwin.c   |  23 ++++----
>  gdb/solib-dsbt.c     |   9 ++--
>  gdb/solib-frv.c      |   9 ++--
>  gdb/solib-rocm.c     |   8 +--
>  gdb/solib-svr4.c     |  35 ++++++------
>  gdb/solib-target.c   |  49 +++++++++--------
>  gdb/solib.c          | 126 +++++++++++++++++++++----------------------
>  gdb/solib.h          |   4 +-
>  gdb/solist.h         |  13 +++--
>  gdb/target-section.h |   2 +-
>  23 files changed, 183 insertions(+), 191 deletions(-)
> 
> diff --git a/gdb/mi/mi-interp.h b/gdb/mi/mi-interp.h
> index f9af61f0a571..781a8dc6f466 100644
> --- a/gdb/mi/mi-interp.h
> +++ b/gdb/mi/mi-interp.h
> @@ -60,8 +60,8 @@ class mi_interp final : public interp
>    void on_record_changed (inferior *inf, int started, const char *method,
>  			  const char *format) override;
>    void on_target_resumed (ptid_t ptid) override;
> -  void on_solib_loaded (so_list *so) override;
> -  void on_solib_unloaded (so_list *so) override;
> +  void on_solib_loaded (const so_list &so) override;
> +  void on_solib_unloaded (const so_list &so) override;

It is orthogonal to this change, but it would make sense for those
methods to be const as well.

Doing this requires interp::interp_ui_out to be const as well (as done
in attached patch).

>    void on_about_to_proceed () override;
>    void on_traceframe_changed (int tfnum, int tpnum) override;
>    void on_tsv_created (const trace_state_variable *tsv) override;
> diff --git a/gdb/observable.h b/gdb/observable.h
> index acb05e9b535c..5ed6ca547ce0 100644
> --- a/gdb/observable.h
> +++ b/gdb/observable.h
> @@ -99,13 +99,12 @@ extern observable<inferior */* parent_inf */, inferior */* child_inf */,
>  /* The shared library specified by SOLIB has been loaded.  Note that
>     when gdb calls this observer, the library's symbols probably
>     haven't been loaded yet.  */
> -extern observable<struct so_list */* solib */> solib_loaded;
> +extern observable<so_list &/* solib */> solib_loaded;

I am wondering, is there a reason to make the solib parameter const for
solib_unloaded but not for solib_loaded?  

Changing it to const seems to still compile just fine.  If down the line
an observer needs to modify the SO, the observer's signature can be
adjusted.

>  
>  /* The shared library SOLIB has been unloaded from program space PSPACE.
>     Note  when gdb calls this observer, the library's symbols have not
>     been unloaded yet, and thus are still available.  */
> -extern observable<struct program_space */* pspace */, struct so_list */* solib */>
> -  solib_unloaded;
> +extern observable<program_space *, const so_list &/* solib */> solib_unloaded;
>  
>  /* The symbol file specified by OBJFILE has been loaded.  */
>  extern observable<struct objfile */* objfile */> new_objfile;
  
Simon Marchi Oct. 19, 2023, 2:49 p.m. UTC | #2
On 10/19/23 07:07, Lancelot SIX wrote:
> Hi Simon,
> 
> Some minor remarks below.
> 
> On Tue, Oct 10, 2023 at 04:39:59PM -0400, Simon Marchi wrote:
>> From: Simon Marchi <simon.marchi@polymtl.ca>
>>
>> A subsequent patch changes so_list to be linked using
>> intrusive_list.  Iterating an intrusive_list yields some references to
>> the list elements.  Convert some functions accepting so_list objects to
>> take references, to make things easier and more natural.  Add const
>> where possible and convenient.
>>
>> Change-Id: Id5ab5339c3eb6432e809ad14782952d6a45806f3
>> ---
>>  gdb/breakpoint.c     |   5 +-
>>  gdb/bsd-uthread.c    |  12 ++---
>>  gdb/exec.c           |   4 +-
>>  gdb/interps.c        |   4 +-
>>  gdb/interps.h        |   8 +--
>>  gdb/mi/mi-cmd-file.c |   2 +-
>>  gdb/mi/mi-interp.c   |  26 ++++-----
>>  gdb/mi/mi-interp.h   |   6 +--
>>  gdb/nto-tdep.c       |   6 +--
>>  gdb/nto-tdep.h       |   3 +-
>>  gdb/observable.h     |   5 +-
>>  gdb/progspace.h      |   4 +-
>>  gdb/solib-aix.c      |  11 ++--
>>  gdb/solib-darwin.c   |  23 ++++----
>>  gdb/solib-dsbt.c     |   9 ++--
>>  gdb/solib-frv.c      |   9 ++--
>>  gdb/solib-rocm.c     |   8 +--
>>  gdb/solib-svr4.c     |  35 ++++++------
>>  gdb/solib-target.c   |  49 +++++++++--------
>>  gdb/solib.c          | 126 +++++++++++++++++++++----------------------
>>  gdb/solib.h          |   4 +-
>>  gdb/solist.h         |  13 +++--
>>  gdb/target-section.h |   2 +-
>>  23 files changed, 183 insertions(+), 191 deletions(-)
>>
>> diff --git a/gdb/mi/mi-interp.h b/gdb/mi/mi-interp.h
>> index f9af61f0a571..781a8dc6f466 100644
>> --- a/gdb/mi/mi-interp.h
>> +++ b/gdb/mi/mi-interp.h
>> @@ -60,8 +60,8 @@ class mi_interp final : public interp
>>    void on_record_changed (inferior *inf, int started, const char *method,
>>  			  const char *format) override;
>>    void on_target_resumed (ptid_t ptid) override;
>> -  void on_solib_loaded (so_list *so) override;
>> -  void on_solib_unloaded (so_list *so) override;
>> +  void on_solib_loaded (const so_list &so) override;
>> +  void on_solib_unloaded (const so_list &so) override;
> 
> It is orthogonal to this change, but it would make sense for those
> methods to be const as well.
> 
> Doing this requires interp::interp_ui_out to be const as well (as done
> in attached patch).

Why do you think the interp object should be const (which is the effect
of marking the methods const)?  These methods are notifiers to let the
interp know about certain events that occured.  Whether they should
modify the state of the interpreter or not is up to the particular
implementation of the interpreter.  Perhaps you're right, but I don't
see it.

In your patch, you make interp::interp_ui_out const, but it still
returns a non-const ui_out.  So when outputting something, the
interpreter itself is not modified, but the ui_out behind it is.  I
presume (sometimes) the ui_out needs to be non-const, since for things
like pagination it clearly needs to keep a state.  Design-wise, is it
"correct" to make a const intepreter able to return a non-const ui_out?

>>    void on_about_to_proceed () override;
>>    void on_traceframe_changed (int tfnum, int tpnum) override;
>>    void on_tsv_created (const trace_state_variable *tsv) override;
>> diff --git a/gdb/observable.h b/gdb/observable.h
>> index acb05e9b535c..5ed6ca547ce0 100644
>> --- a/gdb/observable.h
>> +++ b/gdb/observable.h
>> @@ -99,13 +99,12 @@ extern observable<inferior */* parent_inf */, inferior */* child_inf */,
>>  /* The shared library specified by SOLIB has been loaded.  Note that
>>     when gdb calls this observer, the library's symbols probably
>>     haven't been loaded yet.  */
>> -extern observable<struct so_list */* solib */> solib_loaded;
>> +extern observable<so_list &/* solib */> solib_loaded;
> 
> I am wondering, is there a reason to make the solib parameter const for
> solib_unloaded but not for solib_loaded?  
> 
> Changing it to const seems to still compile just fine.  If down the line
> an observer needs to modify the SO, the observer's signature can be
> adjusted.

Just pragmatic reasons.  Do you build with --enable-targets=all?

It's because bsd_uthread_solib_loaded calls solib_read_symbols to read
in the symbols of the library it is looking for, and that requires a
non-const so_list.

Simon
  
Lancelot SIX Oct. 19, 2023, 3:20 p.m. UTC | #3
>>> -  void on_solib_loaded (so_list *so) override;
>>> -  void on_solib_unloaded (so_list *so) override;
>>> +  void on_solib_loaded (const so_list &so) override;
>>> +  void on_solib_unloaded (const so_list &so) override;
>>
>> It is orthogonal to this change, but it would make sense for those
>> methods to be const as well.
>>
>> Doing this requires interp::interp_ui_out to be const as well (as done
>> in attached patch).
> 
> Why do you think the interp object should be const (which is the effect
> of marking the methods const)?  These methods are notifiers to let the
> interp know about certain events that occured.  Whether they should
> modify the state of the interpreter or not is up to the particular
> implementation of the interpreter.  Perhaps you're right, but I don't
> see it.
> 

It is just that current interps (MI really) are just forwarding 
notifications.  The event does not change the interp's state.
Does it has to be const? No. But usually I tend to make things const 
unless there is a reason not to.  That's all.

That being said, making only those const would become quite 
inconsistent with the rest of the interface.  So in the end, that was 
not a good idea!

> In your patch, you make interp::interp_ui_out const, but it still
> returns a non-const ui_out.  So when outputting something, the
> interpreter itself is not modified, but the ui_out behind it is.  I
> presume (sometimes) the ui_out needs to be non-const, since for things
> like pagination it clearly needs to keep a state.  Design-wise, is it
> "correct" to make a const intepreter able to return a non-const ui_out?
> 

I don't necessarily see that as an issue, the ui_out might need to 
maintain its own state.

Anyway, since it is not really desirable to change this part of the 
interface, I think this comment can be discarded.

>>>     void on_about_to_proceed () override;
>>>     void on_traceframe_changed (int tfnum, int tpnum) override;
>>>     void on_tsv_created (const trace_state_variable *tsv) override;
>>> diff --git a/gdb/observable.h b/gdb/observable.h
>>> index acb05e9b535c..5ed6ca547ce0 100644
>>> --- a/gdb/observable.h
>>> +++ b/gdb/observable.h
>>> @@ -99,13 +99,12 @@ extern observable<inferior */* parent_inf */, inferior */* child_inf */,
>>>   /* The shared library specified by SOLIB has been loaded.  Note that
>>>      when gdb calls this observer, the library's symbols probably
>>>      haven't been loaded yet.  */
>>> -extern observable<struct so_list */* solib */> solib_loaded;
>>> +extern observable<so_list &/* solib */> solib_loaded;
>>
>> I am wondering, is there a reason to make the solib parameter const for
>> solib_unloaded but not for solib_loaded?
>>
>> Changing it to const seems to still compile just fine.  If down the line
>> an observer needs to modify the SO, the observer's signature can be
>> adjusted.
> 
> Just pragmatic reasons.  Do you build with --enable-targets=all?
> 
> It's because bsd_uthread_solib_loaded calls solib_read_symbols to read
> in the symbols of the library it is looking for, and that requires a
> non-const so_list.
> 

Ah, indeed, my current build tree does not have --enable-targets=all, 
thanks.  Having a user requiring a non-const ref is a good reason.

Thanks,
Lancelot.
  
Simon Marchi Oct. 19, 2023, 4:07 p.m. UTC | #4
On 10/19/23 11:20, Lancelot SIX wrote:
> 
>>>> -  void on_solib_loaded (so_list *so) override;
>>>> -  void on_solib_unloaded (so_list *so) override;
>>>> +  void on_solib_loaded (const so_list &so) override;
>>>> +  void on_solib_unloaded (const so_list &so) override;
>>>
>>> It is orthogonal to this change, but it would make sense for those
>>> methods to be const as well.
>>>
>>> Doing this requires interp::interp_ui_out to be const as well (as done
>>> in attached patch).
>>
>> Why do you think the interp object should be const (which is the effect
>> of marking the methods const)?  These methods are notifiers to let the
>> interp know about certain events that occured.  Whether they should
>> modify the state of the interpreter or not is up to the particular
>> implementation of the interpreter.  Perhaps you're right, but I don't
>> see it.
>>
> 
> It is just that current interps (MI really) are just forwarding notifications.  The event does not change the interp's state.
> Does it has to be const? No. But usually I tend to make things const unless there is a reason not to.  That's all.

But if I make the method const for MI, I need to make it const for all
interps, including CLI and TUI, right?  So then we need to extend the
reflection to whether it makes sense to make the method const for them
too (hence my question about the non-const ui_out behind a const cli
interp).

Simon
  

Patch

diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 2edcbf6d4904..75691935553d 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -8018,7 +8018,8 @@  disable_breakpoints_in_shlibs (void)
    disabled ones can just stay disabled.  */
 
 static void
-disable_breakpoints_in_unloaded_shlib (program_space *pspace, so_list *solib)
+disable_breakpoints_in_unloaded_shlib (program_space *pspace,
+				       const so_list &solib)
 {
   bool disabled_shlib_breaks = false;
 
@@ -8051,7 +8052,7 @@  disable_breakpoints_in_unloaded_shlib (program_space *pspace, so_list *solib)
 	      target_terminal::ours_for_output ();
 	      warning (_("Temporarily disabling breakpoints "
 			 "for unloaded shared library \"%s\""),
-		       solib->so_name);
+		       solib.so_name);
 	    }
 	  disabled_shlib_breaks = true;
 	}
diff --git a/gdb/bsd-uthread.c b/gdb/bsd-uthread.c
index 8765fb77283d..6435a5291958 100644
--- a/gdb/bsd-uthread.c
+++ b/gdb/bsd-uthread.c
@@ -275,19 +275,19 @@  static const char * const bsd_uthread_solib_names[] =
 };
 
 static void
-bsd_uthread_solib_loaded (struct so_list *so)
+bsd_uthread_solib_loaded (so_list &so)
 {
   const char * const *names = bsd_uthread_solib_names;
 
   for (names = bsd_uthread_solib_names; *names; names++)
     {
-      if (startswith (so->so_original_name, *names))
+      if (startswith (so.so_original_name, *names))
 	{
 	  solib_read_symbols (so, 0);
 
-	  if (bsd_uthread_activate (so->objfile))
+	  if (bsd_uthread_activate (so.objfile))
 	    {
-	      bsd_uthread_solib_name = so->so_original_name;
+	      bsd_uthread_solib_name = so.so_original_name;
 	      return;
 	    }
 	}
@@ -295,12 +295,12 @@  bsd_uthread_solib_loaded (struct so_list *so)
 }
 
 static void
-bsd_uthread_solib_unloaded (program_space *pspace, so_list *so)
+bsd_uthread_solib_unloaded (program_space *pspace, const so_list &so)
 {
   if (!bsd_uthread_solib_name)
     return;
 
-  if (strcmp (so->so_original_name, bsd_uthread_solib_name) == 0)
+  if (strcmp (so.so_original_name, bsd_uthread_solib_name) == 0)
     bsd_uthread_deactivate ();
 }
 
diff --git a/gdb/exec.c b/gdb/exec.c
index a1396c2aa3d2..08c205662ea1 100644
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -599,7 +599,7 @@  build_section_table (struct bfd *some_bfd)
    current set of target sections.  */
 
 void
-program_space::add_target_sections (void *owner,
+program_space::add_target_sections (const void *owner,
 				    const target_section_table &sections)
 {
   if (!sections.empty ())
@@ -651,7 +651,7 @@  program_space::add_target_sections (struct objfile *objfile)
    OWNER must be the same value passed to add_target_sections.  */
 
 void
-program_space::remove_target_sections (void *owner)
+program_space::remove_target_sections (const void *owner)
 {
   gdb_assert (owner != NULL);
 
diff --git a/gdb/interps.c b/gdb/interps.c
index 62a30583e8c0..544539b0c798 100644
--- a/gdb/interps.c
+++ b/gdb/interps.c
@@ -488,7 +488,7 @@  interps_notify_target_resumed (ptid_t ptid)
 /* See interps.h.  */
 
 void
-interps_notify_solib_loaded (so_list *so)
+interps_notify_solib_loaded (const so_list &so)
 {
   interps_notify (&interp::on_solib_loaded, so);
 }
@@ -496,7 +496,7 @@  interps_notify_solib_loaded (so_list *so)
 /* See interps.h.  */
 
 void
-interps_notify_solib_unloaded (so_list *so)
+interps_notify_solib_unloaded (const so_list &so)
 {
   interps_notify (&interp::on_solib_unloaded, so);
 }
diff --git a/gdb/interps.h b/gdb/interps.h
index 287df2c8c810..a90c5aa17b0a 100644
--- a/gdb/interps.h
+++ b/gdb/interps.h
@@ -147,10 +147,10 @@  class interp : public intrusive_list_node<interp>
   virtual void on_target_resumed (ptid_t ptid) {}
 
   /* Notify the interpreter that solib SO has been loaded.  */
-  virtual void on_solib_loaded (so_list *so) {}
+  virtual void on_solib_loaded (const so_list &so) {}
 
   /* Notify the interpreter that solib SO has been unloaded.  */
-  virtual void on_solib_unloaded (so_list *so) {}
+  virtual void on_solib_unloaded (const so_list &so) {}
 
   /* Notify the interpreter that a command it is executing is about to cause
      the inferior to proceed.  */
@@ -324,10 +324,10 @@  extern void interps_notify_record_changed (inferior *inf, int started,
 extern void interps_notify_target_resumed (ptid_t ptid);
 
 /* Notify all interpreters that solib SO has been loaded.  */
-extern void interps_notify_solib_loaded (so_list *so);
+extern void interps_notify_solib_loaded (const so_list &so);
 
 /* Notify all interpreters that solib SO has been unloaded.  */
-extern void interps_notify_solib_unloaded (so_list *so);
+extern void interps_notify_solib_unloaded (const so_list &so);
 
 /* Notify all interpreters that the selected traceframe changed.
 
diff --git a/gdb/mi/mi-cmd-file.c b/gdb/mi/mi-cmd-file.c
index 688bf493f195..822d3df40005 100644
--- a/gdb/mi/mi-cmd-file.c
+++ b/gdb/mi/mi-cmd-file.c
@@ -171,6 +171,6 @@  mi_cmd_file_list_shared_libraries (const char *command,
 	continue;
 
       ui_out_emit_tuple tuple_emitter (uiout, NULL);
-      mi_output_solib_attribs (uiout, so);
+      mi_output_solib_attribs (uiout, *so);
     }
 }
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index 0d3c8235c2c1..0fae5674201c 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -724,28 +724,28 @@  mi_interp::on_target_resumed (ptid_t ptid)
 /* See mi-interp.h.  */
 
 void
-mi_output_solib_attribs (ui_out *uiout, struct so_list *solib)
+mi_output_solib_attribs (ui_out *uiout, const so_list &solib)
 {
   gdbarch *gdbarch = current_inferior ()->arch ();
 
-  uiout->field_string ("id", solib->so_original_name);
-  uiout->field_string ("target-name", solib->so_original_name);
-  uiout->field_string ("host-name", solib->so_name);
-  uiout->field_signed ("symbols-loaded", solib->symbols_loaded);
+  uiout->field_string ("id", solib.so_original_name);
+  uiout->field_string ("target-name", solib.so_original_name);
+  uiout->field_string ("host-name", solib.so_name);
+  uiout->field_signed ("symbols-loaded", solib.symbols_loaded);
   if (!gdbarch_has_global_solist (current_inferior ()->arch ()))
       uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
 
   ui_out_emit_list list_emitter (uiout, "ranges");
   ui_out_emit_tuple tuple_emitter (uiout, NULL);
-  if (solib->addr_high != 0)
+  if (solib.addr_high != 0)
     {
-      uiout->field_core_addr ("from", gdbarch, solib->addr_low);
-      uiout->field_core_addr ("to", gdbarch, solib->addr_high);
+      uiout->field_core_addr ("from", gdbarch, solib.addr_low);
+      uiout->field_core_addr ("to", gdbarch, solib.addr_high);
     }
 }
 
 void
-mi_interp::on_solib_loaded (so_list *solib)
+mi_interp::on_solib_loaded (const so_list &solib)
 {
   ui_out *uiout = this->interp_ui_out ();
 
@@ -762,7 +762,7 @@  mi_interp::on_solib_loaded (so_list *solib)
 }
 
 void
-mi_interp::on_solib_unloaded (so_list *solib)
+mi_interp::on_solib_unloaded (const so_list &solib)
 {
   ui_out *uiout = this->interp_ui_out ();
 
@@ -773,9 +773,9 @@  mi_interp::on_solib_unloaded (so_list *solib)
 
   ui_out_redirect_pop redir (uiout, this->event_channel);
 
-  uiout->field_string ("id", solib->so_original_name);
-  uiout->field_string ("target-name", solib->so_original_name);
-  uiout->field_string ("host-name", solib->so_name);
+  uiout->field_string ("id", solib.so_original_name);
+  uiout->field_string ("target-name", solib.so_original_name);
+  uiout->field_string ("host-name", solib.so_name);
   if (!gdbarch_has_global_solist (current_inferior ()->arch ()))
     uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
 
diff --git a/gdb/mi/mi-interp.h b/gdb/mi/mi-interp.h
index f9af61f0a571..781a8dc6f466 100644
--- a/gdb/mi/mi-interp.h
+++ b/gdb/mi/mi-interp.h
@@ -60,8 +60,8 @@  class mi_interp final : public interp
   void on_record_changed (inferior *inf, int started, const char *method,
 			  const char *format) override;
   void on_target_resumed (ptid_t ptid) override;
-  void on_solib_loaded (so_list *so) override;
-  void on_solib_unloaded (so_list *so) override;
+  void on_solib_loaded (const so_list &so) override;
+  void on_solib_unloaded (const so_list &so) override;
   void on_about_to_proceed () override;
   void on_traceframe_changed (int tfnum, int tpnum) override;
   void on_tsv_created (const trace_state_variable *tsv) override;
@@ -108,7 +108,7 @@  class mi_interp final : public interp
 
 /* Output the shared object attributes to UIOUT.  */
 
-void mi_output_solib_attribs (ui_out *uiout, struct so_list *solib);
+void mi_output_solib_attribs (ui_out *uiout, const so_list &solib);
 
 /* Returns the INTERP's data cast as mi_interp if INTERP is an MI, and
    returns NULL otherwise.  */
diff --git a/gdb/nto-tdep.c b/gdb/nto-tdep.c
index 9ece8b5fb39b..1d9c7340fcf7 100644
--- a/gdb/nto-tdep.c
+++ b/gdb/nto-tdep.c
@@ -245,9 +245,9 @@  nto_parse_redirection (char *pargv[], const char **pin, const char **pout,
 }
 
 static CORE_ADDR
-lm_addr (struct so_list *so)
+lm_addr (const so_list &so)
 {
-  lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info;
+  const lm_info_svr4 *li = (const lm_info_svr4 *) so.lm_info;
 
   return li->l_addr;
 }
@@ -283,7 +283,7 @@  find_load_phdr (bfd *abfd)
 }
 
 void
-nto_relocate_section_addresses (struct so_list *so, struct target_section *sec)
+nto_relocate_section_addresses (so_list &so, target_section *sec)
 {
   /* Neutrino treats the l_addr base address field in link.h as different than
      the base address in the System V ABI and so the offset needs to be
diff --git a/gdb/nto-tdep.h b/gdb/nto-tdep.h
index b352d5310c49..8b644b30c42a 100644
--- a/gdb/nto-tdep.h
+++ b/gdb/nto-tdep.h
@@ -166,8 +166,7 @@  void nto_init_solib_absolute_prefix (void);
 char **nto_parse_redirection (char *start_argv[], const char **in,
 			      const char **out, const char **err);
 
-void nto_relocate_section_addresses (struct so_list *,
-				     struct target_section *);
+void nto_relocate_section_addresses (so_list &, target_section *);
 
 int nto_map_arch_to_cputype (const char *);
 
diff --git a/gdb/observable.h b/gdb/observable.h
index acb05e9b535c..5ed6ca547ce0 100644
--- a/gdb/observable.h
+++ b/gdb/observable.h
@@ -99,13 +99,12 @@  extern observable<inferior */* parent_inf */, inferior */* child_inf */,
 /* The shared library specified by SOLIB has been loaded.  Note that
    when gdb calls this observer, the library's symbols probably
    haven't been loaded yet.  */
-extern observable<struct so_list */* solib */> solib_loaded;
+extern observable<so_list &/* solib */> solib_loaded;
 
 /* The shared library SOLIB has been unloaded from program space PSPACE.
    Note  when gdb calls this observer, the library's symbols have not
    been unloaded yet, and thus are still available.  */
-extern observable<struct program_space */* pspace */, struct so_list */* solib */>
-  solib_unloaded;
+extern observable<program_space *, const so_list &/* solib */> solib_unloaded;
 
 /* The symbol file specified by OBJFILE has been loaded.  */
 extern observable<struct objfile */* objfile */> new_objfile;
diff --git a/gdb/progspace.h b/gdb/progspace.h
index ee12d89c173c..0930d8583597 100644
--- a/gdb/progspace.h
+++ b/gdb/progspace.h
@@ -286,11 +286,11 @@  struct program_space
   bool empty ();
 
   /* Remove all target sections owned by OWNER.  */
-  void remove_target_sections (void *owner);
+  void remove_target_sections (const void *owner);
 
   /* Add the sections array defined by SECTIONS to the
      current set of target sections.  */
-  void add_target_sections (void *owner,
+  void add_target_sections (const void *owner,
 			    const target_section_table &sections);
 
   /* Add the sections of OBJFILE to the current set of target
diff --git a/gdb/solib-aix.c b/gdb/solib-aix.c
index 0b6ad83eed92..cfcc04db1518 100644
--- a/gdb/solib-aix.c
+++ b/gdb/solib-aix.c
@@ -311,13 +311,12 @@  solib_aix_bss_data_overlap (bfd *abfd)
 /* Implement the "relocate_section_addresses" target_so_ops method.  */
 
 static void
-solib_aix_relocate_section_addresses (struct so_list *so,
-				      struct target_section *sec)
+solib_aix_relocate_section_addresses (so_list &so, target_section *sec)
 {
   struct bfd_section *bfd_sect = sec->the_bfd_section;
   bfd *abfd = bfd_sect->owner;
   const char *section_name = bfd_section_name (bfd_sect);
-  lm_info_aix *info = (lm_info_aix *) so->lm_info;
+  lm_info_aix *info = (lm_info_aix *) so.lm_info;
 
   if (strcmp (section_name, ".text") == 0)
     {
@@ -364,11 +363,11 @@  solib_aix_relocate_section_addresses (struct so_list *so,
 /* Implement the "free_so" target_so_ops method.  */
 
 static void
-solib_aix_free_so (struct so_list *so)
+solib_aix_free_so (so_list &so)
 {
-  lm_info_aix *li = (lm_info_aix *) so->lm_info;
+  lm_info_aix *li = (lm_info_aix *) so.lm_info;
 
-  solib_debug_printf ("%s", so->so_name);
+  solib_debug_printf ("%s", so.so_name);
 
   delete li;
 }
diff --git a/gdb/solib-darwin.c b/gdb/solib-darwin.c
index 4796315c373a..5720f997bef7 100644
--- a/gdb/solib-darwin.c
+++ b/gdb/solib-darwin.c
@@ -608,9 +608,9 @@  darwin_clear_solib (program_space *pspace)
 }
 
 static void
-darwin_free_so (struct so_list *so)
+darwin_free_so (so_list &so)
 {
-  lm_info_darwin *li = (lm_info_darwin *) so->lm_info;
+  lm_info_darwin *li = (lm_info_darwin *) so.lm_info;
 
   delete li;
 }
@@ -619,25 +619,24 @@  darwin_free_so (struct so_list *so)
    Relocate these VMAs according to solib info.  */
 
 static void
-darwin_relocate_section_addresses (struct so_list *so,
-				   struct target_section *sec)
+darwin_relocate_section_addresses (so_list &so, target_section *sec)
 {
-  lm_info_darwin *li = (lm_info_darwin *) so->lm_info;
+  lm_info_darwin *li = (lm_info_darwin *) so.lm_info;
 
   sec->addr += li->lm_addr;
   sec->endaddr += li->lm_addr;
 
   /* Best effort to set addr_high/addr_low.  This is used only by
      'info sharedlibary'.  */
-  if (so->addr_high == 0)
+  if (so.addr_high == 0)
     {
-      so->addr_low = sec->addr;
-      so->addr_high = sec->endaddr;
+      so.addr_low = sec->addr;
+      so.addr_high = sec->endaddr;
     }
-  if (sec->endaddr > so->addr_high)
-    so->addr_high = sec->endaddr;
-  if (sec->addr < so->addr_low)
-    so->addr_low = sec->addr;
+  if (sec->endaddr > so.addr_high)
+    so.addr_high = sec->endaddr;
+  if (sec->addr < so.addr_low)
+    so.addr_low = sec->addr;
 }
 
 static gdb_bfd_ref_ptr
diff --git a/gdb/solib-dsbt.c b/gdb/solib-dsbt.c
index 16fa78a3d8b2..60a211ee6e6e 100644
--- a/gdb/solib-dsbt.c
+++ b/gdb/solib-dsbt.c
@@ -881,19 +881,18 @@  dsbt_clear_solib (program_space *pspace)
 }
 
 static void
-dsbt_free_so (struct so_list *so)
+dsbt_free_so (so_list &so)
 {
-  lm_info_dsbt *li = (lm_info_dsbt *) so->lm_info;
+  lm_info_dsbt *li = (lm_info_dsbt *) so.lm_info;
 
   delete li;
 }
 
 static void
-dsbt_relocate_section_addresses (struct so_list *so,
-				 struct target_section *sec)
+dsbt_relocate_section_addresses (so_list &so, target_section *sec)
 {
   int seg;
-  lm_info_dsbt *li = (lm_info_dsbt *) so->lm_info;
+  lm_info_dsbt *li = (lm_info_dsbt *) so.lm_info;
   int_elf32_dsbt_loadmap *map = li->map;
 
   for (seg = 0; seg < map->nsegs; seg++)
diff --git a/gdb/solib-frv.c b/gdb/solib-frv.c
index c61ed7910ee2..c895eb20e434 100644
--- a/gdb/solib-frv.c
+++ b/gdb/solib-frv.c
@@ -817,19 +817,18 @@  frv_clear_solib (program_space *pspace)
 }
 
 static void
-frv_free_so (struct so_list *so)
+frv_free_so (so_list &so)
 {
-  lm_info_frv *li = (lm_info_frv *) so->lm_info;
+  lm_info_frv *li = (lm_info_frv *) so.lm_info;
 
   delete li;
 }
 
 static void
-frv_relocate_section_addresses (struct so_list *so,
-				 struct target_section *sec)
+frv_relocate_section_addresses (so_list &so, target_section *sec)
 {
   int seg;
-  lm_info_frv *li = (lm_info_frv *) so->lm_info;
+  lm_info_frv *li = (lm_info_frv *) so.lm_info;
   int_elf32_fdpic_loadmap *map = li->map;
 
   for (seg = 0; seg < map->nsegs; seg++)
diff --git a/gdb/solib-rocm.c b/gdb/solib-rocm.c
index b24d0e8fb235..65dd1c06271f 100644
--- a/gdb/solib-rocm.c
+++ b/gdb/solib-rocm.c
@@ -153,7 +153,7 @@  rocm_free_solib_list (struct solib_info *info)
     {
       struct so_list *next = info->solib_list->next;
 
-      free_so (info->solib_list);
+      free_so (*info->solib_list);
       info->solib_list = next;
     }
 
@@ -177,16 +177,16 @@  get_solib_info (inferior *inf)
 /* Relocate section addresses.  */
 
 static void
-rocm_solib_relocate_section_addresses (struct so_list *so,
+rocm_solib_relocate_section_addresses (so_list &so,
 				       struct target_section *sec)
 {
-  if (!is_amdgpu_arch (gdbarch_from_bfd (so->abfd)))
+  if (!is_amdgpu_arch (gdbarch_from_bfd (so.abfd)))
     {
       svr4_so_ops.relocate_section_addresses (so, sec);
       return;
     }
 
-  lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info;
+  lm_info_svr4 *li = (lm_info_svr4 *) so.lm_info;
   sec->addr = sec->addr + li->l_addr;
   sec->endaddr = sec->endaddr + li->l_addr;
 }
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 1f8b8b34c00a..b32848944cad 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -173,16 +173,16 @@  svr4_same_1 (const char *gdb_so_name, const char *inferior_so_name)
 }
 
 static int
-svr4_same (struct so_list *gdb, struct so_list *inferior)
+svr4_same (const so_list &gdb, const so_list &inferior)
 {
-  if (!svr4_same_1 (gdb->so_original_name, inferior->so_original_name))
+  if (!svr4_same_1 (gdb.so_original_name, inferior.so_original_name))
     return false;
 
   /* There may be different instances of the same library, in different
      namespaces.  Each instance, however, must have been loaded at a
      different address so its relocation offset would be different.  */
-  const lm_info_svr4 *lmg = (const lm_info_svr4 *) gdb->lm_info;
-  const lm_info_svr4 *lmi = (const lm_info_svr4 *) inferior->lm_info;
+  const lm_info_svr4 *lmg = (const lm_info_svr4 *) gdb.lm_info;
+  const lm_info_svr4 *lmi = (const lm_info_svr4 *) inferior.lm_info;
 
   return (lmg->l_addr_inferior == lmi->l_addr_inferior);
 }
@@ -229,9 +229,9 @@  has_lm_dynamic_from_link_map (void)
 }
 
 static CORE_ADDR
-lm_addr_check (const struct so_list *so, bfd *abfd)
+lm_addr_check (const so_list &so, bfd *abfd)
 {
-  lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info;
+  lm_info_svr4 *li = (lm_info_svr4 *) so.lm_info;
 
   if (!li->l_addr_p)
     {
@@ -306,7 +306,7 @@  lm_addr_check (const struct so_list *so, bfd *abfd)
 		gdb_printf (_("Using PIC (Position Independent Code) "
 			      "prelink displacement %s for \"%s\".\n"),
 			    paddress (current_inferior ()->arch (), l_addr),
-			    so->so_name);
+			    so.so_name);
 	    }
 	  else
 	    {
@@ -321,7 +321,7 @@  lm_addr_check (const struct so_list *so, bfd *abfd)
 
 	      warning (_(".dynamic section for \"%s\" "
 			 "is not at the expected address "
-			 "(wrong library or version mismatch?)"), so->so_name);
+			 "(wrong library or version mismatch?)"), so.so_name);
 	    }
 	}
 
@@ -979,9 +979,9 @@  svr4_free_objfile_observer (struct objfile *objfile)
 /* Implementation for target_so_ops.free_so.  */
 
 static void
-svr4_free_so (struct so_list *so)
+svr4_free_so (so_list &so)
 {
-  lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info;
+  lm_info_svr4 *li = (lm_info_svr4 *) so.lm_info;
 
   delete li;
 }
@@ -989,9 +989,9 @@  svr4_free_so (struct so_list *so)
 /* Implement target_so_ops.clear_so.  */
 
 static void
-svr4_clear_so (struct so_list *so)
+svr4_clear_so (const so_list &so)
 {
-  lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info;
+  lm_info_svr4 *li = (lm_info_svr4 *) so.lm_info;
 
   if (li != NULL)
     li->l_addr_p = 0;
@@ -1006,7 +1006,7 @@  svr4_free_library_list (so_list *list)
     {
       struct so_list *next = list->next;
 
-      free_so (list);
+      free_so (*list);
       list = next;
     }
 }
@@ -1581,7 +1581,7 @@  svr4_current_sos (void)
 	  if (address_in_mem_range (li->l_ld, &vsyscall_range))
 	    {
 	      *sop = so->next;
-	      free_so (so);
+	      free_so (*so);
 	      break;
 	    }
 
@@ -2471,7 +2471,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 = lm_addr_check (*so, tmp_bfd.get ());
 	      break;
 	    }
 	}
@@ -3214,8 +3214,7 @@  svr4_truncate_ptr (CORE_ADDR addr)
 
 
 static void
-svr4_relocate_section_addresses (struct so_list *so,
-				 struct target_section *sec)
+svr4_relocate_section_addresses (so_list &so, target_section *sec)
 {
   bfd *abfd = sec->the_bfd_section->owner;
 
@@ -3396,7 +3395,7 @@  find_debug_base_for_solib (so_list *solib)
       so_list *solist = tuple.second;
 
       for (; solist != nullptr; solist = solist->next)
-	if (svr4_same (solib, solist))
+	if (svr4_same (*solib, *solist))
 	  return debug_base;
     }
 
diff --git a/gdb/solib-target.c b/gdb/solib-target.c
index 865235de2995..b8b6dd644018 100644
--- a/gdb/solib-target.c
+++ b/gdb/solib-target.c
@@ -282,9 +282,9 @@  solib_target_solib_create_inferior_hook (int from_tty)
 }
 
 static void
-solib_target_free_so (struct so_list *so)
+solib_target_free_so (so_list &so)
 {
-  lm_info_target *li = (lm_info_target *) so->lm_info;
+  lm_info_target *li = (lm_info_target *) so.lm_info;
 
   gdb_assert (li->name.empty ());
 
@@ -292,17 +292,16 @@  solib_target_free_so (struct so_list *so)
 }
 
 static void
-solib_target_relocate_section_addresses (struct so_list *so,
-					 struct target_section *sec)
+solib_target_relocate_section_addresses (so_list &so, target_section *sec)
 {
   CORE_ADDR offset;
-  lm_info_target *li = (lm_info_target *) so->lm_info;
+  lm_info_target *li = (lm_info_target *) so.lm_info;
 
   /* Build the offset table only once per object file.  We can not do
      it any earlier, since we need to open the file first.  */
   if (li->offsets.empty ())
     {
-      int num_sections = gdb_bfd_count_sections (so->abfd);
+      int num_sections = gdb_bfd_count_sections (so.abfd);
 
       li->offsets.assign (num_sections, 0);
 
@@ -312,7 +311,7 @@  solib_target_relocate_section_addresses (struct so_list *so,
 	  asection *sect;
 	  int num_alloc_sections = 0;
 
-	  for (i = 0, sect = so->abfd->sections;
+	  for (i = 0, sect = so.abfd->sections;
 	       sect != NULL;
 	       i++, sect = sect->next)
 	    if ((bfd_section_flags (sect) & SEC_ALLOC))
@@ -321,15 +320,15 @@  solib_target_relocate_section_addresses (struct so_list *so,
 	  if (num_alloc_sections != li->section_bases.size ())
 	    warning (_("\
 Could not relocate shared library \"%s\": wrong number of ALLOC sections"),
-		     so->so_name);
+		     so.so_name);
 	  else
 	    {
 	      int bases_index = 0;
 	      int found_range = 0;
 
-	      so->addr_low = ~(CORE_ADDR) 0;
-	      so->addr_high = 0;
-	      for (i = 0, sect = so->abfd->sections;
+	      so.addr_low = ~(CORE_ADDR) 0;
+	      so.addr_high = 0;
+	      for (i = 0, sect = so.abfd->sections;
 		   sect != NULL;
 		   i++, sect = sect->next)
 		{
@@ -342,40 +341,40 @@  Could not relocate shared library \"%s\": wrong number of ALLOC sections"),
 		      low = li->section_bases[i];
 		      high = low + bfd_section_size (sect) - 1;
 
-		      if (low < so->addr_low)
-			so->addr_low = low;
-		      if (high > so->addr_high)
-			so->addr_high = high;
-		      gdb_assert (so->addr_low <= so->addr_high);
+		      if (low < so.addr_low)
+			so.addr_low = low;
+		      if (high > so.addr_high)
+			so.addr_high = high;
+		      gdb_assert (so.addr_low <= so.addr_high);
 		      found_range = 1;
 		    }
 		  li->offsets[i] = li->section_bases[bases_index];
 		  bases_index++;
 		}
 	      if (!found_range)
-		so->addr_low = so->addr_high = 0;
-	      gdb_assert (so->addr_low <= so->addr_high);
+		so.addr_low = so.addr_high = 0;
+	      gdb_assert (so.addr_low <= so.addr_high);
 	    }
 	}
       else if (!li->segment_bases.empty ())
 	{
 	  symfile_segment_data_up data
-	    = get_symfile_segment_data (so->abfd);
+	    = get_symfile_segment_data (so.abfd);
 
 	  if (data == NULL)
 	    warning (_("\
-Could not relocate shared library \"%s\": no segments"), so->so_name);
+Could not relocate shared library \"%s\": no segments"), so.so_name);
 	  else
 	    {
 	      ULONGEST orig_delta;
 	      int i;
 
-	      if (!symfile_map_offsets_to_segments (so->abfd, data.get (),
+	      if (!symfile_map_offsets_to_segments (so.abfd, data.get (),
 						    li->offsets,
 						    li->segment_bases.size (),
 						    li->segment_bases.data ()))
 		warning (_("\
-Could not relocate shared library \"%s\": bad offsets"), so->so_name);
+Could not relocate shared library \"%s\": bad offsets"), so.so_name);
 
 	      /* Find the range of addresses to report for this library in
 		 "info sharedlibrary".  Report any consecutive segments
@@ -397,11 +396,11 @@  Could not relocate shared library \"%s\": bad offsets"), so->so_name);
 		    break;
 		}
 
-	      so->addr_low = li->segment_bases[0];
-	      so->addr_high = (data->segments[i - 1].base
+	      so.addr_low = li->segment_bases[0];
+	      so.addr_high = (data->segments[i - 1].base
 			       + data->segments[i - 1].size
 			       + orig_delta);
-	      gdb_assert (so->addr_low <= so->addr_high);
+	      gdb_assert (so.addr_low <= so.addr_high);
 	    }
 	}
     }
diff --git a/gdb/solib.c b/gdb/solib.c
index 54a4c3942b0c..a85ea5458bce 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -537,14 +537,14 @@  get_cbfd_soname_build_id (gdb_bfd_ref_ptr abfd, const char *soname)
    expansion stuff?).  */
 
 static int
-solib_map_sections (struct so_list *so)
+solib_map_sections (so_list &so)
 {
   const target_so_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
 
-  gdb::unique_xmalloc_ptr<char> filename (tilde_expand (so->so_name));
+  gdb::unique_xmalloc_ptr<char> filename (tilde_expand (so.so_name));
   gdb_bfd_ref_ptr abfd (ops->bfd_open (filename.get ()));
   gdb::unique_xmalloc_ptr<char> build_id_hexstr
-    = get_cbfd_soname_build_id (current_program_space->cbfd, so->so_name);
+    = get_cbfd_soname_build_id (current_program_space->cbfd, so.so_name);
 
   /* If we already know the build-id of this solib from a core file, verify
      it matches ABFD's build-id.  If there is a mismatch or the solib wasn't
@@ -564,7 +564,7 @@  solib_map_sections (struct so_list *so)
 	{
 	  scoped_fd fd = debuginfod_exec_query ((const unsigned char*)
 						build_id_hexstr.get (),
-						0, so->so_name, &filename);
+						0, so.so_name, &filename);
 
 	  if (fd.get () >= 0)
 	    abfd = ops->bfd_open (filename.get ());
@@ -578,7 +578,7 @@  solib_map_sections (struct so_list *so)
     return 0;
 
   /* Leave bfd open, core_xfer_memory and "info files" need it.  */
-  so->abfd = abfd.release ();
+  so.abfd = abfd.release ();
 
   /* Copy the full path name into so_name, allowing symbol_file_add
      to find it later.  This also affects the =library-loaded GDB/MI
@@ -586,15 +586,15 @@  solib_map_sections (struct so_list *so)
      the library's host-side path.  If we let the target dictate
      that objfile's path, and the target is different from the host,
      GDB/MI will not provide the correct host-side path.  */
-  if (strlen (bfd_get_filename (so->abfd)) >= SO_NAME_MAX_PATH_SIZE)
+  if (strlen (bfd_get_filename (so.abfd)) >= SO_NAME_MAX_PATH_SIZE)
     error (_("Shared library file name is too long."));
-  strcpy (so->so_name, bfd_get_filename (so->abfd));
+  strcpy (so.so_name, bfd_get_filename (so.abfd));
 
-  if (so->sections == nullptr)
-    so->sections = new target_section_table;
-  *so->sections = build_section_table (so->abfd);
+  if (so.sections == nullptr)
+    so.sections = new target_section_table;
+  *so.sections = build_section_table (so.abfd);
 
-  for (target_section &p : *so->sections)
+  for (target_section &p : *so.sections)
     {
       /* Relocate the section binding addresses as recorded in the shared
 	 object's file by the base address to which the object was actually
@@ -604,11 +604,11 @@  solib_map_sections (struct so_list *so)
       /* If the target didn't provide information about the address
 	 range of the shared object, assume we want the location of
 	 the .text section.  */
-      if (so->addr_low == 0 && so->addr_high == 0
+      if (so.addr_low == 0 && so.addr_high == 0
 	  && strcmp (p.the_bfd_section->name, ".text") == 0)
 	{
-	  so->addr_low = p.addr;
-	  so->addr_high = p.endaddr;
+	  so.addr_low = p.addr;
+	  so.addr_high = p.endaddr;
 	}
     }
 
@@ -616,7 +616,7 @@  solib_map_sections (struct so_list *so)
      section tables.  Do this immediately after mapping the object so
      that later nodes in the list can query this object, as is needed
      in solib-osf.c.  */
-  current_program_space->add_target_sections (so, *so->sections);
+  current_program_space->add_target_sections (&so, *so.sections);
 
   return 1;
 }
@@ -631,25 +631,25 @@  solib_map_sections (struct so_list *so)
    responsible for taking care of that.  */
 
 static void
-clear_so (struct so_list *so)
+clear_so (so_list &so)
 {
   const target_so_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
 
-  delete so->sections;
-  so->sections = NULL;
+  delete so.sections;
+  so.sections = NULL;
 
-  gdb_bfd_unref (so->abfd);
-  so->abfd = NULL;
+  gdb_bfd_unref (so.abfd);
+  so.abfd = NULL;
 
   /* Our caller closed the objfile, possibly via objfile_purge_solibs.  */
-  so->symbols_loaded = 0;
-  so->objfile = NULL;
+  so.symbols_loaded = 0;
+  so.objfile = NULL;
 
-  so->addr_low = so->addr_high = 0;
+  so.addr_low = so.addr_high = 0;
 
   /* Restore the target-supplied file name.  SO_NAME may be the path
      of the symbol file.  */
-  strcpy (so->so_name, so->so_original_name);
+  strcpy (so.so_name, so.so_original_name);
 
   /* Do the same for target-specific data.  */
   if (ops->clear_so != NULL)
@@ -668,14 +668,14 @@  clear_so (struct so_list *so)
    responsible for taking care of that.  */
 
 void
-free_so (struct so_list *so)
+free_so (so_list &so)
 {
   const target_so_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
 
   clear_so (so);
   ops->free_so (so);
 
-  xfree (so);
+  xfree (&so);
 }
 
 
@@ -683,13 +683,13 @@  free_so (struct so_list *so)
    be chatty about it.  Return true if any symbols were actually loaded.  */
 
 bool
-solib_read_symbols (struct so_list *so, symfile_add_flags flags)
+solib_read_symbols (so_list &so, symfile_add_flags flags)
 {
-  if (so->symbols_loaded)
+  if (so.symbols_loaded)
     {
       /* If needed, we've already warned in our caller.  */
     }
-  else if (so->abfd == NULL)
+  else if (so.abfd == NULL)
     {
       /* We've already warned about this library, when trying to open
 	 it.  */
@@ -702,35 +702,35 @@  solib_read_symbols (struct so_list *so, symfile_add_flags flags)
       try
 	{
 	  /* Have we already loaded this shared object?  */
-	  so->objfile = nullptr;
+	  so.objfile = nullptr;
 	  for (objfile *objfile : current_program_space->objfiles ())
 	    {
-	      if (filename_cmp (objfile_name (objfile), so->so_name) == 0
-		  && objfile->addr_low == so->addr_low)
+	      if (filename_cmp (objfile_name (objfile), so.so_name) == 0
+		  && objfile->addr_low == so.addr_low)
 		{
-		  so->objfile = objfile;
+		  so.objfile = objfile;
 		  break;
 		}
 	    }
-	  if (so->objfile == NULL)
+	  if (so.objfile == NULL)
 	    {
 	      section_addr_info sap
-		= build_section_addr_info_from_section_table (*so->sections);
+		= build_section_addr_info_from_section_table (*so.sections);
 	      gdb_bfd_ref_ptr tmp_bfd
-		(gdb_bfd_ref_ptr::new_reference (so->abfd));
-	      so->objfile = symbol_file_add_from_bfd (tmp_bfd, so->so_name,
+		(gdb_bfd_ref_ptr::new_reference (so.abfd));
+	      so.objfile = symbol_file_add_from_bfd (tmp_bfd, so.so_name,
 						      flags, &sap,
 						      OBJF_SHARED, NULL);
-	      so->objfile->addr_low = so->addr_low;
+	      so.objfile->addr_low = so.addr_low;
 	    }
 
-	  so->symbols_loaded = 1;
+	  so.symbols_loaded = 1;
 	}
       catch (const gdb_exception_error &e)
 	{
 	  exception_fprintf (gdb_stderr, e, _("Error while reading shared"
 					      " library symbols for %s:\n"),
-			     so->so_name);
+			     so.so_name);
 	}
 
       return true;
@@ -754,7 +754,7 @@  solib_used (const struct so_list *const known)
 /* Notify interpreters and observers that solib SO has been loaded.  */
 
 static void
-notify_solib_loaded (so_list *so)
+notify_solib_loaded (so_list &so)
 {
   interps_notify_solib_loaded (so);
   gdb::observers::solib_loaded.notify (so);
@@ -763,7 +763,7 @@  notify_solib_loaded (so_list *so)
 /* Notify interpreters and observers that solib SO has been unloaded.  */
 
 static void
-notify_solib_unloaded (program_space *pspace, so_list *so)
+notify_solib_unloaded (program_space *pspace, const so_list &so)
 {
   interps_notify_solib_unloaded (so);
   gdb::observers::solib_unloaded.notify (pspace, so);
@@ -840,7 +840,7 @@  update_solib_list (int from_tty)
 	{
 	  if (ops->same)
 	    {
-	      if (ops->same (gdb, i))
+	      if (ops->same (*gdb, *i))
 		break;
 	    }
 	  else
@@ -859,7 +859,7 @@  update_solib_list (int from_tty)
       if (i)
 	{
 	  *i_link = i->next;
-	  free_so (i);
+	  free_so (*i);
 	  gdb_link = &gdb->next;
 	  gdb = *gdb_link;
 	}
@@ -869,7 +869,7 @@  update_solib_list (int from_tty)
 	{
 	  /* Notify any observer that the shared object has been
 	     unloaded before we remove it from GDB's tables.  */
-	  notify_solib_unloaded (current_program_space, gdb);
+	  notify_solib_unloaded (current_program_space, *gdb);
 
 	  current_program_space->deleted_solibs.push_back (gdb->so_name);
 
@@ -881,10 +881,10 @@  update_solib_list (int from_tty)
 	    gdb->objfile->unlink ();
 
 	  /* Some targets' section tables might be referring to
-	     sections from so->abfd; remove them.  */
+	     sections from so.abfd; remove them.  */
 	  current_program_space->remove_target_sections (gdb);
 
-	  free_so (gdb);
+	  free_so (*gdb);
 	  gdb = *gdb_link;
 	}
     }
@@ -910,7 +910,7 @@  update_solib_list (int from_tty)
 	  try
 	    {
 	      /* Fill in the rest of the `struct so_list' node.  */
-	      if (!solib_map_sections (i))
+	      if (!solib_map_sections (*i))
 		{
 		  not_found++;
 		  if (not_found_filename == NULL)
@@ -927,7 +927,7 @@  update_solib_list (int from_tty)
 
 	  /* Notify any observer that the shared object has been
 	     loaded now that we've added it to GDB's tables.  */
-	  notify_solib_loaded (i);
+	  notify_solib_loaded (*i);
 	}
 
       /* If a library was not found, issue an appropriate warning
@@ -972,9 +972,9 @@  libpthread_name_p (const char *name)
 /* Return non-zero if SO is the libpthread shared library.  */
 
 static bool
-libpthread_solib_p (struct so_list *so)
+libpthread_solib_p (const so_list &so)
 {
-  return libpthread_name_p (so->so_name);
+  return libpthread_name_p (so.so_name);
 }
 
 /* Read in symbolic information for any shared objects whose names
@@ -1032,7 +1032,7 @@  solib_add (const char *pattern, int from_tty, int readsyms)
 	     need the library symbols to be loaded in order to provide
 	     thread support (x86-linux for instance).  */
 	  const int add_this_solib =
-	    (readsyms || libpthread_solib_p (gdb));
+	    (readsyms || libpthread_solib_p (*gdb));
 
 	  any_matches = true;
 	  if (add_this_solib)
@@ -1045,7 +1045,7 @@  solib_add (const char *pattern, int from_tty, int readsyms)
 		    gdb_printf (_("Symbols already loaded for %s\n"),
 				gdb->so_name);
 		}
-	      else if (solib_read_symbols (gdb, add_flags))
+	      else if (solib_read_symbols (*gdb, add_flags))
 		loaded_any_symbols = true;
 	    }
 	}
@@ -1172,13 +1172,13 @@  info_sharedlibrary_command (const char *pattern, int from_tty)
 /* See solib.h.  */
 
 bool
-solib_contains_address_p (const struct so_list *const solib,
+solib_contains_address_p (const so_list &solib,
 			  CORE_ADDR address)
 {
-  if (solib->sections == nullptr)
+  if (solib.sections == nullptr)
     return false;
 
-  for (target_section &p : *solib->sections)
+  for (target_section &p : *solib.sections)
     if (p.addr <= address && address < p.endaddr)
       return true;
 
@@ -1202,7 +1202,7 @@  solib_name_from_address (struct program_space *pspace, CORE_ADDR address)
   struct so_list *so = NULL;
 
   for (so = pspace->so_list; so; so = so->next)
-    if (solib_contains_address_p (so, address))
+    if (solib_contains_address_p (*so, address))
       return (so->so_name);
 
   return (0);
@@ -1235,9 +1235,9 @@  clear_solib (void)
       struct so_list *so = current_program_space->so_list;
 
       current_program_space->so_list = so->next;
-      notify_solib_unloaded (current_program_space, so);
+      notify_solib_unloaded (current_program_space, *so);
       current_program_space->remove_target_sections (so);
-      free_so (so);
+      free_so (*so);
     }
 
   if (ops->clear_solib != nullptr)
@@ -1358,7 +1358,7 @@  reload_shared_libraries_1 (int from_tty)
 	      && !solib_used (so))
 	    so->objfile->unlink ();
 	  current_program_space->remove_target_sections (so);
-	  clear_so (so);
+	  clear_so (*so);
 	}
 
       /* If this shared library is now associated with a new symbol
@@ -1371,7 +1371,7 @@  reload_shared_libraries_1 (int from_tty)
 
 	  try
 	    {
-	      solib_map_sections (so);
+	      solib_map_sections (*so);
 	    }
 
 	  catch (const gdb_exception_error &e)
@@ -1383,8 +1383,8 @@  reload_shared_libraries_1 (int from_tty)
 	    }
 
 	    if (!got_error
-		&& (auto_solib_add || was_loaded || libpthread_solib_p (so)))
-	      solib_read_symbols (so, add_flags);
+		&& (auto_solib_add || was_loaded || libpthread_solib_p (*so)))
+	      solib_read_symbols (*so, add_flags);
 	}
     }
 }
diff --git a/gdb/solib.h b/gdb/solib.h
index 77e023002edf..50b154b2b9b6 100644
--- a/gdb/solib.h
+++ b/gdb/solib.h
@@ -50,7 +50,7 @@  extern void clear_solib (void);
 /* Called to add symbols from a shared library to gdb's symbol table.  */
 
 extern void solib_add (const char *, int, int);
-extern bool solib_read_symbols (struct so_list *, symfile_add_flags);
+extern bool solib_read_symbols (so_list &, symfile_add_flags);
 
 /* Function to be called when the inferior starts up, to discover the
    names of shared libraries that are dynamically linked, the base
@@ -65,7 +65,7 @@  extern const char *solib_name_from_address (struct program_space *, CORE_ADDR);
 
 /* Return true if ADDR lies within SOLIB.  */
 
-extern bool solib_contains_address_p (const struct so_list *, CORE_ADDR);
+extern bool solib_contains_address_p (const so_list &, CORE_ADDR);
 
 /* Return whether the data starting at VADDR, size SIZE, must be kept
    in a core file for shared libraries loaded before "gcore" is used
diff --git a/gdb/solist.h b/gdb/solist.h
index b3a06b88c439..5d648900d29d 100644
--- a/gdb/solist.h
+++ b/gdb/solist.h
@@ -84,17 +84,16 @@  struct target_so_ops
 {
   /* Adjust the section binding addresses by the base address at
      which the object was actually mapped.  */
-  void (*relocate_section_addresses) (struct so_list *so,
-				      struct target_section *);
+  void (*relocate_section_addresses) (so_list &so, target_section *);
 
   /* Free the link map info and any other private data structures
      associated with a so_list entry.  */
-  void (*free_so) (struct so_list *so);
+  void (*free_so) (so_list &so);
 
   /* Reset private data structures associated with SO.
      This is called when SO is about to be reloaded.
      It is also called before free_so when SO is about to be freed.  */
-  void (*clear_so) (struct so_list *so);
+  void (*clear_so) (const so_list &so);
 
   /* Free private data structures associated to PSPACE.  This method
      should not free resources associated to individual so_list entries,
@@ -137,7 +136,7 @@  struct target_so_ops
      if they represent the same library.
      Falls back to using strcmp on so_original_name field when set
      to NULL.  */
-  int (*same) (struct so_list *gdb, struct so_list *inferior);
+  int (*same) (const so_list &gdb, const so_list &inferior);
 
   /* Return whether a region of memory must be kept in a core file
      for shared libraries loaded before "gcore" is used to be
@@ -164,14 +163,14 @@  struct target_so_ops
 using so_list_range = next_range<so_list>;
 
 /* Free the memory associated with a (so_list *).  */
-void free_so (struct so_list *so);
+void free_so (so_list &so);
 
 /* A deleter that calls free_so.  */
 struct so_deleter
 {
   void operator() (struct so_list *so) const
   {
-    free_so (so);
+    free_so (*so);
   }
 };
 
diff --git a/gdb/target-section.h b/gdb/target-section.h
index 9dc716b732bd..5d7c846a6e25 100644
--- a/gdb/target-section.h
+++ b/gdb/target-section.h
@@ -48,7 +48,7 @@  struct target_section
      and used by remove_target_sections.
      For example, for executables it is a pointer to exec_bfd and
      for shlibs it is the so_list pointer.  */
-  void *owner;
+  const void *owner;
 };
 
 /* Holds an array of target sections.  */