From d7fa2ae2549091f294e6dd103a57ddf1219dfe6c Mon Sep 17 00:00:00 2001
From: Kevin Buettner <kevinb@redhat.com>
Date: Thu, 22 Feb 2001 03:01:27 +0000
Subject: [PATCH] Made changes to shared library support and added more of the
 support needed for AIX/IA-64.

---
 gdb/ChangeLog            |  34 +++++++++
 gdb/config/ia64/aix.mh   |   9 +++
 gdb/config/ia64/aix.mt   |   4 +
 gdb/config/ia64/linux.mt |   2 +-
 gdb/config/ia64/nm-aix.h |  34 +++++++++
 gdb/config/ia64/tm-aix.h |  32 ++++++++
 gdb/config/ia64/xm-aix.h |  33 ++++++++
 gdb/ia64-aix-nat.c       | 160 +++++++++++++++++++++++++++++++++++++++
 gdb/ia64-aix-tdep.c      | 107 ++++++++++++++++++++++++++
 gdb/ia64-tdep.c          |  12 ++-
 gdb/solib-aix5.c         |   9 +--
 gdb/solib-svr4.c         |  20 +++--
 gdb/solib.c              |  21 +++++
 gdb/solib.h              |  10 +--
 gdb/solist.h             |   6 ++
 15 files changed, 471 insertions(+), 22 deletions(-)
 create mode 100644 gdb/config/ia64/aix.mh
 create mode 100644 gdb/config/ia64/aix.mt
 create mode 100644 gdb/config/ia64/nm-aix.h
 create mode 100644 gdb/config/ia64/tm-aix.h
 create mode 100644 gdb/config/ia64/xm-aix.h
 create mode 100644 gdb/ia64-aix-nat.c
 create mode 100644 gdb/ia64-aix-tdep.c

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 379e177006..3d555453a2 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,37 @@
+2001-02-21  Kevin Buettner  <kevinb@redhat.com>
+
+	* solib.h (in_svr4_dynsym_resolve_code): Delete declaration.
+	(in_solib_dynsym_resolve_code): Add declaration.
+	(IN_SOLIB_DYNSYM_RESOLVE_CODE): Changed define to invoke
+	in_solib_dynsym_resolve_code() rather than
+	in_svr4_dynsym_resolve_code().  Also, removed the ifdefs
+	which caused this macro to only be defined when
+	SVR4_SHARED_LIBS is defined.
+	* solib.c (in_solib_dynsym_resolve_code): New function.
+	* solist.h (struct target_so_ops): Add new member
+	in_dynsym_resolve_code.
+	* solib-aix5.c (aix5_in_dynsym_resolve_code): Renamed from
+	in_svr4_dynsym_resolve_code.  Also, made static.
+	(_initialize_aix5_solib): Initialize in_dynsym_resolve_code
+	member in aix5_so_ops.
+	* solib-svr4.c (svr4_in_dynsym_resolve_code): Renamed from
+	in_svr4_dynsym_resolve_code.  Also, added second version
+	of this function which will be used when SVR4_SHARED_LIBS
+	is not defined.
+	(_initialize_svr4_solib): Initialize in_dynsym_resolve_code
+	member in svr4_so_ops.
+
+	* ia64-aix-nat.c, ia64-aix-tdep.c, config/ia64/aix.mh,
+	config/ia64/aix.mt, config/ia64/nm-aix.h, config/ia64/tm-aix.h,
+	config/ia64/xm-aix.h: New files.
+	* ia64-tdep.c (_initialize_ia64_tdep): Remove declaration.
+	(ia64_aix_sigcontext_register_address): New declaration.
+	(ia64_gdbarch_init): Provide for intialization of 
+	sigcontext_register_address member of struct tdep when
+	on target is detected to be running AIX.
+	* config/ia64/linux.mt (TDEPFILES): Add ia64-aix-tdep.o to
+	this list.
+
 2001-02-20  Kevin Buettner  <kevinb@redhat.com>
 
 	* ia64-tdep.c (ia64_frameless_function_invocation): Implement.
diff --git a/gdb/config/ia64/aix.mh b/gdb/config/ia64/aix.mh
new file mode 100644
index 0000000000..51ba74348f
--- /dev/null
+++ b/gdb/config/ia64/aix.mh
@@ -0,0 +1,9 @@
+# Host: Intel IA-64 running AIX
+
+XM_FILE= xm-aix.h
+XDEPFILES=
+
+NAT_FILE= nm-aix.h
+NATDEPFILES= corelow.o core-regset.o solib.o solib-aix5.o fork-child.o \
+	procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o \
+	ia64-aix-nat.o
diff --git a/gdb/config/ia64/aix.mt b/gdb/config/ia64/aix.mt
new file mode 100644
index 0000000000..0348146c3f
--- /dev/null
+++ b/gdb/config/ia64/aix.mt
@@ -0,0 +1,4 @@
+# Target: Intel IA-64 running AIX
+
+TDEPFILES= ia64-tdep.o ia64-linux-tdep.o ia64-aix-tdep.o
+TM_FILE= tm-aix.h
diff --git a/gdb/config/ia64/linux.mt b/gdb/config/ia64/linux.mt
index 441055dc1b..e536ef2b87 100644
--- a/gdb/config/ia64/linux.mt
+++ b/gdb/config/ia64/linux.mt
@@ -1,5 +1,5 @@
 # Target: Intel IA-64 running GNU/Linux
-TDEPFILES= ia64-tdep.o ia64-linux-tdep.o solib.o solib-svr4.o 
+TDEPFILES= ia64-tdep.o ia64-aix-tdep.o ia64-linux-tdep.o solib.o solib-svr4.o 
 TM_FILE= tm-linux.h
 
 GDBSERVER_DEPFILES= low-linux.o
diff --git a/gdb/config/ia64/nm-aix.h b/gdb/config/ia64/nm-aix.h
new file mode 100644
index 0000000000..4685aeaae3
--- /dev/null
+++ b/gdb/config/ia64/nm-aix.h
@@ -0,0 +1,34 @@
+/* Native support for AIX, for GDB, the GNU debugger.
+   Copyright (C) 2000, 2001 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef NM_AIX_H
+#define NM_AIX_H
+
+#include "nm-sysv4.h"
+
+#ifndef MONTEREY
+#define MONTEREY 1
+#endif
+
+/* Type of the operation code for sending control messages to the
+   /proc/PID/ctl file */
+#define PROC_CTL_WORD_TYPE int
+
+#endif /* #ifndef NM_AIX_H */
diff --git a/gdb/config/ia64/tm-aix.h b/gdb/config/ia64/tm-aix.h
new file mode 100644
index 0000000000..91068f81f6
--- /dev/null
+++ b/gdb/config/ia64/tm-aix.h
@@ -0,0 +1,32 @@
+/* Definitions to target GDB to GNU/Linux on IA-64 running AIX.
+   Copyright (C) 2000, 2001 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef TM_AIX_H
+#define TM_AIX_H
+
+#include "ia64/tm-ia64.h"
+#include "tm-sysv4.h"
+
+#define TARGET_ELF64
+
+extern int ia64_aix_in_sigtramp (CORE_ADDR pc, char *func_name);
+#define IN_SIGTRAMP(pc,func_name) ia64_aix_in_sigtramp (pc, func_name)
+
+#endif /* #ifndef TM_AIX_H */
diff --git a/gdb/config/ia64/xm-aix.h b/gdb/config/ia64/xm-aix.h
new file mode 100644
index 0000000000..dae8e95093
--- /dev/null
+++ b/gdb/config/ia64/xm-aix.h
@@ -0,0 +1,33 @@
+/* Native support for AIX, for GDB, the GNU debugger.
+   Copyright (C) 2000, 2001 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef XM_AIX_H
+#define XM_AIX_H
+
+#define HOST_BYTE_ORDER LITTLE_ENDIAN
+
+/* Pick up more stuff from the generic SVR4 host include file. */
+
+#include "xm-sysv4.h"
+
+#define GDB_GREGSET_T prgregset_t
+#define GDB_FPREGSET_T prfpregset_t
+
+#endif /* #ifndef XM_AIX_H */
diff --git a/gdb/ia64-aix-nat.c b/gdb/ia64-aix-nat.c
new file mode 100644
index 0000000000..3d747882c7
--- /dev/null
+++ b/gdb/ia64-aix-nat.c
@@ -0,0 +1,160 @@
+/* Functions specific to running gdb native on IA-64 running AIX.
+   Copyright 2000, 2001 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+#include "inferior.h"
+#include "target.h"
+#include "gdbcore.h"
+#include <sys/procfs.h>
+
+#include "symtab.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "objfiles.h"
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include "gdb_stat.h"
+
+void
+supply_gregset (prgregset_t *gregsetp)
+{
+  int regi;
+
+  for (regi = IA64_GR0_REGNUM; regi <= IA64_GR31_REGNUM; regi++)
+    {
+      supply_register (regi, 
+                       (char *) &(gregsetp->__gpr[regi - IA64_GR0_REGNUM]));
+    }
+
+  for (regi = IA64_BR0_REGNUM; regi <= IA64_BR7_REGNUM; regi++)
+    {
+      supply_register (regi, 
+                       (char *) &(gregsetp->__br[regi - IA64_BR0_REGNUM]));
+    }
+
+  supply_register (IA64_PSR_REGNUM, (char *) &(gregsetp->__psr));
+  supply_register (IA64_IP_REGNUM, (char *) &(gregsetp->__ip));
+  supply_register (IA64_CFM_REGNUM, (char *) &(gregsetp->__ifs));
+  supply_register (IA64_RSC_REGNUM, (char *) &(gregsetp->__rsc));
+  supply_register (IA64_BSP_REGNUM, (char *) &(gregsetp->__bsp));
+  supply_register (IA64_BSPSTORE_REGNUM, (char *) &(gregsetp->__bspstore));
+  supply_register (IA64_RNAT_REGNUM, (char *) &(gregsetp->__rnat));
+  supply_register (IA64_PFS_REGNUM, (char *) &(gregsetp->__pfs));
+  supply_register (IA64_UNAT_REGNUM, (char *) &(gregsetp->__unat));
+  supply_register (IA64_PR_REGNUM, (char *) &(gregsetp->__preds));
+  supply_register (IA64_CCV_REGNUM, (char *) &(gregsetp->__ccv));
+  supply_register (IA64_LC_REGNUM, (char *) &(gregsetp->__lc));
+  supply_register (IA64_EC_REGNUM, (char *) &(gregsetp->__ec));
+  /* FIXME: __nats */
+  supply_register (IA64_FPSR_REGNUM, (char *) &(gregsetp->__fpsr));
+
+  /* These (for the most part) are pseudo registers and are obtained
+     by other means.  Those that aren't are already handled by the
+     code above.  */
+  for (regi = IA64_GR32_REGNUM; regi <= IA64_GR127_REGNUM; regi++)
+    register_valid[regi] = 1;
+  for (regi = IA64_PR0_REGNUM; regi <= IA64_PR63_REGNUM; regi++)
+    register_valid[regi] = 1;
+  for (regi = IA64_VFP_REGNUM; regi <= NUM_REGS; regi++)
+    register_valid[regi] = 1;
+}
+
+void
+fill_gregset (prgregset_t *gregsetp, int regno)
+{
+  int regi;
+
+#define COPY_REG(_fld_,_regi_) \
+  if ((regno == -1) || regno == _regi_) \
+    memcpy (&(gregsetp->_fld_), &registers[REGISTER_BYTE (_regi_)], \
+	    REGISTER_RAW_SIZE (_regi_))
+
+  for (regi = IA64_GR0_REGNUM; regi <= IA64_GR31_REGNUM; regi++)
+    {
+      COPY_REG (__gpr[regi - IA64_GR0_REGNUM], regi);
+    }
+
+  for (regi = IA64_BR0_REGNUM; regi <= IA64_BR7_REGNUM; regi++)
+    {
+      COPY_REG (__br[regi - IA64_BR0_REGNUM], regi);
+    }
+  COPY_REG (__psr, IA64_PSR_REGNUM);
+  COPY_REG (__ip, IA64_IP_REGNUM);
+  COPY_REG (__ifs, IA64_CFM_REGNUM);
+  COPY_REG (__rsc, IA64_RSC_REGNUM);
+  COPY_REG (__bsp, IA64_BSP_REGNUM);
+
+  /* Bad things happen if we don't update both bsp and bspstore at the
+     same time.  */
+  if (regno == IA64_BSP_REGNUM || regno == -1)
+    {
+      memcpy (&(gregsetp->__bspstore),
+	      &registers[REGISTER_BYTE (IA64_BSP_REGNUM)],
+	      REGISTER_RAW_SIZE (IA64_BSP_REGNUM));
+      memcpy (&registers[REGISTER_BYTE (IA64_BSPSTORE_REGNUM)],
+	      &registers[REGISTER_BYTE (IA64_BSP_REGNUM)],
+	      REGISTER_RAW_SIZE (IA64_BSP_REGNUM));
+    }
+
+#if 0
+  /* We never actually write to bspstore, or we'd have to do the same thing
+     here too.  */
+  COPY_REG (__bspstore, IA64_BSPSTORE_REGNUM);
+#endif
+  COPY_REG (__rnat, IA64_RNAT_REGNUM);
+  COPY_REG (__pfs, IA64_PFS_REGNUM);
+  COPY_REG (__unat, IA64_UNAT_REGNUM);
+  COPY_REG (__preds, IA64_PR_REGNUM);
+  COPY_REG (__ccv, IA64_CCV_REGNUM);
+  COPY_REG (__lc, IA64_LC_REGNUM);
+  COPY_REG (__ec, IA64_EC_REGNUM);
+  /* FIXME: __nats */
+  COPY_REG (__fpsr, IA64_FPSR_REGNUM);
+#undef COPY_REG
+}
+
+void
+supply_fpregset (prfpregset_t *fpregsetp)
+{
+  register int regi;
+
+  for (regi = IA64_FR0_REGNUM; regi <= IA64_FR127_REGNUM; regi++)
+    supply_register (regi, 
+                     (char *) &(fpregsetp->__fpr[regi - IA64_FR0_REGNUM]));
+}
+
+void
+fill_fpregset (prfpregset_t *fpregsetp, int regno)
+{
+  int regi;
+  char *to;
+  char *from;
+
+  for (regi = IA64_FR0_REGNUM; regi <= IA64_FR127_REGNUM; regi++)
+    {
+      if ((regno == -1) || (regno == regi))
+	{
+	  from = (char *) &registers[REGISTER_BYTE (regi)];
+	  to = (char *) &(fpregsetp->__fpr[regi - IA64_FR0_REGNUM]);
+	  memcpy (to, from, REGISTER_RAW_SIZE (regi));
+	}
+    }
+}
diff --git a/gdb/ia64-aix-tdep.c b/gdb/ia64-aix-tdep.c
new file mode 100644
index 0000000000..26eca6b59c
--- /dev/null
+++ b/gdb/ia64-aix-tdep.c
@@ -0,0 +1,107 @@
+/* Target-dependent code for the IA-64 for GDB, the GNU debugger.
+   Copyright 2000, 2001
+   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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+
+/* External hook for finding gate addresses on AIX.  */
+void (*aix5_find_gate_addresses_hook) (CORE_ADDR *, CORE_ADDR *) = 0;
+
+/* Offset to sc_context member of sigcontext structure from frame of handler */
+#define IA64_AIX_SIGCONTEXT_OFFSET 64
+
+/* Return a non-zero value iff PC is in a signal trampoline.  On
+   AIX, we determine this by seeing if the pc is in a special
+   execute only page called the ``gate page''.  The addresses in
+   question are determined by letting the AIX native portion of
+   the code determine these addresses via its own nefarious
+   means.  */
+
+int
+ia64_aix_in_sigtramp (CORE_ADDR pc, char *func_name)
+{
+  CORE_ADDR gate_area_start, gate_area_end;
+
+  if (aix5_find_gate_addresses_hook == 0)
+    return 0;
+
+  (*aix5_find_gate_addresses_hook) (&gate_area_start, &gate_area_end);
+
+  return (pc >=  gate_area_start && pc < gate_area_end);
+}
+
+
+/* IA-64 AIX specific function which, given a frame address and
+   a register number, returns the address at which that register may be
+   found.  0 is returned for registers which aren't stored in the
+   sigcontext structure.  */
+
+CORE_ADDR
+ia64_aix_sigcontext_register_address (CORE_ADDR sp, int regno)
+{
+  /* The hardcoded offsets that follow are actually offsets to the
+     corresponding members in struct __context in
+     /usr/include/sys/context.h (on an IA-64 AIX5 box).  */
+  if (IA64_GR0_REGNUM <= regno && regno <= IA64_GR31_REGNUM)
+    return sp + IA64_AIX_SIGCONTEXT_OFFSET + 152 + 8 * (regno - IA64_GR0_REGNUM);
+  else if (IA64_BR0_REGNUM <= regno && regno <= IA64_BR7_REGNUM)
+    return sp + IA64_AIX_SIGCONTEXT_OFFSET + 408 + 8 * (regno - IA64_BR0_REGNUM);
+  else if (IA64_FR0_REGNUM <= regno && regno <= IA64_FR127_REGNUM)
+    return sp + IA64_AIX_SIGCONTEXT_OFFSET + 480 + 16 * (regno - IA64_FR0_REGNUM);
+  else
+    switch (regno)
+      {
+      case IA64_PSR_REGNUM :
+	return sp + IA64_AIX_SIGCONTEXT_OFFSET + 0;
+      case IA64_IP_REGNUM :
+	return sp + IA64_AIX_SIGCONTEXT_OFFSET + 8;
+      /* iipa is at 16.
+         isr is at 24.
+	 ifa is at 32.
+	 iim is at 40. */
+      case IA64_CFM_REGNUM :
+	return sp + IA64_AIX_SIGCONTEXT_OFFSET + 48;  /* ifs, actually */
+      case IA64_RSC_REGNUM :
+	return sp + IA64_AIX_SIGCONTEXT_OFFSET + 56;
+      case IA64_BSP_REGNUM :
+	return sp + IA64_AIX_SIGCONTEXT_OFFSET + 64;
+      case IA64_BSPSTORE_REGNUM :
+	return sp + IA64_AIX_SIGCONTEXT_OFFSET + 72;
+      case IA64_RNAT_REGNUM :
+	return sp + IA64_AIX_SIGCONTEXT_OFFSET + 80;
+      case IA64_PFS_REGNUM :
+	return sp + IA64_AIX_SIGCONTEXT_OFFSET + 88;
+      case IA64_UNAT_REGNUM :
+	return sp + IA64_AIX_SIGCONTEXT_OFFSET + 96;
+      case IA64_PR_REGNUM :
+	return sp + IA64_AIX_SIGCONTEXT_OFFSET + 104;
+      case IA64_CCV_REGNUM :
+	return sp + IA64_AIX_SIGCONTEXT_OFFSET + 112;
+      case IA64_LC_REGNUM :
+	return sp + IA64_AIX_SIGCONTEXT_OFFSET + 120;
+      case IA64_EC_REGNUM :
+	return sp + IA64_AIX_SIGCONTEXT_OFFSET + 128;
+      /* nats is at 136; this is an address independent NaT bitmask */
+      case IA64_FPSR_REGNUM :
+	return sp + IA64_AIX_SIGCONTEXT_OFFSET + 144;
+      default :
+	return 0;
+      }
+}
diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c
index e68c5fb1e5..eb7472749f 100644
--- a/gdb/ia64-tdep.c
+++ b/gdb/ia64-tdep.c
@@ -76,9 +76,9 @@ typedef enum instruction_type
 
 #define BUNDLE_LEN 16
 
-extern void _initialize_ia64_tdep (void);
-
+/* FIXME: These extern declarations should go in ia64-tdep.h.  */
 extern CORE_ADDR ia64_linux_sigcontext_register_address (CORE_ADDR, int);
+extern CORE_ADDR ia64_aix_sigcontext_register_address (CORE_ADDR, int);
 
 static gdbarch_init_ftype ia64_gdbarch_init;
 
@@ -1970,8 +1970,16 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   gdbarch = gdbarch_alloc (&info, tdep);
   tdep->os_ident = os_ident;
 
+
+  /* Set the method of obtaining the sigcontext addresses at which
+     registers are saved.  The method of checking to see if
+     native_find_global_pointer is nonzero to indicate that we're
+     on AIX is kind of hokey, but I can't think of a better way
+     to do it.  */
   if (os_ident == ELFOSABI_LINUX)
     tdep->sigcontext_register_address = ia64_linux_sigcontext_register_address;
+  else if (native_find_global_pointer != 0)
+    tdep->sigcontext_register_address = ia64_aix_sigcontext_register_address;
   else
     tdep->sigcontext_register_address = 0;
 
diff --git a/gdb/solib-aix5.c b/gdb/solib-aix5.c
index 1eddafe612..bfe7f462fa 100644
--- a/gdb/solib-aix5.c
+++ b/gdb/solib-aix5.c
@@ -409,9 +409,8 @@ static CORE_ADDR interp_text_sect_high;
 static CORE_ADDR interp_plt_sect_low;
 static CORE_ADDR interp_plt_sect_high;
 
-/* FIXME: Does this belong here?  (If it does, it ought to be renamed.) */
-int
-in_svr4_dynsym_resolve_code (CORE_ADDR pc)
+static int
+aix5_in_dynsym_resolve_code (CORE_ADDR pc)
 {
   return ((pc >= interp_text_sect_low && pc < interp_text_sect_high)
 	  || (pc >= interp_plt_sect_low && pc < interp_plt_sect_high)
@@ -496,7 +495,7 @@ enable_break (void)
       load_addr = read_pc () - tmp_bfd->start_address;
 
       /* Record the relocated start and end address of the dynamic linker
-         text and plt section for in_aix5_dynsym_resolve_code.  */
+         text and plt section for aix5_in_dynsym_resolve_code.  */
       interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
       if (interp_sect)
 	{
@@ -792,6 +791,7 @@ _initialize_aix5_solib (void)
   aix5_so_ops.special_symbol_handling = aix5_special_symbol_handling;
   aix5_so_ops.current_sos = aix5_current_sos;
   aix5_so_ops.open_symbol_file_object = open_symbol_file_object;
+  aix5_so_ops.in_dynsym_resolve_code = aix5_in_dynsym_resolve_code;
 
   native_find_global_pointer = aix5_find_global_pointer;
   aix5_find_gate_addresses_hook = aix5_find_gate_addresses;
@@ -799,4 +799,3 @@ _initialize_aix5_solib (void)
   /* FIXME: Don't do this here.  *_gdbarch_init() should set so_ops. */
   current_target_so_ops = &aix5_so_ops;
 }
-
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 07cd2d0d9e..1c451f39f4 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -1085,24 +1085,28 @@ match_main (char *soname)
 }
 
 
-#ifdef SVR4_SHARED_LIBS
-
 /* Return 1 if PC lies in the dynamic symbol resolution code of the
    SVR4 run time loader.  */
-
+#ifdef SVR4_SHARED_LIBS
 static CORE_ADDR interp_text_sect_low;
 static CORE_ADDR interp_text_sect_high;
 static CORE_ADDR interp_plt_sect_low;
 static CORE_ADDR interp_plt_sect_high;
 
-int
-in_svr4_dynsym_resolve_code (CORE_ADDR pc)
+static int
+svr4_in_dynsym_resolve_code (CORE_ADDR pc)
 {
   return ((pc >= interp_text_sect_low && pc < interp_text_sect_high)
 	  || (pc >= interp_plt_sect_low && pc < interp_plt_sect_high)
 	  || in_plt_section (pc, NULL));
 }
-#endif
+#else /* !SVR4_SHARED_LIBS */
+static int
+svr4_in_dynsym_resolve_code (CORE_ADDR pc)
+{
+  return 0;
+}
+#endif /* SVR4_SHARED_LIBS */
 
 /*
 
@@ -1303,7 +1307,7 @@ enable_break (void)
       load_addr = read_pc () - tmp_bfd->start_address;
 
       /* Record the relocated start and end address of the dynamic linker
-         text and plt section for in_svr4_dynsym_resolve_code.  */
+         text and plt section for svr4_in_dynsym_resolve_code.  */
       interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
       if (interp_sect)
 	{
@@ -1694,6 +1698,8 @@ _initialize_svr4_solib (void)
   svr4_so_ops.special_symbol_handling = svr4_special_symbol_handling;
   svr4_so_ops.current_sos = svr4_current_sos;
   svr4_so_ops.open_symbol_file_object = open_symbol_file_object;
+  svr4_so_ops.open_symbol_file_object = open_symbol_file_object;
+  svr4_so_ops.in_dynsym_resolve_code = svr4_in_dynsym_resolve_code;
 
   /* FIXME: Don't do this here.  *_gdbarch_init() should set so_ops. */
   current_target_so_ops = &svr4_so_ops;
diff --git a/gdb/solib.c b/gdb/solib.c
index 07d72ec121..291ac3386a 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -765,6 +765,27 @@ solib_create_inferior_hook (void)
   TARGET_SO_SOLIB_CREATE_INFERIOR_HOOK ();
 }
 
+/* GLOBAL FUNCTION
+
+   in_solib_dynsym_resolve_code -- check to see if an address is in
+                                   dynamic loader's dynamic symbol
+				   resolution code
+
+   SYNOPSIS
+
+   int in_solib_dynsym_resolve_code (CORE_ADDR pc)
+
+   DESCRIPTION
+
+   Determine if PC is in the dynamic linker's symbol resolution
+   code.  Return 1 if so, 0 otherwise.
+*/
+
+int
+in_solib_dynsym_resolve_code (CORE_ADDR pc)
+{
+  return TARGET_SO_IN_DYNSYM_RESOLVE_CODE (pc);
+}
 
 /*
 
diff --git a/gdb/solib.h b/gdb/solib.h
index dd8b23cff8..6022ea25e8 100644
--- a/gdb/solib.h
+++ b/gdb/solib.h
@@ -186,13 +186,9 @@ extern char *solib_address (CORE_ADDR);	/* solib.c */
 
 #define PC_SOLIB(addr)	solib_address (addr)
 
-#ifdef SVR4_SHARED_LIBS
-
 /* Return 1 if PC lies in the dynamic symbol resolution code of the
-   SVR4 run time loader.  */
-
-#define IN_SOLIB_DYNSYM_RESOLVE_CODE(pc) in_svr4_dynsym_resolve_code (pc)
+   run time loader.  */
 
-extern int in_svr4_dynsym_resolve_code (CORE_ADDR);
+#define IN_SOLIB_DYNSYM_RESOLVE_CODE(pc) in_solib_dynsym_resolve_code (pc)
 
-#endif
+extern int in_solib_dynsym_resolve_code (CORE_ADDR);	/* solib.c */
diff --git a/gdb/solist.h b/gdb/solist.h
index 29252505ad..141fd7fc00 100644
--- a/gdb/solist.h
+++ b/gdb/solist.h
@@ -89,6 +89,10 @@ struct target_so_ops
 
     /* Find, open, and read the symbols for the main executable.  */
     int (*open_symbol_file_object) (void *from_ttyp);
+
+    /* Determine if PC lies in the dynamic symbol resolution code of
+       the run time loader */
+    int (*in_dynsym_resolve_code) (CORE_ADDR pc);
   };
 
 void free_so (struct so_list *so);
@@ -110,3 +114,5 @@ extern struct target_so_ops *current_target_so_ops;
 #define TARGET_SO_CURRENT_SOS (current_target_so_ops->current_sos)
 #define TARGET_SO_OPEN_SYMBOL_FILE_OBJECT \
   (current_target_so_ops->open_symbol_file_object)
+#define TARGET_SO_IN_DYNSYM_RESOLVE_CODE \
+  (current_target_so_ops->in_dynsym_resolve_code)
-- 
2.42.0