Reimplement shared library support on ppc-aix...
authorJoel Brobecker <brobecker@gnat.com>
Mon, 6 May 2013 14:15:50 +0000 (14:15 +0000)
committerJoel Brobecker <brobecker@gnat.com>
Mon, 6 May 2013 14:15:50 +0000 (14:15 +0000)
... using the target_so_ops framework.

gdb/ChangeLog:

        * target.h (TARGET_OBJECT_AIX_LIBRARIES): New target_object enum.
        * features/library-list-aix.dtd: New file.
        * solib-aix.h, solib-aix.c: New file.
        * rs6000-aix-tdep.c: #include "solib.h" and "solib-aix.h".
        (rs6000_find_toc_address_hook): Delete.
        (rs6000_push_dummy_call): Rewrite code setting the TOC value.
        (rs6000_aix_init_osabi): Register solib_aix_so_ops.
        * rs6000-nat.c: Remove "xcoffsolib.h" include.  Include
        "xml-utils.h".
        (map_vmap, vmap_exec, vmap_ldinfo, add_vmap, objfile_symbol_add)
        (vmap_symtab, fixup_breakpoints): Delete.
        (rs6000_xfer_shared_libraries): New function.
        (rs6000_xfer_partial): Add TARGET_OBJECT_AIX_LIBRARIES handling.
        (vmap_secs, bss_data_overlap, vmap_add_symbols): Delete.
        (xcoff_relocate_symtab, xcoff_relocate_core): Delete.
        (rs6000_ptrace_ldinfo, rs6000_core_ldinfo)
        (rs6000_xfer_shared_library): New function.
        (find_toc_address): Delete.
        (_initialize_rs6000_nat): Do not set rs6000_find_toc_address_hook.
        * rs6000-tdep.h (rs6000_find_toc_address_hook): Remove.
        * xcoffread.c (record_minimal_symbol): Reloate symbol address
        before creating minimal symbol.  Adjust function description
        accordingly.
        (scan_xcoff_symtab): Replace call to
        prim_record_minimal_symbol_and_info by call to
        record_minimal_symbol.
        (xcoff_symfile_offsets): Reimplement mostly as a wrapper
        around default_symfile_offsets.
        * configure.tgt: Add solib-aix.o to gdb_target_obs for
        powerpc-aix targets.
        * config/rs6000/nm-rs6000.h: Delete.
        * config/powerpc/aix.mh (NAT_FILE): Delete.
        (NATDEPFILES): Remove xcoffsolib.o.
        * Makefile.in (XMLFILES): Add library-list-aix.dtd.
        (ALL_TARGET_OBS): Add solib-aix.o.
        (HFILES_NO_SRCDIR): Remove xcoffsolib.h and
        config/rs6000/nm-rs6000.h.  Add solib-aix.h.
        (ALLDEPFILES): Add solib-aix.c.  Remove xcoffsolib.c.
        * xcoffsolib.h, xcoffsolib.c: Delete.

        * solib.c (reload_shared_libraries): Remove reference to
        SOLIB_CREATE_INFERIOR_HOOK.
        * breakpoint.c (handle_solib_event): Remove reference to SOLIB_ADD.
        (disable_breakpoints_in_shlibs): Remove reference to PC_SOLIB.
        (momentary_bkpt_re_set): Replace SOLIB_ADD by solib_add in
        comment.
        * corelow.c (deprecated_core_resize_section_table): Delete.
        * exec.c: Remove include of xcoffsolib.h".
        (map_vmap, vmap): Delete.
        (exec_close_1): Remove references to vmap.
        (exec_file_attach): Remove vmap handling code, and reference
        to DEPRECATED_IBM6000_TARGET.
        (bfdsec_to_vmap): Delete.
        (exec_files_info): Remove block of code handling VMAP.
        * infcmd.c (post_create_inferior): Remove reference to
        SOLIB_CREATE_INFERIOR_HOOK and SOLIB_ADD.
        * infrun.c (follow_exec): Remove reference to
        SOLIB_CREATE_INFERIOR_HOOK.
        * stack.c (print_frame): Remove reference to PC_SOLIB.
        * solib-dsbt.c (dsbt_current_sos): Adjust comment.
        (dsbt_relocate_main_executable): Likewise.
        * solib-frv.c (frv_current_sos): Likewise.

gdb/doc/ChangeLog:

        * gdbint.texinfo (Algorithms): Remove entries documenting
        DEPRECATED_IBM6000_TARGET, SOLIB_ADD, and
        SOLIB_CREATE_INFERIOR_HOOK.

26 files changed:
gdb/ChangeLog
gdb/Makefile.in
gdb/breakpoint.c
gdb/config/powerpc/aix.mh
gdb/config/rs6000/nm-rs6000.h [deleted file]
gdb/configure.tgt
gdb/corelow.c
gdb/doc/ChangeLog
gdb/doc/gdbint.texinfo
gdb/exec.c
gdb/features/library-list-aix.dtd [new file with mode: 0644]
gdb/infcmd.c
gdb/infrun.c
gdb/rs6000-aix-tdep.c
gdb/rs6000-nat.c
gdb/rs6000-tdep.h
gdb/solib-aix.c [new file with mode: 0644]
gdb/solib-aix.h [new file with mode: 0644]
gdb/solib-dsbt.c
gdb/solib-frv.c
gdb/solib.c
gdb/stack.c
gdb/target.h
gdb/xcoffread.c
gdb/xcoffsolib.c [deleted file]
gdb/xcoffsolib.h [deleted file]

index 14cce79..1917ff9 100644 (file)
@@ -1,5 +1,71 @@
 2013-05-06  Joel Brobecker  <brobecker@adacore.com>
 
 2013-05-06  Joel Brobecker  <brobecker@adacore.com>
 
+       Reimplement shared library support on ppc-aix...
+       * target.h (TARGET_OBJECT_AIX_LIBRARIES): New target_object enum.
+       * features/library-list-aix.dtd: New file.
+       * solib-aix.h, solib-aix.c: New file.
+       * rs6000-aix-tdep.c: #include "solib.h" and "solib-aix.h".
+       (rs6000_find_toc_address_hook): Delete.
+       (rs6000_push_dummy_call): Rewrite code setting the TOC value.
+       (rs6000_aix_init_osabi): Register solib_aix_so_ops.
+       * rs6000-nat.c: Remove "xcoffsolib.h" include.  Include
+       "xml-utils.h".
+       (map_vmap, vmap_exec, vmap_ldinfo, add_vmap, objfile_symbol_add)
+       (vmap_symtab, fixup_breakpoints): Delete.
+       (rs6000_xfer_shared_libraries): New function.
+       (rs6000_xfer_partial): Add TARGET_OBJECT_AIX_LIBRARIES handling.
+       (vmap_secs, bss_data_overlap, vmap_add_symbols): Delete.
+       (xcoff_relocate_symtab, xcoff_relocate_core): Delete.
+       (rs6000_ptrace_ldinfo, rs6000_core_ldinfo)
+       (rs6000_xfer_shared_library): New function.
+       (find_toc_address): Delete.
+       (_initialize_rs6000_nat): Do not set rs6000_find_toc_address_hook.
+       * rs6000-tdep.h (rs6000_find_toc_address_hook): Remove.
+       * xcoffread.c (record_minimal_symbol): Reloate symbol address
+       before creating minimal symbol.  Adjust function description
+       accordingly.
+       (scan_xcoff_symtab): Replace call to
+       prim_record_minimal_symbol_and_info by call to
+       record_minimal_symbol.
+       (xcoff_symfile_offsets): Reimplement mostly as a wrapper
+       around default_symfile_offsets.
+       * configure.tgt: Add solib-aix.o to gdb_target_obs for
+       powerpc-aix targets.
+       * config/rs6000/nm-rs6000.h: Delete.
+       * config/powerpc/aix.mh (NAT_FILE): Delete.
+       (NATDEPFILES): Remove xcoffsolib.o.
+       * Makefile.in (XMLFILES): Add library-list-aix.dtd.
+       (ALL_TARGET_OBS): Add solib-aix.o.
+       (HFILES_NO_SRCDIR): Remove xcoffsolib.h and
+       config/rs6000/nm-rs6000.h.  Add solib-aix.h.
+       (ALLDEPFILES): Add solib-aix.c.  Remove xcoffsolib.c.
+       * xcoffsolib.h, xcoffsolib.c: Delete.
+
+       * solib.c (reload_shared_libraries): Remove reference to
+       SOLIB_CREATE_INFERIOR_HOOK.
+       * breakpoint.c (handle_solib_event): Remove reference to SOLIB_ADD.
+       (disable_breakpoints_in_shlibs): Remove reference to PC_SOLIB.
+       (momentary_bkpt_re_set): Replace SOLIB_ADD by solib_add in
+       comment.
+       * corelow.c (deprecated_core_resize_section_table): Delete.
+       * exec.c: Remove include of xcoffsolib.h".
+       (map_vmap, vmap): Delete.
+       (exec_close_1): Remove references to vmap.
+       (exec_file_attach): Remove vmap handling code, and reference
+       to DEPRECATED_IBM6000_TARGET.
+       (bfdsec_to_vmap): Delete.
+       (exec_files_info): Remove block of code handling VMAP.
+       * infcmd.c (post_create_inferior): Remove reference to
+       SOLIB_CREATE_INFERIOR_HOOK and SOLIB_ADD.
+       * infrun.c (follow_exec): Remove reference to
+       SOLIB_CREATE_INFERIOR_HOOK.
+       * stack.c (print_frame): Remove reference to PC_SOLIB.
+       * solib-dsbt.c (dsbt_current_sos): Adjust comment.
+       (dsbt_relocate_main_executable): Likewise.
+       * solib-frv.c (frv_current_sos): Likewise.
+
+2013-05-06  Joel Brobecker  <brobecker@adacore.com>
+
        * sol-thread.c (rw_common): Cast BUF to "gdb_byte *" in calls
        to target_write_memory and target_read_memory.
 
        * sol-thread.c (rw_common): Cast BUF to "gdb_byte *" in calls
        to target_write_memory and target_read_memory.
 
index c891c83..625ca4a 100644 (file)
@@ -501,6 +501,7 @@ RUNTESTFLAGS=
 # XML files to build in to GDB.
 XMLFILES = $(srcdir)/features/gdb-target.dtd $(srcdir)/features/xinclude.dtd \
        $(srcdir)/features/library-list.dtd \
 # XML files to build in to GDB.
 XMLFILES = $(srcdir)/features/gdb-target.dtd $(srcdir)/features/xinclude.dtd \
        $(srcdir)/features/library-list.dtd \
+       $(srcdir)/features/library-list-aix.dtd \
        $(srcdir)/features/library-list-svr4.dtd $(srcdir)/features/osdata.dtd \
        $(srcdir)/features/threads.dtd $(srcdir)/features/traceframe-info.dtd \
        $(srcdir)/features/btrace.dtd
        $(srcdir)/features/library-list-svr4.dtd $(srcdir)/features/osdata.dtd \
        $(srcdir)/features/threads.dtd $(srcdir)/features/traceframe-info.dtd \
        $(srcdir)/features/btrace.dtd
@@ -573,7 +574,7 @@ ALL_TARGET_OBS = \
        nto-tdep.o \
        ppc-linux-tdep.o ppcnbsd-tdep.o ppcobsd-tdep.o ppc-sysv-tdep.o \
        ppc64-tdep.o rl78-tdep.o \
        nto-tdep.o \
        ppc-linux-tdep.o ppcnbsd-tdep.o ppcobsd-tdep.o ppc-sysv-tdep.o \
        ppc64-tdep.o rl78-tdep.o \
-       rs6000-aix-tdep.o rs6000-tdep.o ppc-ravenscar-thread.o \
+       rs6000-aix-tdep.o rs6000-tdep.o solib-aix.o ppc-ravenscar-thread.o \
        rs6000-lynx178-tdep.o \
        rx-tdep.o \
        s390-tdep.o \
        rs6000-lynx178-tdep.o \
        rx-tdep.o \
        s390-tdep.o \
@@ -805,7 +806,7 @@ target.h prologue-value.h cp-abi.h tui/tui-hooks.h tui/tui.h \
 tui/tui-file.h tui/tui-command.h tui/tui-disasm.h tui/tui-wingeneral.h \
 tui/tui-windata.h tui/tui-data.h tui/tui-win.h tui/tui-stack.h \
 tui/tui-winsource.h tui/tui-regs.h tui/tui-io.h tui/tui-layout.h \
 tui/tui-file.h tui/tui-command.h tui/tui-disasm.h tui/tui-wingeneral.h \
 tui/tui-windata.h tui/tui-data.h tui/tui-win.h tui/tui-stack.h \
 tui/tui-winsource.h tui/tui-regs.h tui/tui-io.h tui/tui-layout.h \
-tui/tui-source.h xcoffsolib.h sol2-tdep.h gregset.h sh-tdep.h sh64-tdep.h \
+tui/tui-source.h sol2-tdep.h gregset.h sh-tdep.h sh64-tdep.h \
 expression.h score-tdep.h gdb_select.h ser-tcp.h buildsym.h valprint.h \
 typeprint.h mi/mi-getopt.h mi/mi-parse.h mi/mi-console.h \
 mi/mi-out.h mi/mi-main.h mi/mi-common.h mi/mi-cmds.h linux-nat.h \
 expression.h score-tdep.h gdb_select.h ser-tcp.h buildsym.h valprint.h \
 typeprint.h mi/mi-getopt.h mi/mi-parse.h mi/mi-console.h \
 mi/mi-out.h mi/mi-main.h mi/mi-common.h mi/mi-cmds.h linux-nat.h \
@@ -824,7 +825,7 @@ inf-child.h p-lang.h event-top.h gdbtypes.h user-regs.h \
 regformats/regdef.h config/alpha/nm-osf3.h  config/i386/nm-i386gnu.h \
 config/i386/nm-fbsd.h \
 config/nm-nto.h config/sparc/nm-sol2.h config/nm-linux.h \
 regformats/regdef.h config/alpha/nm-osf3.h  config/i386/nm-i386gnu.h \
 config/i386/nm-fbsd.h \
 config/nm-nto.h config/sparc/nm-sol2.h config/nm-linux.h \
-config/rs6000/nm-rs6000.h top.h bsd-kvm.h gdb-stabs.h reggroups.h \
+top.h bsd-kvm.h gdb-stabs.h reggroups.h \
 annotate.h sim-regno.h dictionary.h dfp.h main.h frame-unwind.h        \
 remote-fileio.h i386-linux-tdep.h vax-tdep.h objc-lang.h \
 sentinel-frame.h bcache.h symfile.h windows-tdep.h linux-tdep.h \
 annotate.h sim-regno.h dictionary.h dfp.h main.h frame-unwind.h        \
 remote-fileio.h i386-linux-tdep.h vax-tdep.h objc-lang.h \
 sentinel-frame.h bcache.h symfile.h windows-tdep.h linux-tdep.h \
@@ -836,7 +837,7 @@ dicos-tdep.h filesystem.h gcore.h gdb_wchar.h hppabsd-tdep.h \
 i386-darwin-tdep.h i386-nat.h linux-record.h moxie-tdep.h \
 osdata.h procfs.h python/py-event.h python/py-events.h python/py-stopevent.h \
 python/python-internal.h python/python.h ravenscar-thread.h record.h \
 i386-darwin-tdep.h i386-nat.h linux-record.h moxie-tdep.h \
 osdata.h procfs.h python/py-event.h python/py-events.h python/py-stopevent.h \
 python/python-internal.h python/python.h ravenscar-thread.h record.h \
-record-full.h \
+record-full.h solib-aix.h \
 solib-darwin.h solib-ia64-hpux.h solib-spu.h windows-nat.h xcoffread.h \
 gnulib/import/extra/snippet/arg-nonnull.h gnulib/import/extra/snippet/c++defs.h \
 gnulib/import/extra/snippet/warn-on-use.h \
 solib-darwin.h solib-ia64-hpux.h solib-spu.h windows-nat.h xcoffread.h \
 gnulib/import/extra/snippet/arg-nonnull.h gnulib/import/extra/snippet/c++defs.h \
 gnulib/import/extra/snippet/warn-on-use.h \
@@ -1528,7 +1529,7 @@ ALLDEPFILES = \
        remote-sim.c \
        dcache.c \
        rl78-tdep.c \
        remote-sim.c \
        dcache.c \
        rl78-tdep.c \
-       rs6000-nat.c rs6000-tdep.c ppc-ravenscar-thread.c \
+       rs6000-nat.c rs6000-tdep.c solib-aix.c ppc-ravenscar-thread.c \
        rs6000-lynx178-tdep.c \
        rx-tdep.c \
        s390-tdep.c s390-nat.c \
        rs6000-lynx178-tdep.c \
        rx-tdep.c \
        s390-tdep.c s390-nat.c \
@@ -1549,7 +1550,7 @@ ALLDEPFILES = \
        v850-tdep.c \
        vax-nat.c vax-tdep.c vaxbsd-nat.c vaxnbsd-tdep.c \
        windows-nat.c windows-tdep.c \
        v850-tdep.c \
        vax-nat.c vax-tdep.c vaxbsd-nat.c vaxnbsd-tdep.c \
        windows-nat.c windows-tdep.c \
-       xcoffread.c xcoffsolib.c \
+       xcoffread.c \
        xstormy16-tdep.c \
        xtensa-tdep.c xtensa-config.c \
        xtensa-linux-tdep.c xtensa-linux-nat.c xtensa-xtregs.c
        xstormy16-tdep.c \
        xtensa-tdep.c xtensa-config.c \
        xtensa-linux-tdep.c xtensa-linux-nat.c xtensa-xtregs.c
index 35ada7a..ef9c23c 100644 (file)
@@ -5367,11 +5367,7 @@ handle_solib_event (void)
      be adding them automatically.  Switch terminal for any messages
      produced by breakpoint_re_set.  */
   target_terminal_ours_for_output ();
      be adding them automatically.  Switch terminal for any messages
      produced by breakpoint_re_set.  */
   target_terminal_ours_for_output ();
-#ifdef SOLIB_ADD
-  SOLIB_ADD (NULL, 0, &current_target, auto_solib_add);
-#else
   solib_add (NULL, 0, &current_target, auto_solib_add);
   solib_add (NULL, 0, &current_target, auto_solib_add);
-#endif
   target_terminal_inferior ();
 }
 
   target_terminal_inferior ();
 }
 
@@ -7417,11 +7413,7 @@ disable_breakpoints_in_shlibs (void)
         || (is_tracepoint (b)))
        && loc->pspace == current_program_space
        && !loc->shlib_disabled
         || (is_tracepoint (b)))
        && loc->pspace == current_program_space
        && !loc->shlib_disabled
-#ifdef PC_SOLIB
-       && PC_SOLIB (loc->address)
-#else
        && solib_name_from_address (loc->pspace, loc->address)
        && solib_name_from_address (loc->pspace, loc->address)
-#endif
        )
       {
        loc->shlib_disabled = 1;
        )
       {
        loc->shlib_disabled = 1;
@@ -13077,7 +13069,7 @@ static void
 momentary_bkpt_re_set (struct breakpoint *b)
 {
   /* Keep temporary breakpoints, which can be encountered when we step
 momentary_bkpt_re_set (struct breakpoint *b)
 {
   /* Keep temporary breakpoints, which can be encountered when we step
-     over a dlopen call and SOLIB_ADD is resetting the breakpoints.
+     over a dlopen call and solib_add is resetting the breakpoints.
      Otherwise these should have been blown away via the cleanup chain
      or by breakpoint_init_inferior when we rerun the executable.  */
 }
      Otherwise these should have been blown away via the cleanup chain
      or by breakpoint_init_inferior when we rerun the executable.  */
 }
index d007fff..141501d 100644 (file)
@@ -1,10 +1,7 @@
 # Host: IBM PowerPC running AIX
 
 # Host: IBM PowerPC running AIX
 
-NAT_FILE= config/rs6000/nm-rs6000.h
-
 # aix-thread.o is not listed in NATDEPFILES as it is pulled in by configure.
 # aix-thread.o is not listed in NATDEPFILES as it is pulled in by configure.
-NATDEPFILES= fork-child.o inf-ptrace.o rs6000-nat.o \
-            xcoffsolib.o
+NATDEPFILES= fork-child.o inf-ptrace.o rs6000-nat.o
 
 # When compiled with cc, for debugging, this argument should be passed.
 # We have no idea who our current compiler is though, so we skip it.
 
 # When compiled with cc, for debugging, this argument should be passed.
 # We have no idea who our current compiler is though, so we skip it.
diff --git a/gdb/config/rs6000/nm-rs6000.h b/gdb/config/rs6000/nm-rs6000.h
deleted file mode 100644 (file)
index e631521..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* IBM RS/6000 native-dependent macros for GDB, the GNU debugger.
-   Copyright (C) 1986-2013 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 <http://www.gnu.org/licenses/>.  */
-
-/* When a child process is just starting, we sneak in and relocate
-   the symbol table (and other stuff) after the dynamic linker has
-   figured out where they go.  */
-
-#define        SOLIB_CREATE_INFERIOR_HOOK(PID) \
-  do {                                 \
-    xcoff_relocate_symtab (PID);       \
-  } while (0)
-
-/* When a target process or core-file has been attached, we sneak in
-   and figure out where the shared libraries have got to.  */
-
-#define        SOLIB_ADD(a, b, c, d)   \
-  if (PIDGET (inferior_ptid))  \
-    /* Attach to process.  */  \
-    xcoff_relocate_symtab (PIDGET (inferior_ptid)); \
-  else         \
-    /* Core file.  */ \
-    xcoff_relocate_core (c);
-
-extern void xcoff_relocate_symtab (unsigned int);
-struct target_ops;
-extern void xcoff_relocate_core (struct target_ops *);
-
-/* If ADDR lies in a shared library, return its name.  */
-
-#define        PC_SOLIB(PC)    xcoff_solib_address(PC)
-extern char *xcoff_solib_address (CORE_ADDR);
-
-/* Flag for machine-specific stuff in shared files.  FIXME */
-#define DEPRECATED_IBM6000_TARGET
-
index 2435de4..4acad87 100644 (file)
@@ -419,7 +419,7 @@ powerpc-*-openbsd*)
 powerpc-*-aix* | rs6000-*-*)
        # Target: PowerPC running AIX
        gdb_target_obs="rs6000-tdep.o rs6000-aix-tdep.o xcoffread.o \
 powerpc-*-aix* | rs6000-*-*)
        # Target: PowerPC running AIX
        gdb_target_obs="rs6000-tdep.o rs6000-aix-tdep.o xcoffread.o \
-                       ppc-sysv-tdep.o \
+                       ppc-sysv-tdep.o solib-aix.o \
                        ravenscar-thread.o ppc-ravenscar-thread.o"
        ;;
 powerpc-*-linux* | powerpc64-*-linux*)
                        ravenscar-thread.o ppc-ravenscar-thread.o"
        ;;
 powerpc-*-linux* | powerpc64-*-linux*)
index 46da881..de940fc 100644 (file)
@@ -467,24 +467,6 @@ core_detach (struct target_ops *ops, char *args, int from_tty)
     printf_filtered (_("No core file now.\n"));
 }
 
     printf_filtered (_("No core file now.\n"));
 }
 
-#ifdef DEPRECATED_IBM6000_TARGET
-
-/* Resize the core memory's section table, by NUM_ADDED.  Returns a
-   pointer into the first new slot.  This will not be necessary when
-   the rs6000 target is converted to use the standard solib
-   framework.  */
-
-struct target_section *
-deprecated_core_resize_section_table (int num_added)
-{
-  int old_count;
-
-  old_count = resize_section_table (core_data, num_added);
-  return core_data->sections + old_count;
-}
-
-#endif
-
 /* Try to retrieve registers from a section in core_bfd, and supply
    them to core_vec->core_read_registers, as the register set numbered
    WHICH.
 /* Try to retrieve registers from a section in core_bfd, and supply
    them to core_vec->core_read_registers, as the register set numbered
    WHICH.
index 75a4db8..8035f3e 100644 (file)
@@ -1,3 +1,9 @@
+2013-05-06  Joel Brobecker  <brobecker@adacore.com>
+
+       * gdbint.texinfo (Algorithms): Remove entries documenting
+       DEPRECATED_IBM6000_TARGET, SOLIB_ADD, and
+       SOLIB_CREATE_INFERIOR_HOOK.
+
 2013-04-29  Tom Tromey  <tromey@redhat.com>
 
        PR python/14204:
 2013-04-29  Tom Tromey  <tromey@redhat.com>
 
        PR python/14204:
index 3a04c18..9bdbe74 100644 (file)
@@ -4666,13 +4666,6 @@ offset into the @code{jmp_buf}.  (While we might like to get the offset
 from the target's @file{jmpbuf.h}, that header file cannot be assumed
 to be available when building a cross-debugger.)
 
 from the target's @file{jmpbuf.h}, that header file cannot be assumed
 to be available when building a cross-debugger.)
 
-@item DEPRECATED_IBM6000_TARGET
-@findex DEPRECATED_IBM6000_TARGET
-Shows that we are configured for an IBM RS/6000 system.  This
-conditional should be eliminated (FIXME) and replaced by
-feature-specific macros.  It was introduced in haste and we are
-repenting at leisure.
-
 @item I386_USE_GENERIC_WATCHPOINTS
 An x86-based target can define this to use the generic x86 watchpoint
 support; see @ref{Algorithms, I386_USE_GENERIC_WATCHPOINTS}.
 @item I386_USE_GENERIC_WATCHPOINTS
 An x86-based target can define this to use the generic x86 watchpoint
 support; see @ref{Algorithms, I386_USE_GENERIC_WATCHPOINTS}.
@@ -5412,18 +5405,6 @@ undefined) in @file{nm-@var{system}.h}.
 An x86-based machine can define this to use the generic x86 watchpoint
 support; see @ref{Algorithms, I386_USE_GENERIC_WATCHPOINTS}.
 
 An x86-based machine can define this to use the generic x86 watchpoint
 support; see @ref{Algorithms, I386_USE_GENERIC_WATCHPOINTS}.
 
-@item SOLIB_ADD (@var{filename}, @var{from_tty}, @var{targ}, @var{readsyms})
-@findex SOLIB_ADD
-Define this to expand into an expression that will cause the symbols in
-@var{filename} to be added to @value{GDBN}'s symbol table.  If
-@var{readsyms} is zero symbols are not read but any necessary low level
-processing for @var{filename} is still done.
-
-@item SOLIB_CREATE_INFERIOR_HOOK
-@findex SOLIB_CREATE_INFERIOR_HOOK
-Define this to expand into any shared-library-relocation code that you
-want to be run just after the child process has been forked.
-
 @item START_INFERIOR_TRAPS_EXPECTED
 @findex START_INFERIOR_TRAPS_EXPECTED
 When starting an inferior, @value{GDBN} normally expects to trap
 @item START_INFERIOR_TRAPS_EXPECTED
 @findex START_INFERIOR_TRAPS_EXPECTED
 When starting an inferior, @value{GDBN} normally expects to trap
index 3386b60..e8605b9 100644 (file)
 #include <ctype.h>
 #include "gdb_stat.h"
 
 #include <ctype.h>
 #include "gdb_stat.h"
 
-#include "xcoffsolib.h"
-
-struct vmap *map_vmap (bfd *, bfd *);
-
 void (*deprecated_file_changed_hook) (char *);
 
 /* Prototypes for local functions */
 void (*deprecated_file_changed_hook) (char *);
 
 /* Prototypes for local functions */
@@ -81,8 +77,6 @@ show_write_files (struct ui_file *file, int from_tty,
 }
 
 
 }
 
 
-struct vmap *vmap;
-
 static void
 exec_open (char *args, int from_tty)
 {
 static void
 exec_open (char *args, int from_tty)
 {
@@ -117,25 +111,8 @@ exec_close (void)
 static void
 exec_close_1 (void)
 {
 static void
 exec_close_1 (void)
 {
-  struct vmap *vp, *nxt;
-
   using_exec_ops = 0;
 
   using_exec_ops = 0;
 
-  for (nxt = vmap; nxt != NULL;)
-    {
-      vp = nxt;
-      nxt = vp->nxt;
-
-      if (vp->objfile)
-       free_objfile (vp->objfile);
-
-      gdb_bfd_unref (vp->bfd);
-
-      xfree (vp);
-    }
-
-  vmap = NULL;
-
   {
     struct program_space *ss;
     struct cleanup *old_chain;
   {
     struct program_space *ss;
     struct cleanup *old_chain;
@@ -248,22 +225,6 @@ exec_file_attach (char *filename, int from_tty)
                 gdb_bfd_errmsg (bfd_get_error (), matching));
        }
 
                 gdb_bfd_errmsg (bfd_get_error (), matching));
        }
 
-      /* FIXME - This should only be run for RS6000, but the ifdef is a poor
-         way to accomplish.  */
-#ifdef DEPRECATED_IBM6000_TARGET
-      /* Setup initial vmap.  */
-
-      map_vmap (exec_bfd, 0);
-      if (vmap == NULL)
-       {
-         /* Make sure to close exec_bfd, or else "run" might try to use
-            it.  */
-         exec_close ();
-         error (_("\"%s\": can't find the file sections: %s"),
-                scratch_pathname, bfd_errmsg (bfd_get_error ()));
-       }
-#endif /* DEPRECATED_IBM6000_TARGET */
-
       if (build_section_table (exec_bfd, &sections, &sections_end))
        {
          /* Make sure to close exec_bfd, or else "run" might try to use
       if (build_section_table (exec_bfd, &sections, &sections_end))
        {
          /* Make sure to close exec_bfd, or else "run" might try to use
@@ -507,62 +468,6 @@ remove_target_sections (void *key, bfd *abfd)
 }
 
 \f
 }
 
 \f
-static void
-bfdsec_to_vmap (struct bfd *abfd, struct bfd_section *sect, void *arg3)
-{
-  struct vmap_and_bfd *vmap_bfd = (struct vmap_and_bfd *) arg3;
-  struct vmap *vp;
-
-  vp = vmap_bfd->pvmap;
-
-  if ((bfd_get_section_flags (abfd, sect) & SEC_LOAD) == 0)
-    return;
-
-  if (strcmp (bfd_section_name (abfd, sect), ".text") == 0)
-    {
-      vp->tstart = bfd_section_vma (abfd, sect);
-      vp->tend = vp->tstart + bfd_section_size (abfd, sect);
-      vp->tvma = bfd_section_vma (abfd, sect);
-      vp->toffs = sect->filepos;
-    }
-  else if (strcmp (bfd_section_name (abfd, sect), ".data") == 0)
-    {
-      vp->dstart = bfd_section_vma (abfd, sect);
-      vp->dend = vp->dstart + bfd_section_size (abfd, sect);
-      vp->dvma = bfd_section_vma (abfd, sect);
-    }
-  /* Silently ignore other types of sections.  (FIXME?)  */
-}
-
-/* Make a vmap for ABFD which might be a member of the archive ARCH.
-   Return the new vmap.  */
-
-struct vmap *
-map_vmap (bfd *abfd, bfd *arch)
-{
-  struct vmap_and_bfd vmap_bfd;
-  struct vmap *vp, **vpp;
-
-  vp = (struct vmap *) xmalloc (sizeof (*vp));
-  memset ((char *) vp, '\0', sizeof (*vp));
-  vp->nxt = 0;
-  vp->bfd = abfd;
-  gdb_bfd_ref (abfd);
-  vp->name = bfd_get_filename (arch ? arch : abfd);
-  vp->member = arch ? bfd_get_filename (abfd) : "";
-
-  vmap_bfd.pbfd = arch;
-  vmap_bfd.pvmap = vp;
-  bfd_map_over_sections (abfd, bfdsec_to_vmap, &vmap_bfd);
-
-  /* Find the end of the list and append.  */
-  for (vpp = &vmap; *vpp; vpp = &(*vpp)->nxt)
-    ;
-  *vpp = vp;
-
-  return vp;
-}
-\f
 
 VEC(mem_range_s) *
 section_table_available_memory (VEC(mem_range_s) *memory,
 
 VEC(mem_range_s) *
 section_table_available_memory (VEC(mem_range_s) *memory,
@@ -758,31 +663,6 @@ exec_files_info (struct target_ops *t)
     print_section_info (current_target_sections, exec_bfd);
   else
     puts_filtered (_("\t<no file loaded>\n"));
     print_section_info (current_target_sections, exec_bfd);
   else
     puts_filtered (_("\t<no file loaded>\n"));
-
-  if (vmap)
-    {
-      int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
-      struct vmap *vp;
-
-      printf_unfiltered (_("\tMapping info for file `%s'.\n"), vmap->name);
-      printf_unfiltered ("\t  %*s   %*s   %*s   %*s %8.8s %s\n",
-                        addr_size * 2, "tstart",
-                        addr_size * 2, "tend",
-                        addr_size * 2, "dstart",
-                        addr_size * 2, "dend",
-                        "section",
-                        "file(member)");
-
-      for (vp = vmap; vp; vp = vp->nxt)
-       printf_unfiltered ("\t0x%s 0x%s 0x%s 0x%s %s%s%s%s\n",
-                          phex (vp->tstart, addr_size),
-                          phex (vp->tend, addr_size),
-                          phex (vp->dstart, addr_size),
-                          phex (vp->dend, addr_size),
-                          vp->name,
-                          *vp->member ? "(" : "", vp->member,
-                          *vp->member ? ")" : "");
-    }
 }
 
 static void
 }
 
 static void
diff --git a/gdb/features/library-list-aix.dtd b/gdb/features/library-list-aix.dtd
new file mode 100644 (file)
index 0000000..5a24ce5
--- /dev/null
@@ -0,0 +1,18 @@
+<!-- Copyright (C) 2013 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!-- library-list: Root element with versioning -->
+<!ELEMENT library-list  (library)*>
+<!ATTLIST library-list  version CDATA   #FIXED  "1.0">
+
+<!ELEMENT library  (name, member, text_addr, text_size, data_addr, data_size)>
+<!ATTLIST library  name       CDATA   #REQUIRED>
+<!ATTLIST library  member     CDATA   #REQUIRED>
+<!ATTLIST library  text_addr  CDATA   #REQUIRED>
+<!ATTLIST library  text_size  CDATA   #REQUIRED>
+<!ATTLIST library  data_addr  CDATA   #REQUIRED>
+<!ATTLIST library  data_size  CDATA   #REQUIRED>
+
index 11cdf62..aeb24ff 100644 (file)
@@ -432,11 +432,7 @@ post_create_inferior (struct target_ops *target, int from_tty)
 
       /* Create the hooks to handle shared library load and unload
         events.  */
 
       /* Create the hooks to handle shared library load and unload
         events.  */
-#ifdef SOLIB_CREATE_INFERIOR_HOOK
-      SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
-#else
       solib_create_inferior_hook (from_tty);
       solib_create_inferior_hook (from_tty);
-#endif
 
       if (current_program_space->solib_add_generation == solib_add_generation)
        {
 
       if (current_program_space->solib_add_generation == solib_add_generation)
        {
@@ -452,13 +448,7 @@ post_create_inferior (struct target_ops *target, int from_tty)
          /* If the solist is global across processes, there's no need to
             refetch it here.  */
          if (!gdbarch_has_global_solist (target_gdbarch ()))
          /* If the solist is global across processes, there's no need to
             refetch it here.  */
          if (!gdbarch_has_global_solist (target_gdbarch ()))
-           {
-#ifdef SOLIB_ADD
-             SOLIB_ADD (NULL, 0, target, auto_solib_add);
-#else
-             solib_add (NULL, 0, target, auto_solib_add);
-#endif
-           }
+           solib_add (NULL, 0, target, auto_solib_add);
        }
     }
 
        }
     }
 
index 5d6a9af..54e92f2 100644 (file)
@@ -958,11 +958,7 @@ follow_exec (ptid_t pid, char *execd_pathname)
      registers.  */
   target_find_description ();
 
      registers.  */
   target_find_description ();
 
-#ifdef SOLIB_CREATE_INFERIOR_HOOK
-  SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
-#else
   solib_create_inferior_hook (0);
   solib_create_inferior_hook (0);
-#endif
 
   jit_inferior_created_hook ();
 
 
   jit_inferior_created_hook ();
 
index 0b70ad1..0992213 100644 (file)
 #include "ppc-tdep.h"
 #include "exceptions.h"
 #include "xcoffread.h"
 #include "ppc-tdep.h"
 #include "exceptions.h"
 #include "xcoffread.h"
-
-/* Hook for determining the TOC address when calling functions in the
-   inferior under AIX.  The initialization code in rs6000-nat.c sets
-   this hook to point to find_toc_address.  */
-
-CORE_ADDR (*rs6000_find_toc_address_hook) (CORE_ADDR) = NULL;
+#include "solib.h"
+#include "solib-aix.h"
 
 /* If the kernel has to deliver a signal, it pushes a sigcontext
    structure on the stack and then calls the signal handler, passing
 
 /* If the kernel has to deliver a signal, it pushes a sigcontext
    structure on the stack and then calls the signal handler, passing
@@ -412,13 +408,9 @@ ran_out_of_registers_for_arguments:
      breakpoint.  */
   regcache_raw_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr);
 
      breakpoint.  */
   regcache_raw_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr);
 
-  /* Set the TOC register, get the value from the objfile reader
-     which, in turn, gets it from the VMAP table.  */
-  if (rs6000_find_toc_address_hook != NULL)
-    {
-      CORE_ADDR tocvalue = (*rs6000_find_toc_address_hook) (func_addr);
-      regcache_raw_write_signed (regcache, tdep->ppc_toc_regnum, tocvalue);
-    }
+  /* Set the TOC register value.  */
+  regcache_raw_write_signed (regcache, tdep->ppc_toc_regnum,
+                            solib_aix_get_toc_value (func_addr));
 
   target_store_registers (regcache, -1);
   return sp;
 
   target_store_registers (regcache, -1);
   return sp;
@@ -793,6 +785,8 @@ rs6000_aix_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
     set_gdbarch_frame_red_zone_size (gdbarch, 0);
 
   set_gdbarch_auto_wide_charset (gdbarch, rs6000_aix_auto_wide_charset);
     set_gdbarch_frame_red_zone_size (gdbarch, 0);
 
   set_gdbarch_auto_wide_charset (gdbarch, rs6000_aix_auto_wide_charset);
+
+  set_solib_ops (gdbarch, &solib_aix_so_ops);
 }
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
 }
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
index f16a964..a16ccf2 100644 (file)
@@ -21,7 +21,6 @@
 #include "inferior.h"
 #include "target.h"
 #include "gdbcore.h"
 #include "inferior.h"
 #include "target.h"
 #include "gdbcore.h"
-#include "xcoffsolib.h"
 #include "symfile.h"
 #include "objfiles.h"
 #include "libbfd.h"            /* For bfd_default_set_arch_mach (FIXME) */
 #include "symfile.h"
 #include "objfiles.h"
 #include "libbfd.h"            /* For bfd_default_set_arch_mach (FIXME) */
@@ -58,6 +57,7 @@
 #define __LDINFO_PTRACE64__    /* for __ld_info64 */
 #include <sys/ldr.h>
 #include <sys/systemcfg.h>
 #define __LDINFO_PTRACE64__    /* for __ld_info64 */
 #include <sys/ldr.h>
 #include <sys/systemcfg.h>
+#include "xml-utils.h"
 
 /* On AIX4.3+, sys/ldr.h provides different versions of struct ld_info for
    debugging 32-bit and 64-bit processes.  Define a typedef and macros for
 
 /* On AIX4.3+, sys/ldr.h provides different versions of struct ld_info for
    debugging 32-bit and 64-bit processes.  Define a typedef and macros for
@@ -118,20 +118,13 @@ typedef union {
 #define LDI_FD(ldi, arch64)            LDI_FIELD(ldi, arch64, fd)
 #define LDI_FILENAME(ldi, arch64)      LDI_FIELD(ldi, arch64, filename)
 
 #define LDI_FD(ldi, arch64)            LDI_FIELD(ldi, arch64, fd)
 #define LDI_FILENAME(ldi, arch64)      LDI_FIELD(ldi, arch64, filename)
 
-extern struct vmap *map_vmap (bfd * bf, bfd * arch);
-
-static void vmap_exec (void);
-
-static void vmap_ldinfo (LdInfo *);
-
-static struct vmap *add_vmap (LdInfo *);
-
-static int objfile_symbol_add (void *);
-
-static void vmap_symtab (struct vmap *);
-
 static void exec_one_dummy_insn (struct regcache *);
 
 static void exec_one_dummy_insn (struct regcache *);
 
+static LONGEST rs6000_xfer_shared_libraries
+  (struct target_ops *ops, enum target_object object,
+   const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf,
+   ULONGEST offset, LONGEST len);
+
 /* Given REGNO, a gdb register number, return the corresponding
    number suitable for use as a ptrace() parameter.  Return -1 if
    there's no suitable mapping.  Also, set the int pointed to by
 /* Given REGNO, a gdb register number, return the corresponding
    number suitable for use as a ptrace() parameter.  Return -1 if
    there's no suitable mapping.  Also, set the int pointed to by
@@ -431,6 +424,10 @@ rs6000_xfer_partial (struct target_ops *ops, enum target_object object,
 
   switch (object)
     {
 
   switch (object)
     {
+    case TARGET_OBJECT_AIX_LIBRARIES:
+      return rs6000_xfer_shared_libraries (ops, object, annex,
+                                          readbuf, writebuf,
+                                          offset, len);
     case TARGET_OBJECT_MEMORY:
       {
        union
     case TARGET_OBJECT_MEMORY:
       {
        union
@@ -621,431 +618,6 @@ exec_one_dummy_insn (struct regcache *regcache)
 }
 \f
 
 }
 \f
 
-/* Copy information about text and data sections from LDI to VP for a 64-bit
-   process if ARCH64 and for a 32-bit process otherwise.  */
-
-static void
-vmap_secs (struct vmap *vp, LdInfo *ldi, int arch64)
-{
-  if (arch64)
-    {
-      vp->tstart = (CORE_ADDR) ldi->l64.ldinfo_textorg;
-      vp->tend = vp->tstart + ldi->l64.ldinfo_textsize;
-      vp->dstart = (CORE_ADDR) ldi->l64.ldinfo_dataorg;
-      vp->dend = vp->dstart + ldi->l64.ldinfo_datasize;
-    }
-  else
-    {
-      vp->tstart = (unsigned long) ldi->l32.ldinfo_textorg;
-      vp->tend = vp->tstart + ldi->l32.ldinfo_textsize;
-      vp->dstart = (unsigned long) ldi->l32.ldinfo_dataorg;
-      vp->dend = vp->dstart + ldi->l32.ldinfo_datasize;
-    }
-
-  /* The run time loader maps the file header in addition to the text
-     section and returns a pointer to the header in ldinfo_textorg.
-     Adjust the text start address to point to the real start address
-     of the text section.  */
-  vp->tstart += vp->toffs;
-}
-
-/* If the .bss section's VMA is set to an address located before
-   the end of the .data section, causing the two sections to overlap,
-   return the overlap in bytes.  Otherwise, return zero.
-
-   Motivation:
-
-   The GNU linker sometimes sets the start address of the .bss session
-   before the end of the .data section, making the 2 sections overlap.
-   The loader appears to handle this situation gracefully, by simply
-   loading the bss section right after the end of the .data section.
-
-   This means that the .data and the .bss sections are sometimes
-   no longer relocated by the same amount.  The problem is that
-   the ldinfo data does not contain any information regarding
-   the relocation of the .bss section, assuming that it would be
-   identical to the information provided for the .data section
-   (this is what would normally happen if the program was linked
-   correctly).
-
-   GDB therefore needs to detect those cases, and make the corresponding
-   adjustment to the .bss section offset computed from the ldinfo data
-   when necessary.  This function returns the adjustment amount  (or
-   zero when no adjustment is needed).  */
-
-static CORE_ADDR
-bss_data_overlap (struct objfile *objfile)
-{
-  struct obj_section *osect;
-  struct bfd_section *data = NULL;
-  struct bfd_section *bss = NULL;
-
-  /* First, find the .data and .bss sections.  */
-  ALL_OBJFILE_OSECTIONS (objfile, osect)
-    {
-      if (strcmp (bfd_section_name (objfile->obfd,
-                                   osect->the_bfd_section),
-                 ".data") == 0)
-       data = osect->the_bfd_section;
-      else if (strcmp (bfd_section_name (objfile->obfd,
-                                        osect->the_bfd_section),
-                      ".bss") == 0)
-       bss = osect->the_bfd_section;
-    }
-
-  /* If either section is not defined, there can be no overlap.  */
-  if (data == NULL || bss == NULL)
-    return 0;
-
-  /* Assume the problem only occurs with linkers that place the .bss
-     section after the .data section (the problem has only been
-     observed when using the GNU linker, and the default linker
-     script always places the .data and .bss sections in that order).  */
-  if (bfd_section_vma (objfile->obfd, bss)
-      < bfd_section_vma (objfile->obfd, data))
-    return 0;
-
-  if (bfd_section_vma (objfile->obfd, bss)
-      < bfd_section_vma (objfile->obfd, data) + bfd_get_section_size (data))
-    return ((bfd_section_vma (objfile->obfd, data)
-            + bfd_get_section_size (data))
-           - bfd_section_vma (objfile->obfd, bss));
-
-  return 0;
-}
-
-/* Handle symbol translation on vmapping.  */
-
-static void
-vmap_symtab (struct vmap *vp)
-{
-  struct objfile *objfile;
-  struct section_offsets *new_offsets;
-  int i;
-
-  objfile = vp->objfile;
-  if (objfile == NULL)
-    {
-      /* OK, it's not an objfile we opened ourselves.
-         Currently, that can only happen with the exec file, so
-         relocate the symbols for the symfile.  */
-      if (symfile_objfile == NULL)
-       return;
-      objfile = symfile_objfile;
-    }
-  else if (!vp->loaded)
-    /* If symbols are not yet loaded, offsets are not yet valid.  */
-    return;
-
-  new_offsets =
-    (struct section_offsets *)
-    alloca (SIZEOF_N_SECTION_OFFSETS (objfile->num_sections));
-
-  for (i = 0; i < objfile->num_sections; ++i)
-    new_offsets->offsets[i] = ANOFFSET (objfile->section_offsets, i);
-
-  /* The symbols in the object file are linked to the VMA of the section,
-     relocate them VMA relative.  */
-  new_offsets->offsets[SECT_OFF_TEXT (objfile)] = vp->tstart - vp->tvma;
-  new_offsets->offsets[SECT_OFF_DATA (objfile)] = vp->dstart - vp->dvma;
-  new_offsets->offsets[SECT_OFF_BSS (objfile)] = vp->dstart - vp->dvma;
-
-  /* Perform the same adjustment as the loader if the .data and
-     .bss sections overlap.  */
-  new_offsets->offsets[SECT_OFF_BSS (objfile)] += bss_data_overlap (objfile);
-
-  objfile_relocate (objfile, new_offsets);
-}
-\f
-/* Add symbols for an objfile.  */
-
-static int
-objfile_symbol_add (void *arg)
-{
-  struct objfile *obj = (struct objfile *) arg;
-
-  syms_from_objfile (obj, NULL, 0, 0, 0);
-  new_symfile_objfile (obj, 0);
-  return 1;
-}
-
-/* Add symbols for a vmap. Return zero upon error.  */
-
-int
-vmap_add_symbols (struct vmap *vp)
-{
-  if (catch_errors (objfile_symbol_add, vp->objfile,
-                   "Error while reading shared library symbols:\n",
-                   RETURN_MASK_ALL))
-    {
-      /* Note this is only done if symbol reading was successful.  */
-      vp->loaded = 1;
-      vmap_symtab (vp);
-      return 1;
-    }
-  return 0;
-}
-
-/* Add a new vmap entry based on ldinfo() information.
-
-   If ldi->ldinfo_fd is not valid (e.g. this struct ld_info is from a
-   core file), the caller should set it to -1, and we will open the file.
-
-   Return the vmap new entry.  */
-
-static struct vmap *
-add_vmap (LdInfo *ldi)
-{
-  bfd *abfd, *last;
-  char *mem, *filename;
-  struct objfile *obj;
-  struct vmap *vp;
-  int fd;
-  ARCH64_DECL (arch64);
-
-  /* This ldi structure was allocated using alloca() in 
-     xcoff_relocate_symtab().  Now we need to have persistent object 
-     and member names, so we should save them.  */
-
-  filename = LDI_FILENAME (ldi, arch64);
-  mem = filename + strlen (filename) + 1;
-  mem = xstrdup (mem);
-
-  fd = LDI_FD (ldi, arch64);
-  abfd = gdb_bfd_open (filename, gnutarget, fd < 0 ? -1 : fd);
-  if (!abfd)
-    {
-      warning (_("Could not open `%s' as an executable file: %s"),
-              filename, bfd_errmsg (bfd_get_error ()));
-      return NULL;
-    }
-
-  /* Make sure we have an object file.  */
-
-  if (bfd_check_format (abfd, bfd_object))
-    vp = map_vmap (abfd, 0);
-
-  else if (bfd_check_format (abfd, bfd_archive))
-    {
-      last = gdb_bfd_openr_next_archived_file (abfd, NULL);
-      while (last != NULL)
-       {
-         bfd *next;
-
-         if (strcmp (mem, last->filename) == 0)
-           break;
-
-         next = gdb_bfd_openr_next_archived_file (abfd, last);
-         gdb_bfd_unref (last);
-         last = next;
-       }
-
-      if (!last)
-       {
-         warning (_("\"%s\": member \"%s\" missing."), filename, mem);
-         gdb_bfd_unref (abfd);
-         return NULL;
-       }
-
-      if (!bfd_check_format (last, bfd_object))
-       {
-         warning (_("\"%s\": member \"%s\" not in executable format: %s."),
-                  filename, mem, bfd_errmsg (bfd_get_error ()));
-         gdb_bfd_unref (last);
-         gdb_bfd_unref (abfd);
-         return NULL;
-       }
-
-      vp = map_vmap (last, abfd);
-      /* map_vmap acquired a reference to LAST, so we can release
-        ours.  */
-      gdb_bfd_unref (last);
-    }
-  else
-    {
-      warning (_("\"%s\": not in executable format: %s."),
-              filename, bfd_errmsg (bfd_get_error ()));
-      gdb_bfd_unref (abfd);
-      return NULL;
-    }
-  obj = allocate_objfile (vp->bfd, 0);
-  vp->objfile = obj;
-
-  /* Always add symbols for the main objfile.  */
-  if (vp == vmap || auto_solib_add)
-    vmap_add_symbols (vp);
-
-  /* Anything needing a reference to ABFD has already acquired it, so
-     release our local reference.  */
-  gdb_bfd_unref (abfd);
-
-  return vp;
-}
-\f
-/* update VMAP info with ldinfo() information
-   Input is ptr to ldinfo() results.  */
-
-static void
-vmap_ldinfo (LdInfo *ldi)
-{
-  struct stat ii, vi;
-  struct vmap *vp;
-  int got_one, retried;
-  int got_exec_file = 0;
-  uint next;
-  int arch64 = ARCH64 ();
-
-  /* For each *ldi, see if we have a corresponding *vp.
-     If so, update the mapping, and symbol table.
-     If not, add an entry and symbol table.  */
-
-  do
-    {
-      char *name = LDI_FILENAME (ldi, arch64);
-      char *memb = name + strlen (name) + 1;
-      int fd = LDI_FD (ldi, arch64);
-
-      retried = 0;
-
-      if (fstat (fd, &ii) < 0)
-       {
-         /* The kernel sets ld_info to -1, if the process is still using the
-            object, and the object is removed.  Keep the symbol info for the
-            removed object and issue a warning.  */
-         warning (_("%s (fd=%d) has disappeared, keeping its symbols"),
-                  name, fd);
-         continue;
-       }
-    retry:
-      for (got_one = 0, vp = vmap; vp; vp = vp->nxt)
-       {
-         struct objfile *objfile;
-
-         /* First try to find a `vp', which is the same as in ldinfo.
-            If not the same, just continue and grep the next `vp'.  If same,
-            relocate its tstart, tend, dstart, dend values.  If no such `vp'
-            found, get out of this for loop, add this ldi entry as a new vmap
-            (add_vmap) and come back, find its `vp' and so on...  */
-
-         /* The filenames are not always sufficient to match on.  */
-
-         if ((name[0] == '/' && strcmp (name, vp->name) != 0)
-             || (memb[0] && strcmp (memb, vp->member) != 0))
-           continue;
-
-         /* See if we are referring to the same file.
-            We have to check objfile->obfd, symfile.c:reread_symbols might
-            have updated the obfd after a change.  */
-         objfile = vp->objfile == NULL ? symfile_objfile : vp->objfile;
-         if (objfile == NULL
-             || objfile->obfd == NULL
-             || bfd_stat (objfile->obfd, &vi) < 0)
-           {
-             warning (_("Unable to stat %s, keeping its symbols"), name);
-             continue;
-           }
-
-         if (ii.st_dev != vi.st_dev || ii.st_ino != vi.st_ino)
-           continue;
-
-         if (!retried)
-           close (fd);
-
-         ++got_one;
-
-         /* Found a corresponding VMAP.  Remap!  */
-
-         vmap_secs (vp, ldi, arch64);
-
-         /* The objfile is only NULL for the exec file.  */
-         if (vp->objfile == NULL)
-           got_exec_file = 1;
-
-         /* relocate symbol table(s).  */
-         vmap_symtab (vp);
-
-         /* Announce new object files.  Doing this after symbol relocation
-            makes aix-thread.c's job easier.  */
-         if (vp->objfile)
-           observer_notify_new_objfile (vp->objfile);
-
-         /* There may be more, so we don't break out of the loop.  */
-       }
-
-      /* If there was no matching *vp, we must perforce create the
-        sucker(s). */
-      if (!got_one && !retried)
-       {
-         add_vmap (ldi);
-         ++retried;
-         goto retry;
-       }
-    }
-  while ((next = LDI_NEXT (ldi, arch64))
-        && (ldi = (void *) (next + (char *) ldi)));
-
-  /* If we don't find the symfile_objfile anywhere in the ldinfo, it
-     is unlikely that the symbol file is relocated to the proper
-     address.  And we might have attached to a process which is
-     running a different copy of the same executable.  */
-  if (symfile_objfile != NULL && !got_exec_file)
-    {
-      warning (_("Symbol file %s\nis not mapped; discarding it.\n\
-If in fact that file has symbols which the mapped files listed by\n\
-\"info files\" lack, you can load symbols with the \"symbol-file\" or\n\
-\"add-symbol-file\" commands (note that you must take care of relocating\n\
-symbols to the proper address)."),
-              symfile_objfile->name);
-      free_objfile (symfile_objfile);
-      gdb_assert (symfile_objfile == NULL);
-    }
-  breakpoint_re_set ();
-}
-\f
-/* As well as symbol tables, exec_sections need relocation.  After
-   the inferior process' termination, there will be a relocated symbol
-   table exist with no corresponding inferior process.  At that time, we
-   need to use `exec' bfd, rather than the inferior process's memory space
-   to look up symbols.
-
-   `exec_sections' need to be relocated only once, as long as the exec
-   file remains unchanged.  */
-
-static void
-vmap_exec (void)
-{
-  static bfd *execbfd;
-  int i;
-  struct target_section_table *table = target_get_section_table (&exec_ops);
-
-  if (execbfd == exec_bfd)
-    return;
-
-  execbfd = exec_bfd;
-
-  if (!vmap || !table->sections)
-    error (_("vmap_exec: vmap or table->sections == 0."));
-
-  for (i = 0; &table->sections[i] < table->sections_end; i++)
-    {
-      if (strcmp (".text", table->sections[i].the_bfd_section->name) == 0)
-       {
-         table->sections[i].addr += vmap->tstart - vmap->tvma;
-         table->sections[i].endaddr += vmap->tstart - vmap->tvma;
-       }
-      else if (strcmp (".data", table->sections[i].the_bfd_section->name) == 0)
-       {
-         table->sections[i].addr += vmap->dstart - vmap->dvma;
-         table->sections[i].endaddr += vmap->dstart - vmap->dvma;
-       }
-      else if (strcmp (".bss", table->sections[i].the_bfd_section->name) == 0)
-       {
-         table->sections[i].addr += vmap->dstart - vmap->dvma;
-         table->sections[i].endaddr += vmap->dstart - vmap->dvma;
-       }
-    }
-}
-
 /* Set the current architecture from the host running GDB.  Called when
    starting a child process.  */
 
 /* Set the current architecture from the host running GDB.  Called when
    starting a child process.  */
 
@@ -1101,195 +673,209 @@ rs6000_create_inferior (struct target_ops * ops, char *exec_file,
                    _("rs6000_create_inferior: failed "
                      "to select architecture"));
 }
                    _("rs6000_create_inferior: failed "
                      "to select architecture"));
 }
-
 \f
 \f
-/* xcoff_relocate_symtab -      hook for symbol table relocation.
-   
-   This is only applicable to live processes, and is a no-op when
-   debugging a core file.  */
 
 
-void
-xcoff_relocate_symtab (unsigned int pid)
-{
-  int load_segs = 64; /* number of load segments */
-  int rc;
-  LdInfo *ldi = NULL;
-  int arch64 = ARCH64 ();
-  int ldisize = arch64 ? sizeof (ldi->l64) : sizeof (ldi->l32);
-  int size;
+/* Shared Object support.  */
 
 
-  /* Nothing to do if we are debugging a core file.  */
-  if (!target_has_execution)
-    return;
+/* Return the LdInfo data for the given process.  Raises an error
+   if the data could not be obtained.
 
 
-  do
-    {
-      size = load_segs * ldisize;
-      ldi = (void *) xrealloc (ldi, size);
+   The returned value must be deallocated after use.  */
 
 
-#if 0
-      /* According to my humble theory, AIX has some timing problems and
-         when the user stack grows, kernel doesn't update stack info in time
-         and ptrace calls step on user stack.  That is why we sleep here a
-         little, and give kernel to update its internals.  */
-      usleep (36000);
-#endif
+static LdInfo *
+rs6000_ptrace_ldinfo (ptid_t ptid)
+{
+  const int pid = ptid_get_pid (ptid);
+  int ldi_size = 1024;
+  LdInfo *ldi = xmalloc (ldi_size);
+  int rc = -1;
 
 
-      if (arch64)
-       rc = rs6000_ptrace64 (PT_LDINFO, pid, (unsigned long) ldi, size, NULL);
-      else
-       rc = rs6000_ptrace32 (PT_LDINFO, pid, (int *) ldi, size, NULL);
-
-      if (rc == -1)
-        {
-          if (errno == ENOMEM)
-            load_segs *= 2;
-          else
-            perror_with_name (_("ptrace ldinfo"));
-        }
+  while (1)
+    {
+      if (ARCH64 ())
+       rc = rs6000_ptrace64 (PT_LDINFO, pid, (unsigned long) ldi, ldi_size,
+                             NULL);
       else
       else
-       {
-          vmap_ldinfo (ldi);
-          vmap_exec (); /* relocate the exec and core sections as well.  */
-       }
-    } while (rc == -1);
-  if (ldi)
-    xfree (ldi);
+       rc = rs6000_ptrace32 (PT_LDINFO, pid, (int *) ldi, ldi_size, NULL);
+
+      if (rc != -1)
+       break; /* Success, we got the entire ld_info data.  */
+
+      if (errno != ENOMEM)
+       perror_with_name (_("ptrace ldinfo"));
+
+      /* ldi is not big enough.  Double it and try again.  */
+      ldi_size *= 2;
+      ldi = xrealloc (ldi, ldi_size);
+    }
+
+  return ldi;
 }
 }
-\f
-/* Core file stuff.  */
 
 
-/* Relocate symtabs and read in shared library info, based on symbols
-   from the core file.  */
+/* Assuming ABFD refers to a core file, return the LdInfo data
+   stored in that core file.  Raises an error if the data could
+   not be read or extracted.
 
 
-void
-xcoff_relocate_core (struct target_ops *target)
+   The returned value much be deallocated after use.  */
+
+static LdInfo *
+rs6000_core_ldinfo (bfd *abfd)
 {
   struct bfd_section *ldinfo_sec;
 {
   struct bfd_section *ldinfo_sec;
-  int offset = 0;
-  LdInfo *ldi;
-  struct vmap *vp;
-  int arch64 = ARCH64 ();
+  int ldinfo_size;
+  gdb_byte *ldinfo_buf;
+  struct cleanup *cleanup;
 
 
-  /* Size of a struct ld_info except for the variable-length filename.  */
-  int nonfilesz = (int)LDI_FILENAME ((LdInfo *)0, arch64);
+  ldinfo_sec = bfd_get_section_by_name (abfd, ".ldinfo");
+  if (ldinfo_sec == NULL)
+    error (_("cannot find .ldinfo section from core file: %s\n"),
+          bfd_errmsg (bfd_get_error ()));
+  ldinfo_size = bfd_get_section_size (ldinfo_sec);
 
 
-  /* Allocated size of buffer.  */
-  int buffer_size = nonfilesz;
-  char *buffer = xmalloc (buffer_size);
-  struct cleanup *old = make_cleanup (free_current_contents, &buffer);
+  ldinfo_buf = xmalloc (ldinfo_size);
+  cleanup = make_cleanup (xfree, ldinfo_buf);
 
 
-  ldinfo_sec = bfd_get_section_by_name (core_bfd, ".ldinfo");
-  if (ldinfo_sec == NULL)
+  if (! bfd_get_section_contents (abfd, ldinfo_sec,
+                                 ldinfo_buf, 0, ldinfo_size))
+    error (_("unable to read .ldinfo section from core file: %s\n"),
+          bfd_errmsg (bfd_get_error ()));
+
+  discard_cleanups (cleanup);
+  return (LdInfo *) ldinfo_buf;
+}
+
+/* Append to OBJSTACK an XML string description of the shared library
+   corresponding to LDI, following the TARGET_OBJECT_AIX_LIBRARIES
+   format.  */
+
+static void
+rs6000_xfer_shared_library (LdInfo *ldi, struct obstack *obstack)
+{
+  const int arch64 = ARCH64 ();
+  const char *archive_name = LDI_FILENAME (ldi, arch64);
+  const char *member_name = archive_name + strlen (archive_name) + 1;
+  CORE_ADDR text_addr, data_addr;
+  ULONGEST text_size, data_size;
+  char *p;
+
+  if (arch64)
     {
     {
-    bfd_err:
-      fprintf_filtered (gdb_stderr, "Couldn't get ldinfo from core file: %s\n",
-                       bfd_errmsg (bfd_get_error ()));
-      do_cleanups (old);
-      return;
+      text_addr = ldi->l64.ldinfo_textorg;
+      text_size = ldi->l64.ldinfo_textsize;
+      data_addr = ldi->l64.ldinfo_dataorg;
+      data_size = ldi->l64.ldinfo_datasize;
     }
     }
-  do
+  else
     {
     {
-      int i;
-      int names_found = 0;
+      /* The text and data addresses are defined as pointers.
+        To avoid sign-extending their value in the assignments
+        below, we cast their value to unsigned long first.  */
+      text_addr = (unsigned long) ldi->l32.ldinfo_textorg;
+      text_size = ldi->l32.ldinfo_textsize;
+      data_addr = (unsigned long) ldi->l32.ldinfo_dataorg;
+      data_size = ldi->l32.ldinfo_datasize;
+    }
 
 
-      /* Read in everything but the name.  */
-      if (bfd_get_section_contents (core_bfd, ldinfo_sec, buffer,
-                                   offset, nonfilesz) == 0)
-       goto bfd_err;
+  obstack_grow_str (obstack, "<library name=\"");
+  p = xml_escape_text (archive_name);
+  obstack_grow_str (obstack, p);
+  xfree (p);
+  obstack_grow_str (obstack, "\"");
 
 
-      /* Now the name.  */
-      i = nonfilesz;
-      do
-       {
-         if (i == buffer_size)
-           {
-             buffer_size *= 2;
-             buffer = xrealloc (buffer, buffer_size);
-           }
-         if (bfd_get_section_contents (core_bfd, ldinfo_sec, &buffer[i],
-                                       offset + i, 1) == 0)
-           goto bfd_err;
-         if (buffer[i++] == '\0')
-           ++names_found;
-       }
-      while (names_found < 2);
+  if (member_name[0] != '\0')
+    {
+      obstack_grow_str (obstack, " member=\"");
+      p = xml_escape_text (member_name);
+      obstack_grow_str (obstack, p);
+      xfree (p);
+      obstack_grow_str (obstack, "\"");
+    }
 
 
-      ldi = (LdInfo *) buffer;
+  obstack_grow_str (obstack, " text_addr=\"");
+  obstack_grow_str (obstack, core_addr_to_string (text_addr));
+  obstack_grow_str (obstack, "\"");
 
 
-      /* Can't use a file descriptor from the core file; need to open it.  */
-      if (arch64)
-       ldi->l64.ldinfo_fd = -1;
-      else
-       ldi->l32.ldinfo_fd = -1;
+  obstack_grow_str (obstack, " text_size=\"");
+  obstack_grow_str (obstack, pulongest (text_size));
+  obstack_grow_str (obstack, "\"");
 
 
-      /* The first ldinfo is for the exec file, allocated elsewhere.  */
-      if (offset == 0 && vmap != NULL)
-       vp = vmap;
-      else
-       vp = add_vmap (ldi);
+  obstack_grow_str (obstack, " data_addr=\"");
+  obstack_grow_str (obstack, core_addr_to_string (data_addr));
+  obstack_grow_str (obstack, "\"");
 
 
-      /* Process next shared library upon error.  */
-      offset += LDI_NEXT (ldi, arch64);
-      if (vp == NULL)
-       continue;
+  obstack_grow_str (obstack, " data_size=\"");
+  obstack_grow_str (obstack, pulongest (data_size));
+  obstack_grow_str (obstack, "\"");
 
 
-      vmap_secs (vp, ldi, arch64);
+  obstack_grow_str (obstack, "></library>");
+}
 
 
-      /* Unless this is the exec file,
-         add our sections to the section table for the core target.  */
-      if (vp != vmap)
-       {
-         struct target_section *stp;
+/* Implement the to_xfer_partial target_ops method for
+   TARGET_OBJECT_AIX_LIBRARIES objects.  */
 
 
-         stp = deprecated_core_resize_section_table (2);
+static LONGEST
+rs6000_xfer_shared_libraries
+  (struct target_ops *ops, enum target_object object,
+   const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf,
+   ULONGEST offset, LONGEST len)
+{
+  const int arch64 = ARCH64 ();
+  LdInfo *ldi_data;
+  LdInfo *ldi;
+  struct obstack obstack;
+  const char *buf;
+  LONGEST len_avail;
 
 
-         stp->bfd = vp->bfd;
-         stp->the_bfd_section = bfd_get_section_by_name (stp->bfd, ".text");
-         stp->addr = vp->tstart;
-         stp->endaddr = vp->tend;
-         stp++;
+  if (writebuf)
+    return -1;
 
 
-         stp->bfd = vp->bfd;
-         stp->the_bfd_section = bfd_get_section_by_name (stp->bfd, ".data");
-         stp->addr = vp->dstart;
-         stp->endaddr = vp->dend;
-       }
+  /* Get the ldinfo raw data: If debugging a live process, we get it
+     using ptrace.  Otherwise, the info is stored in the .ldinfo
+     section of the core file.  */
+
+  if (target_has_execution)
+    ldi_data = rs6000_ptrace_ldinfo (inferior_ptid);
+  else
+    ldi_data = rs6000_core_ldinfo (core_bfd);
+
+  /* Convert the raw data into an XML representation.  */
 
 
-      vmap_symtab (vp);
+  obstack_init (&obstack);
+  obstack_grow_str (&obstack, "<library-list version=\"1.0\">\n");
 
 
-      if (vp != vmap && vp->objfile)
-       observer_notify_new_objfile (vp->objfile);
+  ldi = ldi_data;
+  while (1)
+    {
+      /* Close the fd.  We cannot use it, because we cannot assume
+        that the user of this descriptor will be in the same
+        process.  */
+      close (LDI_FD (ldi, arch64));
+
+      rs6000_xfer_shared_library (ldi, &obstack);
+
+      if (!LDI_NEXT (ldi, arch64))
+       break;
+      ldi = (LdInfo *) ((char *) ldi + LDI_NEXT (ldi, arch64));
     }
     }
-  while (LDI_NEXT (ldi, arch64) != 0);
-  vmap_exec ();
-  breakpoint_re_set ();
-  do_cleanups (old);
-}
-\f
-/* Under AIX, we have to pass the correct TOC pointer to a function
-   when calling functions in the inferior.
-   We try to find the relative toc offset of the objfile containing PC
-   and add the current load address of the data segment from the vmap.  */
 
 
-static CORE_ADDR
-find_toc_address (CORE_ADDR pc)
-{
-  struct vmap *vp;
+  xfree (ldi_data);
+
+  obstack_grow_str0 (&obstack, "</library-list>\n");
 
 
-  for (vp = vmap; vp; vp = vp->nxt)
+  buf = obstack_finish (&obstack);
+  len_avail = strlen (buf);
+  if (offset >= len_avail)
+    len= 0;
+  else
     {
     {
-      if (pc >= vp->tstart && pc < vp->tend)
-       {
-         /* vp->objfile is only NULL for the exec file.  */
-         return vp->dstart + xcoff_get_toc_offset (vp->objfile == NULL
-                                                   ? symfile_objfile
-                                                   : vp->objfile);
-       }
+      if (len > len_avail - offset)
+        len = len_avail - offset;
+      memcpy (readbuf, buf + offset, len);
     }
     }
-  error (_("Unable to find TOC entry for pc %s."), hex_string (pc));
+
+  obstack_free (&obstack, NULL);
+  return len;
 }
 }
-\f
 
 void _initialize_rs6000_nat (void);
 
 
 void _initialize_rs6000_nat (void);
 
@@ -1309,8 +895,4 @@ _initialize_rs6000_nat (void)
   t->to_wait = rs6000_wait;
 
   add_target (t);
   t->to_wait = rs6000_wait;
 
   add_target (t);
-
-  /* Initialize hook in rs6000-tdep.c for determining the TOC address
-     when calling functions in the inferior.  */
-  rs6000_find_toc_address_hook = find_toc_address;
 }
 }
index 569655a..ad983bb 100644 (file)
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-/* Hook in rs6000-aix-tdep.c for determining the TOC address when
-   calling functions in the inferior.  */
-extern CORE_ADDR (*rs6000_find_toc_address_hook) (CORE_ADDR);
-
 /* Minimum possible text address in AIX.  */
 #define AIX_TEXT_SEGMENT_BASE 0x10000000
 
 /* Minimum possible text address in AIX.  */
 #define AIX_TEXT_SEGMENT_BASE 0x10000000
 
diff --git a/gdb/solib-aix.c b/gdb/solib-aix.c
new file mode 100644 (file)
index 0000000..8c17a6f
--- /dev/null
@@ -0,0 +1,830 @@
+/* Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "solib-aix.h"
+#include "solist.h"
+#include "inferior.h"
+#include "gdb_bfd.h"
+#include "gdbcore.h"
+#include "objfiles.h"
+#include "symtab.h"
+#include "xcoffread.h"
+#include "observer.h"
+#include "gdbcmd.h"
+
+/* Variable controlling the output of the debugging traces for
+   this module.  */
+static int solib_aix_debug;
+
+/* Our private data in struct so_list.  */
+
+struct lm_info
+{
+  /* The name of the file mapped by the loader.  Apart from the entry
+     for the main executable, this is usually a shared library (which,
+     on AIX, is an archive library file, created using the "ar"
+     command).  */
+  char *filename;
+
+  /* The name of the shared object file with the actual dynamic
+     loading dependency.  This may be NULL (Eg. main executable).  */
+  char *member_name;
+
+  /* The address in inferior memory where the text section got mapped.  */
+  CORE_ADDR text_addr;
+
+  /* The size of the text section, obtained via the loader data.  */
+  ULONGEST text_size;
+
+  /* The address in inferior memory where the data section got mapped.  */
+  CORE_ADDR data_addr;
+
+  /* The size of the data section, obtained via the loader data.  */
+  ULONGEST data_size;
+};
+
+typedef struct lm_info *lm_info_p;
+DEF_VEC_P(lm_info_p);
+
+/* Return a deep copy of the given struct lm_info object.  */
+
+static struct lm_info *
+solib_aix_new_lm_info (struct lm_info *info)
+{
+  struct lm_info *result = xmalloc (sizeof (struct lm_info));
+
+  memcpy (result, info, sizeof (struct lm_info));
+  result->filename = xstrdup (info->filename);
+  if (info->member_name != NULL)
+    result->member_name = xstrdup (info->member_name);
+
+  return result;
+}
+
+/* Free the memory allocated for the given lm_info.  */
+
+static void
+solib_aix_xfree_lm_info (struct lm_info *info)
+{
+  xfree (info->filename);
+  xfree (info->member_name);
+  xfree (info);
+}
+
+/* This module's per-inferior data.  */
+
+struct solib_aix_inferior_data
+{
+  /* The list of shared libraries.  NULL if not computed yet.
+
+     Note that the first element of this list is always the main
+     executable, which is not technically a shared library.  But
+     we need that information to perform its relocation, and
+     the same principles applied to shared libraries also apply
+     to the main executable.  So it's simpler to keep it as part
+     of this list.  */
+  VEC (lm_info_p) *library_list;
+};
+
+/* Key to our per-inferior data.  */
+static const struct inferior_data *solib_aix_inferior_data_handle;
+
+/* Return this module's data for the given inferior.
+   If none is found, add a zero'ed one now.  */
+
+static struct solib_aix_inferior_data *
+get_solib_aix_inferior_data (struct inferior *inf)
+{
+  struct solib_aix_inferior_data *data;
+
+  data = inferior_data (inf, solib_aix_inferior_data_handle);
+  if (data == NULL)
+    {
+      data = XZALLOC (struct solib_aix_inferior_data);
+      set_inferior_data (inf, solib_aix_inferior_data_handle, data);
+    }
+
+  return data;
+}
+
+#if !defined(HAVE_LIBEXPAT)
+
+/* Dummy implementation if XML support is not compiled in.  */
+
+static VEC (lm_info_p) *
+solib_aix_parse_libraries (const char *library)
+{
+  static int have_warned;
+
+  if (!have_warned)
+    {
+      have_warned = 1;
+      warning (_("Can not parse XML library list; XML support was disabled "
+                 "at compile time"));
+    }
+
+  return NULL;
+}
+
+#else /* HAVE_LIBEXPAT */
+
+#include "xml-support.h"
+
+/* Handle the start of a <library> element.  */
+
+static void
+library_list_start_library (struct gdb_xml_parser *parser,
+                           const struct gdb_xml_element *element,
+                           void *user_data,
+                           VEC (gdb_xml_value_s) *attributes)
+{
+  VEC (lm_info_p) **list = user_data;
+  struct lm_info *item = XZALLOC (struct lm_info);
+  struct gdb_xml_value *attr;
+
+  attr = xml_find_attribute (attributes, "name");
+  item->filename = xstrdup (attr->value);
+
+  attr = xml_find_attribute (attributes, "member");
+  if (attr != NULL)
+    item->member_name = xstrdup (attr->value);
+
+  attr = xml_find_attribute (attributes, "text_addr");
+  item->text_addr = * (ULONGEST *) attr->value;
+
+  attr = xml_find_attribute (attributes, "text_size");
+  item->text_size = * (ULONGEST *) attr->value;
+
+  attr = xml_find_attribute (attributes, "data_addr");
+  item->data_addr = * (ULONGEST *) attr->value;
+
+  attr = xml_find_attribute (attributes, "data_size");
+  item->data_size = * (ULONGEST *) attr->value;
+
+  VEC_safe_push (lm_info_p, *list, item);
+}
+
+/* Handle the start of a <library-list> element.  */
+
+static void
+library_list_start_list (struct gdb_xml_parser *parser,
+                         const struct gdb_xml_element *element,
+                         void *user_data, VEC (gdb_xml_value_s) *attributes)
+{
+  char *version = xml_find_attribute (attributes, "version")->value;
+
+  if (strcmp (version, "1.0") != 0)
+    gdb_xml_error (parser,
+                   _("Library list has unsupported version \"%s\""),
+                   version);
+}
+
+/* Discard the constructed library list.  */
+
+static void
+solib_aix_free_library_list (void *p)
+{
+  VEC (lm_info_p) **result = p;
+  struct lm_info *info;
+  int ix;
+
+  if (solib_aix_debug)
+    fprintf_unfiltered (gdb_stdlog, "DEBUG: solib_aix_free_library_list\n");
+
+  for (ix = 0; VEC_iterate (lm_info_p, *result, ix, info); ix++)
+    solib_aix_xfree_lm_info (info);
+  VEC_free (lm_info_p, *result);
+  *result = NULL;
+}
+
+/* The allowed elements and attributes for an AIX library list
+   described in XML format.  The root element is a <library-list>.  */
+
+static const struct gdb_xml_attribute library_attributes[] =
+{
+  { "name", GDB_XML_AF_NONE, NULL, NULL },
+  { "member", GDB_XML_AF_OPTIONAL, NULL, NULL },
+  { "text_addr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+  { "text_size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+  { "data_addr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+  { "data_size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
+  { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element library_list_children[] =
+{
+  { "library", library_attributes, NULL,
+    GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
+    library_list_start_library, NULL},
+  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_attribute library_list_attributes[] =
+{
+  { "version", GDB_XML_AF_NONE, NULL, NULL },
+  { NULL, GDB_XML_AF_NONE, NULL, NULL }
+};
+
+static const struct gdb_xml_element library_list_elements[] =
+{
+  { "library-list", library_list_attributes, library_list_children,
+    GDB_XML_EF_NONE, library_list_start_list, NULL },
+  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+/* Parse LIBRARY, a string containing the loader info in XML format,
+   and return an lm_info_p vector.
+
+   Return NULL if the parsing failed.  */
+
+static VEC (lm_info_p) *
+solib_aix_parse_libraries (const char *library)
+{
+  VEC (lm_info_p) *result = NULL;
+  struct cleanup *back_to = make_cleanup (solib_aix_free_library_list,
+                                          &result);
+
+  if (gdb_xml_parse_quick (_("aix library list"), "library-list-aix.dtd",
+                           library_list_elements, library, &result) == 0)
+    {
+      /* Parsed successfully, keep the result.  */
+      discard_cleanups (back_to);
+      return result;
+    }
+
+  do_cleanups (back_to);
+  return NULL;
+}
+
+#endif /* HAVE_LIBEXPAT */
+
+/* Return the loader info for the given inferior (INF), or NULL if
+   the list could not be computed.
+
+   Cache the result in per-inferior data, so as to avoid recomputing it
+   each time this function is called.
+
+   If an error occurs while computing this list, and WARNING_MSG
+   is not NULL, then print a warning including WARNING_MSG and
+   a description of the error.  */
+
+static VEC (lm_info_p) *
+solib_aix_get_library_list (struct inferior *inf, const char *warning_msg)
+{
+  struct solib_aix_inferior_data *data;
+  char *library_document;
+  struct cleanup *cleanup;
+
+  /* If already computed, return the cached value.  */
+  data = get_solib_aix_inferior_data (inf);
+  if (data->library_list != NULL)
+    return data->library_list;
+
+  library_document = target_read_stralloc (&current_target,
+                                           TARGET_OBJECT_AIX_LIBRARIES,
+                                           NULL);
+  if (library_document == NULL && warning_msg != NULL)
+    {
+      warning (_("%s (failed to read TARGET_OBJECT_AIX_LIBRARIES)"),
+              warning_msg);
+      return NULL;
+    }
+  cleanup = make_cleanup (xfree, library_document);
+
+  if (solib_aix_debug)
+    fprintf_unfiltered (gdb_stdlog,
+                       "DEBUG: TARGET_OBJECT_AIX_LIBRARIES = \n%s\n",
+                       library_document);
+
+  data->library_list = solib_aix_parse_libraries (library_document);
+  if (data->library_list == NULL && warning_msg != NULL)
+    {
+      warning (_("%s (missing XML support?)"), warning_msg);
+      do_cleanups (cleanup);
+      return NULL;
+    }
+
+  do_cleanups (cleanup);
+  return data->library_list;
+}
+
+/* If the .bss section's VMA is set to an address located before
+   the end of the .data section, causing the two sections to overlap,
+   return the overlap in bytes.  Otherwise, return zero.
+
+   Motivation:
+
+   The GNU linker sometimes sets the start address of the .bss session
+   before the end of the .data section, making the 2 sections overlap.
+   The loader appears to handle this situation gracefully, by simply
+   loading the bss section right after the end of the .data section.
+
+   This means that the .data and the .bss sections are sometimes
+   no longer relocated by the same amount.  The problem is that
+   the ldinfo data does not contain any information regarding
+   the relocation of the .bss section, assuming that it would be
+   identical to the information provided for the .data section
+   (this is what would normally happen if the program was linked
+   correctly).
+
+   GDB therefore needs to detect those cases, and make the corresponding
+   adjustment to the .bss section offset computed from the ldinfo data
+   when necessary.  This function returns the adjustment amount  (or
+   zero when no adjustment is needed).  */
+
+static CORE_ADDR
+solib_aix_bss_data_overlap (bfd *abfd)
+{
+  struct bfd_section *data_sect, *bss_sect;
+
+  data_sect = bfd_get_section_by_name (abfd, ".data");
+  if (data_sect == NULL)
+    return 0; /* No overlap possible.  */
+
+  bss_sect = bfd_get_section_by_name (abfd, ".bss");
+  if (bss_sect == NULL)
+    return 0; /* No overlap possible.  */
+
+  /* Assume the problem only occurs with linkers that place the .bss
+     section after the .data section (the problem has only been
+     observed when using the GNU linker, and the default linker
+     script always places the .data and .bss sections in that order).  */
+  if (bfd_section_vma (abfd, bss_sect)
+      < bfd_section_vma (abfd, data_sect))
+    return 0;
+
+  if (bfd_section_vma (abfd, bss_sect)
+      < bfd_section_vma (abfd, data_sect) + bfd_get_section_size (data_sect))
+    return ((bfd_section_vma (abfd, data_sect)
+            + bfd_get_section_size (data_sect))
+           - bfd_section_vma (abfd, bss_sect));
+
+  return 0;
+}
+
+/* Implement the "relocate_section_addresses" target_so_ops method.  */
+
+static void
+solib_aix_relocate_section_addresses (struct so_list *so,
+                                     struct target_section *sec)
+{
+  bfd *abfd = sec->bfd;
+  struct bfd_section *bfd_sect = sec->the_bfd_section;
+  const char *section_name = bfd_section_name (abfd, bfd_sect);
+  struct lm_info *info = so->lm_info;
+
+  if (strcmp (section_name, ".text") == 0)
+    {
+      sec->addr = info->text_addr;
+      sec->endaddr = sec->addr + info->text_size;
+
+      /* The text address given to us by the loader contains
+        XCOFF headers, so we need to adjust by this much.  */
+      sec->addr += bfd_sect->filepos;
+    }
+  else if (strcmp (section_name, ".data") == 0)
+    {
+      sec->addr = info->data_addr;
+      sec->endaddr = sec->addr + info->data_size;
+    }
+  else if (strcmp (section_name, ".bss") == 0)
+    {
+      sec->addr = bfd_section_vma (abfd, bfd_sect) + info->data_addr;
+      sec->addr += solib_aix_bss_data_overlap (abfd);
+      sec->endaddr = sec->addr + bfd_section_size (abfd, bfd_sect);
+    }
+  else
+    {
+      /* All other sections should not be relocated.  */
+      /* FIXME: GDB complains that the .loader section sometimes
+        overlaps with other sections (Eg: the .data section).
+        As far as I can tell, the loader section had the LOAD flag
+        set, but not the RELOC.  So it should not be relocated.
+        There seems to be a problem there, and maybe it has to do
+        with setting sec->addr to 0 (when the vma is indeed 0).
+        But even if there wasn't, the problem then becomes the fact
+        that many shared objects inside shared libraries have
+        a .loader section whose vma is 0, thus also triggering
+        an overlap warning.  */
+      sec->addr = bfd_section_vma (abfd, bfd_sect);
+      sec->endaddr = sec->addr + bfd_section_size (abfd, bfd_sect);
+    }
+}
+
+/* Implement the "free_so" target_so_ops method.  */
+
+static void
+solib_aix_free_so (struct so_list *so)
+{
+  if (solib_aix_debug)
+    fprintf_unfiltered (gdb_stdlog, "DEBUG: solib_aix_free_so (%s)\n",
+                       so->so_name);
+  solib_aix_xfree_lm_info (so->lm_info);
+}
+
+/* Implement the "clear_solib" target_so_ops method.  */
+
+static void
+solib_aix_clear_solib (void)
+{
+  /* Nothing needed.  */
+}
+
+/* Compute and return the OBJFILE's section_offset array, using
+   the associated loader info (INFO).
+
+   The resulting array is computed on the heap and must be
+   deallocated after use.  */
+
+static struct section_offsets *
+solib_aix_get_section_offsets (struct objfile *objfile,
+                              struct lm_info *info)
+{
+  struct section_offsets *offsets;
+  bfd *abfd = objfile->obfd;
+  int i;
+
+  offsets = XCALLOC (objfile->num_sections, struct section_offsets);
+
+  /* .text */
+
+  if (objfile->sect_index_text != -1)
+    {
+      struct bfd_section *sect
+       = objfile->sections[objfile->sect_index_text].the_bfd_section;
+
+      offsets->offsets[objfile->sect_index_text]
+       = info->text_addr + sect->filepos - bfd_section_vma (abfd, sect);
+    }
+
+  /* .data */
+
+  if (objfile->sect_index_data != -1)
+    {
+      struct bfd_section *sect
+       = objfile->sections[objfile->sect_index_data].the_bfd_section;
+
+      offsets->offsets[objfile->sect_index_data]
+       = info->data_addr - bfd_section_vma (abfd, sect);
+    }
+
+  /* .bss
+
+     The offset of the .bss section should be identical to the offset
+     of the .data section.  If no .data section (which seems hard to
+     believe it is possible), assume it is zero.  */
+
+  if (objfile->sect_index_bss != -1
+      && objfile->sect_index_data != -1)
+    {
+      offsets->offsets[objfile->sect_index_bss]
+       = (offsets->offsets[objfile->sect_index_data]
+          + solib_aix_bss_data_overlap (abfd));
+    }
+
+  /* All other sections should not need relocation.  */
+
+  return offsets;
+}
+
+/* Implement the "solib_create_inferior_hook" target_so_ops method.  */
+
+static void
+solib_aix_solib_create_inferior_hook (int from_tty)
+{
+  const char *warning_msg = "unable to relocate main executable";
+  VEC (lm_info_p) *library_list;
+  struct lm_info *exec_info;
+
+  /* We need to relocate the main executable...  */
+
+  library_list = solib_aix_get_library_list (current_inferior (),
+                                            warning_msg);
+  if (library_list == NULL)
+    return;  /* Warning already printed.  */
+
+  if (VEC_length (lm_info_p, library_list) < 1)
+    {
+      warning (_("unable to relocate main executable (no info from loader)"));
+      return;
+    }
+
+  exec_info = VEC_index (lm_info_p, library_list, 0);
+
+  if (symfile_objfile != NULL)
+    {
+      struct section_offsets *offsets
+       = solib_aix_get_section_offsets (symfile_objfile, exec_info);
+      struct cleanup *cleanup = make_cleanup (xfree, offsets);
+
+      objfile_relocate (symfile_objfile, offsets);
+      do_cleanups (cleanup);
+    }
+}
+
+/* Implement the "special_symbol_handling" target_so_ops method.  */
+
+static void
+solib_aix_special_symbol_handling (void)
+{
+  /* Nothing needed.  */
+}
+
+/* Implement the "current_sos" target_so_ops method.  */
+
+static struct so_list *
+solib_aix_current_sos (void)
+{
+  struct so_list *start = NULL, *last = NULL;
+  VEC (lm_info_p) *library_list;
+  struct lm_info *info;
+  int ix;
+
+  library_list = solib_aix_get_library_list (current_inferior (), NULL);
+  if (library_list == NULL)
+    return NULL;
+
+  /* Build a struct so_list for each entry on the list.
+     We skip the first entry, since this is the entry corresponding
+     to the main executable, not a shared library.  */
+  for (ix = 1; VEC_iterate (lm_info_p, library_list, ix, info); ix++)
+    {
+      struct so_list *new_solib = XZALLOC (struct so_list);
+      char *so_name;
+
+      if (info->member_name == NULL)
+       {
+        /* INFO->FILENAME is probably not an archive, but rather
+           a shared object.  Unusual, but it should be possible
+           to link a program against a shared object directory,
+           without having to put it in an archive first.  */
+        so_name = xstrdup (info->filename);
+       }
+      else
+       {
+        /* This is the usual case on AIX, where the shared object
+           is a member of an archive.  Create a synthetic so_name
+           that follows the same convention as AIX's ldd tool
+           (Eg: "/lib/libc.a(shr.o)").  */
+        so_name = xstrprintf ("%s(%s)", info->filename, info->member_name);
+       }
+      strncpy (new_solib->so_original_name, so_name,
+              SO_NAME_MAX_PATH_SIZE - 1);
+      new_solib->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
+      memcpy (new_solib->so_name, new_solib->so_original_name,
+             SO_NAME_MAX_PATH_SIZE);
+      new_solib->lm_info = solib_aix_new_lm_info (info);
+
+      /* Add it to the list.  */
+      if (!start)
+        last = start = new_solib;
+      else
+        {
+          last->next = new_solib;
+          last = new_solib;
+        }
+    }
+
+  return start;
+}
+
+/* Implement the "open_symbol_file_object" target_so_ops method.  */
+
+static int
+solib_aix_open_symbol_file_object (void *from_ttyp)
+{
+  return 0;
+}
+
+/* Implement the "in_dynsym_resolve_code" target_so_ops method.  */
+
+static int
+solib_aix_in_dynsym_resolve_code (CORE_ADDR pc)
+{
+  return 0;
+}
+
+/* Implement the "bfd_open" target_so_ops method.  */
+
+static bfd *
+solib_aix_bfd_open (char *pathname)
+{
+  /* The pathname is actually a synthetic filename with the following
+     form: "/path/to/sharedlib(member.o)" (double-quotes excluded).
+     split this into archive name and member name.
+
+     FIXME: This is a little hacky.  Perhaps we should provide access
+     to the solib's lm_info here?  */
+  const int path_len = strlen (pathname);
+  char *sep;
+  char *filename;
+  int filename_len;
+  char *member_name;
+  bfd *archive_bfd, *object_bfd;
+  struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
+
+  if (pathname[path_len - 1] != ')')
+    return solib_bfd_open (pathname);
+
+  /* Search for the associated parens.  */
+  sep = strrchr (pathname, '(');
+  if (sep == NULL)
+    {
+      /* Should never happen, but recover as best as we can (trying
+        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);
+    }
+  filename_len = sep - pathname;
+
+  filename = xstrprintf ("%.*s", filename_len, pathname);
+  make_cleanup (xfree, filename);
+  member_name = xstrprintf ("%.*s", path_len - filename_len - 2, sep + 1);
+  make_cleanup (xfree, member_name);
+
+  archive_bfd = gdb_bfd_open (filename, gnutarget, -1);
+  if (archive_bfd == NULL)
+    {
+      warning (_("Could not open `%s' as an executable file: %s"),
+              filename, bfd_errmsg (bfd_get_error ()));
+      do_cleanups (cleanup);
+      return NULL;
+    }
+
+  if (bfd_check_format (archive_bfd, bfd_object))
+    {
+      do_cleanups (cleanup);
+      return archive_bfd;
+    }
+
+  if (! bfd_check_format (archive_bfd, bfd_archive))
+    {
+      warning (_("\"%s\": not in executable format: %s."),
+              filename, bfd_errmsg (bfd_get_error ()));
+      gdb_bfd_unref (archive_bfd);
+      do_cleanups (cleanup);
+      return NULL;
+    }
+
+  object_bfd = gdb_bfd_openr_next_archived_file (archive_bfd, NULL);
+  while (object_bfd != NULL)
+    {
+      bfd *next;
+
+      if (strcmp (member_name, object_bfd->filename) == 0)
+       break;
+
+      next = gdb_bfd_openr_next_archived_file (archive_bfd, object_bfd);
+      gdb_bfd_unref (object_bfd);
+      object_bfd = next;
+    }
+
+  if (object_bfd == NULL)
+    {
+      warning (_("\"%s\": member \"%s\" missing."), filename, member_name);
+      gdb_bfd_unref (archive_bfd);
+      do_cleanups (cleanup);
+      return NULL;
+    }
+
+  if (! bfd_check_format (object_bfd, bfd_object))
+    {
+      warning (_("%s(%s): not in object format: %s."),
+              filename, member_name, bfd_errmsg (bfd_get_error ()));
+      gdb_bfd_unref (archive_bfd);
+      gdb_bfd_unref (object_bfd);
+      do_cleanups (cleanup);
+      return NULL;
+    }
+
+  gdb_bfd_unref (archive_bfd);
+  do_cleanups (cleanup);
+  return object_bfd;
+}
+
+/* Return the obj_section corresponding to OBJFILE's data section,
+   or NULL if not found.  */
+/* FIXME: Define in a more general location? */
+
+static struct obj_section *
+data_obj_section_from_objfile (struct objfile *objfile)
+{
+  struct obj_section *osect;
+
+  ALL_OBJFILE_OSECTIONS (objfile, osect)
+    if (strcmp (bfd_section_name (objfile->obfd, osect->the_bfd_section),
+               ".data") == 0)
+      return osect;
+
+  return NULL;
+}
+
+/* Return the TOC value corresponding to the given PC address,
+   or raise an error if the value could not be determined.  */
+
+CORE_ADDR
+solib_aix_get_toc_value (CORE_ADDR pc)
+{
+  struct obj_section *pc_osect = find_pc_section (pc);
+  struct obj_section *data_osect;
+  CORE_ADDR result;
+
+  if (pc_osect == NULL)
+    error (_("unable to find TOC entry for pc %s "
+            "(no section contains this PC)"),
+          core_addr_to_string (pc));
+
+  data_osect = data_obj_section_from_objfile (pc_osect->objfile);
+  if (data_osect == NULL)
+    error (_("unable to find TOC entry for pc %s "
+            "(%s has no data section)"),
+          core_addr_to_string (pc), pc_osect->objfile->name);
+
+  result = (obj_section_addr (data_osect)
+           + xcoff_get_toc_offset (pc_osect->objfile));
+  if (solib_aix_debug)
+    fprintf_unfiltered (gdb_stdlog,
+                       "DEBUG: solib_aix_get_toc_value (pc=%s) -> %s\n",
+                       core_addr_to_string (pc),
+                       core_addr_to_string (result));
+
+  return result;
+}
+
+/* This module's normal_stop observer.  */
+
+static void
+solib_aix_normal_stop_observer (struct bpstats *unused_1, int unused_2)
+{
+  struct solib_aix_inferior_data *data
+    = get_solib_aix_inferior_data (current_inferior ());
+
+  /* The inferior execution has been resumed, and it just stopped
+     again.  This means that the list of shared libraries may have
+     evolved.  Reset our cached value.  */
+  solib_aix_free_library_list (&data->library_list);
+}
+
+/* Implements the "show debug aix-solib" command.  */
+
+static void
+show_solib_aix_debug (struct ui_file *file, int from_tty,
+                     struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("solib-aix debugging is %s.\n"), value);
+}
+
+/* The target_so_ops for AIX targets.  */
+struct target_so_ops solib_aix_so_ops;
+
+/* -Wmissing-prototypes */
+extern initialize_file_ftype _initialize_solib_aix;
+
+void
+_initialize_solib_aix (void)
+{
+  solib_aix_so_ops.relocate_section_addresses
+    = solib_aix_relocate_section_addresses;
+  solib_aix_so_ops.free_so = solib_aix_free_so;
+  solib_aix_so_ops.clear_solib = solib_aix_clear_solib;
+  solib_aix_so_ops.solib_create_inferior_hook
+    = solib_aix_solib_create_inferior_hook;
+  solib_aix_so_ops.special_symbol_handling
+    = solib_aix_special_symbol_handling;
+  solib_aix_so_ops.current_sos = solib_aix_current_sos;
+  solib_aix_so_ops.open_symbol_file_object
+    = solib_aix_open_symbol_file_object;
+  solib_aix_so_ops.in_dynsym_resolve_code
+    = solib_aix_in_dynsym_resolve_code;
+  solib_aix_so_ops.bfd_open = solib_aix_bfd_open;
+
+  solib_aix_inferior_data_handle = register_inferior_data ();
+
+  observer_attach_normal_stop (solib_aix_normal_stop_observer);
+
+  /* Debug this file's internals.  */
+  add_setshow_boolean_cmd ("aix-solib", class_maintenance,
+                          &solib_aix_debug, _("\
+Control the debugging traces for the solib-aix module."), _("\
+Show whether solib-aix debugging traces are enabled."), _("\
+When on, solib-aix debugging traces are enabled."),
+                            NULL,
+                            show_solib_aix_debug,
+                            &setdebuglist, &showdebuglist);
+}
diff --git a/gdb/solib-aix.h b/gdb/solib-aix.h
new file mode 100644 (file)
index 0000000..a5c39b0
--- /dev/null
@@ -0,0 +1,26 @@
+/* Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.  */
+
+#ifndef SOLIB_AIX_H
+#define SOLIB_AIX_H
+
+struct target_so_ops;
+extern struct target_so_ops solib_aix_so_ops;
+
+extern CORE_ADDR solib_aix_get_toc_value (CORE_ADDR pc);
+
+#endif
index afe3f8c..c6745a9 100644 (file)
@@ -647,11 +647,11 @@ dsbt_current_sos (void)
      for details.)
 
      Note that the relocation of the main executable is also performed
      for details.)
 
      Note that the relocation of the main executable is also performed
-     by SOLIB_CREATE_INFERIOR_HOOK, however, in the case of core
+     by solib_create_inferior_hook, however, in the case of core
      files, this hook is called too late in order to be of benefit to
      files, this hook is called too late in order to be of benefit to
-     SOLIB_ADD.  SOLIB_ADD eventually calls this function,
+     solib_add.  solib_add eventually calls this function,
      dsbt_current_sos, and also precedes the call to
      dsbt_current_sos, and also precedes the call to
-     SOLIB_CREATE_INFERIOR_HOOK.   (See post_create_inferior in
+     solib_create_inferior_hook.   (See post_create_inferior in
      infcmd.c.)  */
   if (info->main_executable_lm_info == 0 && core_bfd != NULL)
     dsbt_relocate_main_executable ();
      infcmd.c.)  */
   if (info->main_executable_lm_info == 0 && core_bfd != NULL)
     dsbt_relocate_main_executable ();
@@ -1089,12 +1089,10 @@ dsbt_relocate_main_executable (void)
 
 /* When gdb starts up the inferior, it nurses it along (through the
    shell) until it is ready to execute it's first instruction.  At this
 
 /* When gdb starts up the inferior, it nurses it along (through the
    shell) until it is ready to execute it's first instruction.  At this
-   point, this function gets called via expansion of the macro
-   SOLIB_CREATE_INFERIOR_HOOK.
+   point, this function gets called via solib_create_inferior_hook.
 
    For the DSBT shared library, the main executable needs to be relocated.
 
    For the DSBT shared library, the main executable needs to be relocated.
-   The shared library breakpoints also need to be enabled.
- */
+   The shared library breakpoints also need to be enabled.  */
 
 static void
 dsbt_solib_create_inferior_hook (int from_tty)
 
 static void
 dsbt_solib_create_inferior_hook (int from_tty)
index 0f3e5d7..28fb4a4 100644 (file)
@@ -328,11 +328,11 @@ frv_current_sos (void)
      for details.)
 
      Note that the relocation of the main executable is also performed
      for details.)
 
      Note that the relocation of the main executable is also performed
-     by SOLIB_CREATE_INFERIOR_HOOK(), however, in the case of core
+     by solib_create_inferior_hook(), however, in the case of core
      files, this hook is called too late in order to be of benefit to
      files, this hook is called too late in order to be of benefit to
-     SOLIB_ADD.  SOLIB_ADD eventually calls this this function,
+     solib_add.  solib_add eventually calls this this function,
      frv_current_sos, and also precedes the call to
      frv_current_sos, and also precedes the call to
-     SOLIB_CREATE_INFERIOR_HOOK().   (See post_create_inferior() in
+     solib_create_inferior_hook().   (See post_create_inferior() in
      infcmd.c.)  */
   if (main_executable_lm_info == 0 && core_bfd != NULL)
     frv_relocate_main_executable ();
      infcmd.c.)  */
   if (main_executable_lm_info == 0 && core_bfd != NULL)
     frv_relocate_main_executable ();
index 319538f..af48388 100644 (file)
@@ -1294,11 +1294,7 @@ reload_shared_libraries (char *ignored, int from_tty,
         we're not really starting up the inferior here.  */
       remove_solib_event_breakpoints ();
 
         we're not really starting up the inferior here.  */
       remove_solib_event_breakpoints ();
 
-#ifdef SOLIB_CREATE_INFERIOR_HOOK
-      SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
-#else
       solib_create_inferior_hook (from_tty);
       solib_create_inferior_hook (from_tty);
-#endif
     }
 
   /* Sometimes the platform-specific hook loads initial shared
     }
 
   /* Sometimes the platform-specific hook loads initial shared
index c072a2e..e13a5a0 100644 (file)
@@ -1205,12 +1205,9 @@ print_frame (struct frame_info *frame, int print_level,
 
   if (pc_p && (funname == NULL || sal.symtab == NULL))
     {
 
   if (pc_p && (funname == NULL || sal.symtab == NULL))
     {
-#ifdef PC_SOLIB
-      char *lib = PC_SOLIB (get_frame_pc (frame));
-#else
       char *lib = solib_name_from_address (get_frame_program_space (frame),
                                           get_frame_pc (frame));
       char *lib = solib_name_from_address (get_frame_program_space (frame),
                                           get_frame_pc (frame));
-#endif
+
       if (lib)
        {
          annotate_frame_where ();
       if (lib)
        {
          annotate_frame_where ();
index 319fcc3..d77bcf2 100644 (file)
@@ -261,6 +261,8 @@ enum target_object
   TARGET_OBJECT_LIBRARIES,
   /* Currently loaded libraries specific for SVR4 systems, in XML format.  */
   TARGET_OBJECT_LIBRARIES_SVR4,
   TARGET_OBJECT_LIBRARIES,
   /* Currently loaded libraries specific for SVR4 systems, in XML format.  */
   TARGET_OBJECT_LIBRARIES_SVR4,
+  /* Currently loaded libraries specific to AIX systems, in XML format.  */
+  TARGET_OBJECT_AIX_LIBRARIES,
   /* Get OS specific data.  The ANNEX specifies the type (running
      processes, etc.).  The data being transfered is expected to follow
      the DTD specified in features/osdata.dtd.  */
   /* Get OS specific data.  The ANNEX specifies the type (running
      processes, etc.).  The data being transfered is expected to follow
      the DTD specified in features/osdata.dtd.  */
index 2b5f9b7..48b6935 100644 (file)
@@ -907,11 +907,16 @@ enter_line_range (struct subfile *subfile, unsigned beginoffset,
 
 /* Create a new minimal symbol (using prim_record_minimal_symbol_and_info).
 
 
 /* Create a new minimal symbol (using prim_record_minimal_symbol_and_info).
 
+   Creation of all new minimal symbols should go through this function
+   rather than calling the various prim_record_[...] functions in order
+   to make sure that all symbol addresses get properly relocated.
+
    Arguments are:
 
    NAME - the symbol's name (but if NAME starts with a period, that
    leading period is discarded).
    Arguments are:
 
    NAME - the symbol's name (but if NAME starts with a period, that
    leading period is discarded).
-   ADDRESS - the symbol's address.
+   ADDRESS - the symbol's address, prior to relocation.  This function
+      relocates the address before recording the minimal symbol.
    MS_TYPE - the symbol's type.
    N_SCNUM - the symbol's XCOFF section number.
    OBJFILE - the objfile associated with the minimal symbol.  */
    MS_TYPE - the symbol's type.
    N_SCNUM - the symbol's XCOFF section number.
    OBJFILE - the objfile associated with the minimal symbol.  */
@@ -922,9 +927,12 @@ record_minimal_symbol (const char *name, CORE_ADDR address,
                       int n_scnum,
                       struct objfile *objfile)
 {
                       int n_scnum,
                       struct objfile *objfile)
 {
+  int section = secnum_to_section (n_scnum, objfile);
+
   if (name[0] == '.')
     ++name;
 
   if (name[0] == '.')
     ++name;
 
+  address += ANOFFSET (objfile->section_offsets, section);
   prim_record_minimal_symbol_and_info (name, address, ms_type,
                                       secnum_to_section (n_scnum, objfile),
                                       objfile);
   prim_record_minimal_symbol_and_info (name, address, ms_type,
                                       secnum_to_section (n_scnum, objfile),
                                       objfile);
@@ -2339,11 +2347,10 @@ scan_xcoff_symtab (struct objfile *objfile)
                    /* Data variables are recorded in the minimal symbol
                       table, except for section symbols.  */
                    if (*namestring != '.')
                    /* Data variables are recorded in the minimal symbol
                       table, except for section symbols.  */
                    if (*namestring != '.')
-                     prim_record_minimal_symbol_and_info
+                     record_minimal_symbol
                        (namestring, symbol.n_value,
                         sclass == C_HIDEXT ? mst_file_data : mst_data,
                        (namestring, symbol.n_value,
                         sclass == C_HIDEXT ? mst_file_data : mst_data,
-                        secnum_to_section (symbol.n_scnum, objfile),
-                        objfile);
+                        symbol.n_scnum, objfile);
                    break;
 
                  case XMC_TC0:
                    break;
 
                  case XMC_TC0:
@@ -2416,11 +2423,10 @@ scan_xcoff_symtab (struct objfile *objfile)
                       typically be XMC_RW; I suspect XMC_RO and
                       XMC_BS might be possible too.  */
                    if (*namestring != '.')
                       typically be XMC_RW; I suspect XMC_RO and
                       XMC_BS might be possible too.  */
                    if (*namestring != '.')
-                     prim_record_minimal_symbol_and_info
+                     record_minimal_symbol
                        (namestring, symbol.n_value,
                         sclass == C_HIDEXT ? mst_file_data : mst_data,
                        (namestring, symbol.n_value,
                         sclass == C_HIDEXT ? mst_file_data : mst_data,
-                        secnum_to_section (symbol.n_scnum, objfile),
-                        objfile);
+                        symbol.n_scnum, objfile);
                    break;
                  }
                break;
                    break;
                  }
                break;
@@ -2433,11 +2439,10 @@ scan_xcoff_symtab (struct objfile *objfile)
                    /* Common variables are recorded in the minimal symbol
                       table, except for section symbols.  */
                    if (*namestring != '.')
                    /* Common variables are recorded in the minimal symbol
                       table, except for section symbols.  */
                    if (*namestring != '.')
-                     prim_record_minimal_symbol_and_info
+                     record_minimal_symbol
                        (namestring, symbol.n_value,
                         sclass == C_HIDEXT ? mst_file_bss : mst_bss,
                        (namestring, symbol.n_value,
                         sclass == C_HIDEXT ? mst_file_bss : mst_bss,
-                        secnum_to_section (symbol.n_scnum, objfile),
-                        objfile);
+                        symbol.n_scnum, objfile);
                    break;
                  }
                break;
                    break;
                  }
                break;
@@ -3035,44 +3040,38 @@ static void
 xcoff_symfile_offsets (struct objfile *objfile,
                       struct section_addr_info *addrs)
 {
 xcoff_symfile_offsets (struct objfile *objfile,
                       struct section_addr_info *addrs)
 {
-  asection *sect = NULL;
-  int i;
+  const char *first_section_name;
 
 
-  objfile->num_sections = bfd_count_sections (objfile->obfd);
-  objfile->section_offsets = (struct section_offsets *)
-    obstack_alloc (&objfile->objfile_obstack, 
-                  SIZEOF_N_SECTION_OFFSETS (objfile->num_sections));
+  default_symfile_offsets (objfile, addrs);
 
 
-  /* Initialize the section indexes for future use.  */
-  sect = bfd_get_section_by_name (objfile->obfd, ".text");
-  if (sect) 
-    objfile->sect_index_text = sect->index;
+  /* Oneof the weird side-effects of default_symfile_offsets is that
+     it sometimes sets some section indices to zero for sections that,
+     in fact do not exist. See the body of default_symfile_offsets
+     for more info on when that happens. Undo that, as this then allows
+     us to test whether the associated section exists or not, and then
+     access it quickly (without searching it again).  */
 
 
-  sect = bfd_get_section_by_name (objfile->obfd, ".data");
-  if (sect) 
-    objfile->sect_index_data = sect->index;
+  if (objfile->num_sections == 0)
+    return; /* Is that even possible?  Better safe than sorry.  */
 
 
-  sect = bfd_get_section_by_name (objfile->obfd, ".bss");
-  if (sect) 
-    objfile->sect_index_bss = sect->index;
+  first_section_name
+    = bfd_section_name (objfile->obfd, objfile->sections[0].the_bfd_section);
 
 
-  sect = bfd_get_section_by_name (objfile->obfd, ".rodata");
-  if (sect) 
-    objfile->sect_index_rodata = sect->index;
+  if (objfile->sect_index_text == 0
+      && strcmp (first_section_name, ".text") != 0)
+    objfile->sect_index_text = -1;
 
 
-  for (i = 0; i < objfile->num_sections; ++i)
-    {
-      /* syms_from_objfile kindly subtracts from addr the
-        bfd_section_vma of the .text section.  This strikes me as
-        wrong--whether the offset to be applied to symbol reading is
-        relative to the start address of the section depends on the
-        symbol format.  In any event, this whole "addr" concept is
-        pretty broken (it doesn't handle any section but .text
-        sensibly), so just ignore the addr parameter and use 0.
-        rs6000-nat.c will set the correct section offsets via
-        objfile_relocate.  */
-       (objfile->section_offsets)->offsets[i] = 0;
-    }
+  if (objfile->sect_index_data == 0
+      && strcmp (first_section_name, ".data") != 0)
+    objfile->sect_index_data = -1;
+
+  if (objfile->sect_index_bss == 0
+      && strcmp (first_section_name, ".bss") != 0)
+    objfile->sect_index_bss = -1;
+
+  if (objfile->sect_index_rodata == 0
+      && strcmp (first_section_name, ".rodata") != 0)
+    objfile->sect_index_rodata = -1;
 }
 
 /* Register our ability to parse symbols for xcoff BFD files.  */
 }
 
 /* Register our ability to parse symbols for xcoff BFD files.  */
diff --git a/gdb/xcoffsolib.c b/gdb/xcoffsolib.c
deleted file mode 100644 (file)
index 069b016..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/* Shared library support for RS/6000 (xcoff) object files, for GDB.
-   Copyright (C) 1991-2013 Free Software Foundation, Inc.
-   Contributed by IBM Corporation.
-
-   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 <http://www.gnu.org/licenses/>.  */
-
-#include "defs.h"
-#include "bfd.h"
-#include "xcoffsolib.h"
-#include "inferior.h"
-#include "gdbcmd.h"
-#include "symfile.h"
-#include "frame.h"
-#include "gdb_regex.h"
-
-
-/* If ADDR lies in a shared library, return its name.
-   Note that returned name points to static data whose content is overwritten
-   by each call.  */
-
-char *
-xcoff_solib_address (CORE_ADDR addr)
-{
-  static char *buffer = NULL;
-  struct vmap *vp = vmap;
-
-  /* The first vmap entry is for the exec file.  */
-
-  if (vp == NULL)
-    return NULL;
-  for (vp = vp->nxt; vp; vp = vp->nxt)
-    if (vp->tstart <= addr && addr < vp->tend)
-      {
-       xfree (buffer);
-       buffer = xstrprintf ("%s%s%s%s",
-                            vp->name,
-                            *vp->member ? "(" : "",
-                            vp->member,
-                            *vp->member ? ")" : "");
-       return buffer;
-      }
-  return NULL;
-}
-
-static void solib_info (char *, int);
-static void sharedlibrary_command (char *pattern, int from_tty);
-
-static void
-solib_info (char *args, int from_tty)
-{
-  int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
-  struct vmap *vp = vmap;
-
-  /* Check for new shared libraries loaded with load ().  */
-  if (! ptid_equal (inferior_ptid, null_ptid))
-    xcoff_relocate_symtab (PIDGET (inferior_ptid));
-
-  if (vp == NULL || vp->nxt == NULL)
-    {
-      printf_unfiltered ("No shared libraries loaded at this time.\n");
-      return;
-    }
-
-  /* Skip over the first vmap, it is the main program, always loaded.  */
-  vp = vp->nxt;
-
-  printf_unfiltered ("Text Range               Data Range              "
-                    "Syms      Shared Object Library\n");
-
-  for (; vp != NULL; vp = vp->nxt)
-    {
-      printf_unfiltered ("0x%s-0x%s    0x%s-0x%s       %s      %s%s%s%s\n",
-                        phex (vp->tstart, addr_size),
-                        phex (vp->tend, addr_size),
-                        phex (vp->dstart, addr_size),
-                        phex (vp->dend, addr_size),
-                        vp->loaded ? "Yes" : "No ",
-                        vp->name,
-                        *vp->member ? "(" : "",
-                        vp->member,
-                        *vp->member ? ")" : "");
-    }
-}
-
-static void
-sharedlibrary_command (char *pattern, int from_tty)
-{
-  dont_repeat ();
-
-  /* Check for new shared libraries loaded with load ().  */
-  if (! ptid_equal (inferior_ptid, null_ptid))
-    xcoff_relocate_symtab (PIDGET (inferior_ptid));
-
-  if (pattern)
-    {
-      char *re_err = re_comp (pattern);
-
-      if (re_err)
-       error (_("Invalid regexp: %s"), re_err);
-    }
-
-  /* Walk the list of currently loaded shared libraries, and read
-     symbols for any that match the pattern --- or any whose symbols
-     aren't already loaded, if no pattern was given.  */
-  {
-    int any_matches = 0;
-    int loaded_any_symbols = 0;
-    struct vmap *vp = vmap;
-
-    if (!vp)
-      return;
-
-    /* skip over the first vmap, it is the main program, always loaded.  */
-    for (vp = vp->nxt; vp; vp = vp->nxt)
-      if (! pattern
-           || re_exec (vp->name)
-           || (*vp->member && re_exec (vp->member)))
-       {
-         any_matches = 1;
-
-         if (vp->loaded)
-           {
-             if (from_tty)
-               printf_unfiltered ("Symbols already loaded for %s\n",
-                                  vp->name);
-           }
-         else
-           {
-             if (vmap_add_symbols (vp))
-               loaded_any_symbols = 1;
-           }
-       }
-
-    if (from_tty && pattern && ! any_matches)
-      printf_unfiltered
-       ("No loaded shared libraries match the pattern `%s'.\n", pattern);
-
-    if (loaded_any_symbols)
-      {
-       /* Getting new symbols may change our opinion about what is
-          frameless.  */
-       reinit_frame_cache ();
-      }
-  }
-}
-
-void _initialize_xcoffsolib (void);
-
-void
-_initialize_xcoffsolib (void)
-{
-  add_com ("sharedlibrary", class_files, sharedlibrary_command,
-          _("Load shared object library symbols for files matching REGEXP."));
-  add_info ("sharedlibrary", solib_info,
-           _("Status of loaded shared object libraries"));
-
-  add_setshow_boolean_cmd ("auto-solib-add", class_support,
-                          &auto_solib_add, _("\
-Set autoloading of shared library symbols."), _("\
-Show autoloading of shared library symbols."), _("\
-If \"on\", symbols from all shared object libraries will be loaded\n\
-automatically when the inferior begins execution, when the dynamic linker\n\
-informs gdb that a new library has been loaded, or when attaching to the\n\
-inferior.  Otherwise, symbols must be loaded manually, using \
-`sharedlibrary'."),
-                          NULL,
-                          NULL, /* FIXME: i18n: */
-                          &setlist, &showlist);
-}
diff --git a/gdb/xcoffsolib.h b/gdb/xcoffsolib.h
deleted file mode 100644 (file)
index 7dcdb60..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Data structures for RS/6000 shared libraries, for GDB.
-   Copyright (C) 1991-2013 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 <http://www.gnu.org/licenses/>.  */
-
-/* The vmap struct is used to describe the virtual address space of
-   the target we are manipulating.  The first entry is always the "exec"
-   file.  Subsequent entries correspond to other objects that are
-   mapped into the address space of a process created from the "exec" file.
-   These are either in response to exec()ing the file, in which case all
-   shared libraries are loaded, or a "load" system call, followed by the
-   user's issuance of a "load" command.  */
-
-#ifndef XCOFFSOLIB_H
-#define XCOFFSOLIB_H
-
-struct vmap
-  {
-    struct vmap *nxt;          /* ptr to next in chain                 */
-    bfd *bfd;                  /* BFD for mappable object library      */
-    char *name;                        /* ptr to object file name              */
-    char *member;              /* ptr to member name                   */
-    CORE_ADDR tstart;          /* virtual addr where member is mapped  */
-    CORE_ADDR tend;            /* virtual upper bound of member        */
-    CORE_ADDR tvma;            /* virtual addr of text section in
-                                  object file */
-    CORE_ADDR toffs;           /* offset of text section in object file */
-    CORE_ADDR dstart;          /* virtual address of data start        */
-    CORE_ADDR dend;            /* virtual address of data end          */
-    CORE_ADDR dvma;            /* virtual addr of data section in
-                                  object file */
-
-    /* This is NULL for the exec-file.  */
-    struct objfile *objfile;
-
-    unsigned loaded:1;         /* True if symbols are loaded           */
-    unsigned padding:15;
-  };
-
-
-struct vmap_and_bfd
-  {
-    bfd *pbfd;
-    struct vmap *pvmap;
-  };
-
-extern struct vmap *vmap;
-
-/* Add symbols for a vmap.  */
-extern int vmap_add_symbols (struct vmap *vp);
-
-#endif