public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Aaron Merey <amerey@redhat.com>
To: gdb-patches@sourceware.org
Subject: [PING*4][RFC PATCH] gdb/debuginfod: Support on-demand downloading of debuginfo
Date: Tue, 3 Jan 2023 16:32:31 -0500	[thread overview]
Message-ID: <CAJDtP-RHi7rmd9=nuU0gqFdxEuRkU0eo4sf1T708LhPNT6EY+Q@mail.gmail.com> (raw)
In-Reply-To: <CAJDtP-TCxr5-rZOYP2oNjNkKSM=2Bmuaa=ovorDQ2+FdD0d9XQ@mail.gmail.com>

Ping

Thanks,
Aaron

On Fri, Nov 18, 2022 at 3:33 PM Aaron Merey <amerey@redhat.com> wrote:
>
> Ping
>
> Thanks,
> Aaron
>
> On Fri, Nov 4, 2022 at 6:34 PM Aaron Merey <amerey@redhat.com> wrote:
> >
> > Ping.  I've tweaked the patch to require the latest version of
> > libdebuginfod which contains the new section query feature used by this
> > patch.
> >
> > Thanks,
> > Aaron
> >
> > ---
> > At the beginning of a session, GDB attempts to download debuginfo for
> > every shared library used by the process being debugged.  One disadvantage
> > of this is that time may be spent downloading debuginfo that ultimately
> > isn't needed during the current session.
> >
> > This patch helps address the issue by adding support for on-demand
> > downloading and reading of debuginfo.  The basic approach it takes is
> > to use debuginfod to download just the .gdb_index of a debuginfo file
> > as soon as the corresponding library is linked.  GDB then relies on the
> > information in the index for as long as possible.  When the index isn't
> > enough then debuginfo is downloaded and read. This helps avoid unnecessary
> > downloads.
> >
> > Although this patch specifically uses .gdb_index, other indexes such
> > as .debug_names could be supported in much the same way.
> >
> > This patch changes the libdebuginfod version requirement from 0.179 to
> > 0.188 in order to support queries for individual ELF sections.
> > libdebuginfod-0.188 is a part of elfutils-0.188 [1].
> >
> > Now I'll describe the implementation in more detail.
> >
> > This patch adds a command 'set debuginfod enabled lazy' which enables
> > on-demand debuginfo downloading/reading.  If this 'lazy' mode is enabled
> > and a solib's debuginfo cannot be found locally, the new function
> > dwarf2_has_separate_index is called in elf_symfile_read. This function
> > queries debuginfod servers for the .gdb_index matching the build-id
> > of the solib.  If it's found, a new objfile is created to hold the .gdb_index
> > information.  The new objfile flag OBJF_INDEX_READLATER is used to indicate
> > that the objfile contains quick_symbols_functions for an index has deferred
> > debuginfo reading.
> >
> > When GDB tries and fails to perform
> > dwarf2_base_index_functions::find_pc_sect_compunit_symtab or
> > dwarf2_gdb_index::expand_symtabs_matching, the new function
> > read_full_dwarf_from_debuginfod downloads the actual debuginfo file and
> > updates the objfile using the new function objfile::reinit. Symtab expansion
> > then proceeds as if the debuginfo was present all along.
> >
> > This patch implements basic on-demand functionality but more work needs
> > to be done to fully take advantage of this feature.  Currently GDB does
> > not attempt to download debuginfo when generating backtraces.  In some
> > situations backtraces may lack information for libraries that we ought
> > to be able to download debuginfo for.  If the user attempts to print a
> > non-existant symbol, GDB will start expanding symtabs one-by-one causing
> > all debuginfo to be downloaded. Some uses of the 'list' command also trigger
> > the downloading of all debuginfo.
> >
> > [1] https://sourceware.org/git/?p=elfutils.git;a=commit;h=e9f3045caa5c4498f371383e5519151942d48b6d
> > ---
> >  binutils/configure       |  20 +--
> >  config/debuginfod.m4     |   2 +-
> >  gdb/configure            |  20 +--
> >  gdb/debuginfod-support.c |  56 +++++++
> >  gdb/debuginfod-support.h |  23 +++
> >  gdb/dwarf2/index-cache.c |  33 +++++
> >  gdb/dwarf2/index-cache.h |  13 ++
> >  gdb/dwarf2/public.h      |   2 +
> >  gdb/dwarf2/read.c        | 308 ++++++++++++++++++++++++++++++++++++---
> >  gdb/dwarf2/section.c     |   4 +-
> >  gdb/elfread.c            |   2 +-
> >  gdb/objfile-flags.h      |   4 +
> >  gdb/objfiles.c           |  16 ++
> >  gdb/objfiles.h           |   5 +
> >  gdb/symfile.c            |  82 +++++++++++
> >  gdb/symfile.h            |   3 +
> >  gdb/symtab.h             |   2 +
> >  17 files changed, 552 insertions(+), 43 deletions(-)
> >
> > diff --git a/binutils/configure b/binutils/configure
> > index 2e33584e548..ea66a71f1f2 100755
> > --- a/binutils/configure
> > +++ b/binutils/configure
> > @@ -11795,19 +11795,19 @@ $as_echo "$with_debuginfod" >&6; }
> >  if test "x$with_debuginfod" != xno; then
> >
> >  pkg_failed=no
> > -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libdebuginfod >= 0.179" >&5
> > -$as_echo_n "checking for libdebuginfod >= 0.179... " >&6; }
> > +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libdebuginfod >= 0.188" >&5
> > +$as_echo_n "checking for libdebuginfod >= 0.188... " >&6; }
> >
> >  if test -n "$DEBUGINFOD_CFLAGS"; then
> >      pkg_cv_DEBUGINFOD_CFLAGS="$DEBUGINFOD_CFLAGS"
> >   elif test -n "$PKG_CONFIG"; then
> >      if test -n "$PKG_CONFIG" && \
> > -    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdebuginfod >= 0.179\""; } >&5
> > -  ($PKG_CONFIG --exists --print-errors "libdebuginfod >= 0.179") 2>&5
> > +    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdebuginfod >= 0.188\""; } >&5
> > +  ($PKG_CONFIG --exists --print-errors "libdebuginfod >= 0.188") 2>&5
> >    ac_status=$?
> >    $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
> >    test $ac_status = 0; }; then
> > -  pkg_cv_DEBUGINFOD_CFLAGS=`$PKG_CONFIG --cflags "libdebuginfod >= 0.179" 2>/dev/null`
> > +  pkg_cv_DEBUGINFOD_CFLAGS=`$PKG_CONFIG --cflags "libdebuginfod >= 0.188" 2>/dev/null`
> >                       test "x$?" != "x0" && pkg_failed=yes
> >  else
> >    pkg_failed=yes
> > @@ -11819,12 +11819,12 @@ if test -n "$DEBUGINFOD_LIBS"; then
> >      pkg_cv_DEBUGINFOD_LIBS="$DEBUGINFOD_LIBS"
> >   elif test -n "$PKG_CONFIG"; then
> >      if test -n "$PKG_CONFIG" && \
> > -    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdebuginfod >= 0.179\""; } >&5
> > -  ($PKG_CONFIG --exists --print-errors "libdebuginfod >= 0.179") 2>&5
> > +    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdebuginfod >= 0.188\""; } >&5
> > +  ($PKG_CONFIG --exists --print-errors "libdebuginfod >= 0.188") 2>&5
> >    ac_status=$?
> >    $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
> >    test $ac_status = 0; }; then
> > -  pkg_cv_DEBUGINFOD_LIBS=`$PKG_CONFIG --libs "libdebuginfod >= 0.179" 2>/dev/null`
> > +  pkg_cv_DEBUGINFOD_LIBS=`$PKG_CONFIG --libs "libdebuginfod >= 0.188" 2>/dev/null`
> >                       test "x$?" != "x0" && pkg_failed=yes
> >  else
> >    pkg_failed=yes
> > @@ -11869,9 +11869,9 @@ else
> >          _pkg_short_errors_supported=no
> >  fi
> >          if test $_pkg_short_errors_supported = yes; then
> > -               DEBUGINFOD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libdebuginfod >= 0.179" 2>&1`
> > +               DEBUGINFOD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libdebuginfod >= 0.188" 2>&1`
> >          else
> > -               DEBUGINFOD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libdebuginfod >= 0.179" 2>&1`
> > +               DEBUGINFOD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libdebuginfod >= 0.188" 2>&1`
> >          fi
> >         # Put the nasty error message in config.log where it belongs
> >         echo "$DEBUGINFOD_PKG_ERRORS" >&5
> > diff --git a/config/debuginfod.m4 b/config/debuginfod.m4
> > index 2c1bfbdb544..d861156a643 100644
> > --- a/config/debuginfod.m4
> > +++ b/config/debuginfod.m4
> > @@ -15,7 +15,7 @@ AC_MSG_CHECKING([whether to use debuginfod])
> >  AC_MSG_RESULT([$with_debuginfod])
> >
> >  if test "x$with_debuginfod" != xno; then
> > -  PKG_CHECK_MODULES([DEBUGINFOD], [libdebuginfod >= 0.179],
> > +  PKG_CHECK_MODULES([DEBUGINFOD], [libdebuginfod >= 0.188],
> >      [AC_DEFINE([HAVE_LIBDEBUGINFOD], [1], [Define to 1 if debuginfod is enabled.])],
> >      [if test "x$with_debuginfod" = xyes; then
> >         AC_MSG_ERROR(["--with-debuginfod was given, but libdebuginfod is missing or unusable."])
> > diff --git a/gdb/configure b/gdb/configure
> > index 33677262783..6548714da2e 100755
> > --- a/gdb/configure
> > +++ b/gdb/configure
> > @@ -7032,19 +7032,19 @@ $as_echo "$with_debuginfod" >&6; }
> >  if test "x$with_debuginfod" != xno; then
> >
> >  pkg_failed=no
> > -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libdebuginfod >= 0.179" >&5
> > -$as_echo_n "checking for libdebuginfod >= 0.179... " >&6; }
> > +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libdebuginfod >= 0.188" >&5
> > +$as_echo_n "checking for libdebuginfod >= 0.188... " >&6; }
> >
> >  if test -n "$DEBUGINFOD_CFLAGS"; then
> >      pkg_cv_DEBUGINFOD_CFLAGS="$DEBUGINFOD_CFLAGS"
> >   elif test -n "$PKG_CONFIG"; then
> >      if test -n "$PKG_CONFIG" && \
> > -    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdebuginfod >= 0.179\""; } >&5
> > -  ($PKG_CONFIG --exists --print-errors "libdebuginfod >= 0.179") 2>&5
> > +    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdebuginfod >= 0.188\""; } >&5
> > +  ($PKG_CONFIG --exists --print-errors "libdebuginfod >= 0.188") 2>&5
> >    ac_status=$?
> >    $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
> >    test $ac_status = 0; }; then
> > -  pkg_cv_DEBUGINFOD_CFLAGS=`$PKG_CONFIG --cflags "libdebuginfod >= 0.179" 2>/dev/null`
> > +  pkg_cv_DEBUGINFOD_CFLAGS=`$PKG_CONFIG --cflags "libdebuginfod >= 0.188" 2>/dev/null`
> >                       test "x$?" != "x0" && pkg_failed=yes
> >  else
> >    pkg_failed=yes
> > @@ -7056,12 +7056,12 @@ if test -n "$DEBUGINFOD_LIBS"; then
> >      pkg_cv_DEBUGINFOD_LIBS="$DEBUGINFOD_LIBS"
> >   elif test -n "$PKG_CONFIG"; then
> >      if test -n "$PKG_CONFIG" && \
> > -    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdebuginfod >= 0.179\""; } >&5
> > -  ($PKG_CONFIG --exists --print-errors "libdebuginfod >= 0.179") 2>&5
> > +    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdebuginfod >= 0.188\""; } >&5
> > +  ($PKG_CONFIG --exists --print-errors "libdebuginfod >= 0.188") 2>&5
> >    ac_status=$?
> >    $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
> >    test $ac_status = 0; }; then
> > -  pkg_cv_DEBUGINFOD_LIBS=`$PKG_CONFIG --libs "libdebuginfod >= 0.179" 2>/dev/null`
> > +  pkg_cv_DEBUGINFOD_LIBS=`$PKG_CONFIG --libs "libdebuginfod >= 0.188" 2>/dev/null`
> >                       test "x$?" != "x0" && pkg_failed=yes
> >  else
> >    pkg_failed=yes
> > @@ -7106,9 +7106,9 @@ else
> >          _pkg_short_errors_supported=no
> >  fi
> >          if test $_pkg_short_errors_supported = yes; then
> > -               DEBUGINFOD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libdebuginfod >= 0.179" 2>&1`
> > +               DEBUGINFOD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libdebuginfod >= 0.188" 2>&1`
> >          else
> > -               DEBUGINFOD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libdebuginfod >= 0.179" 2>&1`
> > +               DEBUGINFOD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libdebuginfod >= 0.188" 2>&1`
> >          fi
> >         # Put the nasty error message in config.log where it belongs
> >         echo "$DEBUGINFOD_PKG_ERRORS" >&5
> > diff --git a/gdb/debuginfod-support.c b/gdb/debuginfod-support.c
> > index 5f04a2b38ca..c2f4d54256c 100644
> > --- a/gdb/debuginfod-support.c
> > +++ b/gdb/debuginfod-support.c
> > @@ -33,12 +33,14 @@ static cmd_list_element *show_debuginfod_prefix_list;
> >  static const char debuginfod_on[] = "on";
> >  static const char debuginfod_off[] = "off";
> >  static const char debuginfod_ask[] = "ask";
> > +static const char debuginfod_lazy[] = "lazy";
> >
> >  static const char *debuginfod_enabled_enum[] =
> >  {
> >    debuginfod_on,
> >    debuginfod_off,
> >    debuginfod_ask,
> > +  debuginfod_lazy,
> >    nullptr
> >  };
> >
> > @@ -79,6 +81,15 @@ debuginfod_exec_query (const unsigned char *build_id,
> >    return scoped_fd (-ENOSYS);
> >  }
> >
> > +scoped_fd
> > +debuginfod_section_query (const unsigned char *build_id,
> > +                         int build_id_len,
> > +                         const char *filename,
> > +                         const char *section_name,
> > +                         gdb::unique_xmalloc_ptr<char> *destname)
> > +{
> > +  return scoped_fd (-ENOSYS);
> > +}
> >  #define NO_IMPL _("Support for debuginfod is not compiled into GDB.")
> >
> >  #else
> > @@ -358,6 +369,51 @@ debuginfod_exec_query (const unsigned char *build_id,
> >
> >    return fd;
> >  }
> > +
> > +/* See debuginfod-support.h  */
> > +
> > +scoped_fd
> > +debuginfod_section_query (const unsigned char *build_id,
> > +                         int build_id_len,
> > +                         const char *filename,
> > +                         const char *section_name,
> > +                         gdb::unique_xmalloc_ptr<char> *destname)
> > +{
> > +  if (debuginfod_enabled != debuginfod_lazy || !debuginfod_is_enabled ())
> > +    return scoped_fd (-ENOSYS);
> > +
> > +  debuginfod_client *c = get_debuginfod_client ();
> > +
> > +  if (c == nullptr)
> > +    return scoped_fd (-ENOMEM);
> > +
> > +  char *dname = nullptr;
> > +  std::string desc = std::string ("section ") + section_name + " for";
> > +  user_data data (desc.c_str (), filename);
> > +
> > +  debuginfod_set_user_data (c, &data);
> > +  gdb::optional<target_terminal::scoped_restore_terminal_state> term_state;
> > +  if (target_supports_terminal_ours ())
> > +    {
> > +      term_state.emplace ();
> > +      target_terminal::ours ();
> > +    }
> > +
> > +  scoped_fd fd (debuginfod_find_section (c, build_id, build_id_len,
> > +                                        section_name, &dname));
> > +  debuginfod_set_user_data (c, nullptr);
> > +
> > +  if (fd.get () < 0 && fd.get () != -ENOENT)
> > +    gdb_printf (_("Download failed: %s. " \
> > +                 "Continuing without section %s for %ps.\n"),
> > +               safe_strerror (-fd.get ()), section_name,
> > +               styled_string (file_name_style.style (),  filename));
> > +
> > +  if (fd.get () >= 0 && destname != nullptr)
> > +    destname->reset (dname);
> > +
> > +  return fd;
> > +}
> >  #endif
> >
> >  /* Set callback for "set debuginfod enabled".  */
> > diff --git a/gdb/debuginfod-support.h b/gdb/debuginfod-support.h
> > index 5b1c1cb91f4..5294b65cac4 100644
> > --- a/gdb/debuginfod-support.h
> > +++ b/gdb/debuginfod-support.h
> > @@ -78,4 +78,27 @@ extern scoped_fd debuginfod_exec_query (const unsigned char *build_id,
> >                                         const char *filename,
> >                                         gdb::unique_xmalloc_ptr<char>
> >                                           *destname);
> > +
> > +/* Query debuginfod servers for the binary contents of a ELF/DWARF section
> > +   from a file matching BUILD_ID.  BUILD_ID can be given as a binary blob
> > +   or a null-terminated string.  If given as a binary blob, BUILD_ID_LEN
> > +   should be the number of bytes.  If given as a null-terminated string,
> > +   BUILD_ID_LEN should be 0.
> > +
> > +   FILENAME should be the name or path associated with the file matching
> > +   BUILD_ID.  It is used for printing messages to the user.
> > +
> > +   SECTION_NAME should be the name of an ELF/DWARF section beginning
> > +   with '.'.
> > +
> > +   If the file is successfully retrieved, its path on the local machine
> > +   is stored in DESTNAME.  If GDB is not built with debuginfod, this
> > +   function returns -ENOSYS.  */
> > +
> > +extern scoped_fd debuginfod_section_query (const unsigned char *build_id,
> > +                                          int build_id_len,
> > +                                          const char *filename,
> > +                                          const char *section_name,
> > +                                          gdb::unique_xmalloc_ptr<char>
> > +                                            *destname);
> >  #endif /* DEBUGINFOD_SUPPORT_H */
> > diff --git a/gdb/dwarf2/index-cache.c b/gdb/dwarf2/index-cache.c
> > index 6de58592050..cc170e8abfe 100644
> > --- a/gdb/dwarf2/index-cache.c
> > +++ b/gdb/dwarf2/index-cache.c
> > @@ -222,6 +222,33 @@ index_cache::lookup_gdb_index (const bfd_build_id *build_id,
> >    return {};
> >  }
> >
> > +/* See dwarf-index-cache.h.  */
> > +
> > +gdb::array_view<const gdb_byte>
> > +index_cache::lookup_gdb_index_debuginfod (const char *index_path,
> > +                                         std::unique_ptr<index_cache_resource> *resource)
> > +{
> > +  try
> > +    {
> > +      /* Try to map that file.  */
> > +      index_cache_resource_mmap *mmap_resource
> > +       = new index_cache_resource_mmap (index_path);
> > +
> > +      /* Hand the resource to the caller.  */
> > +      resource->reset (mmap_resource);
> > +
> > +      return gdb::array_view<const gdb_byte>
> > +         ((const gdb_byte *) mmap_resource->mapping.get (),
> > +          mmap_resource->mapping.size ());
> > +    }
> > +  catch (const gdb_exception_error &except)
> > +    {
> > +      warning (_("Unable to read %s: %s"), index_path, except.what ());
> > +    }
> > +
> > +  return {};
> > +}
> > +
> >  #else /* !HAVE_SYS_MMAN_H */
> >
> >  /* See dwarf-index-cache.h.  This is a no-op on unsupported systems.  */
> > @@ -233,6 +260,12 @@ index_cache::lookup_gdb_index (const bfd_build_id *build_id,
> >    return {};
> >  }
> >
> > +gdb::array_view<const gdb_byte>
> > +index_cache::lookup_gdb_index_debuginfod (const char *index_path,
> > +                                         std::unique_ptr<index_cache_resource> *resource)
> > +{
> > +  return {};
> > +}
> >  #endif
> >
> >  /* See dwarf-index-cache.h.  */
> > diff --git a/gdb/dwarf2/index-cache.h b/gdb/dwarf2/index-cache.h
> > index 6366a9a9360..ecf74684c67 100644
> > --- a/gdb/dwarf2/index-cache.h
> > +++ b/gdb/dwarf2/index-cache.h
> > @@ -65,6 +65,19 @@ class index_cache
> >    lookup_gdb_index (const bfd_build_id *build_id,
> >                     std::unique_ptr<index_cache_resource> *resource);
> >
> > +  /* Look for an index file located at INDEX_PATH in the debuginfod cache.
> > +     Unlike lookup_gdb_index, this function does not exit early if the
> > +     index cache has not been enabled.
> > +
> > +     If found, return the contents as an array_view and store the underlying
> > +     resources (allocated memory, mapped file, etc) in RESOURCE.  The returned
> > +     array_view is valid as long as RESOURCE is not destroyed.
> > +
> > +     If no matching index file is found, return an empty array view.  */
> > +  gdb::array_view<const gdb_byte>
> > +  lookup_gdb_index_debuginfod (const char *index_path,
> > +                              std::unique_ptr<index_cache_resource> *resource);
> > +
> >    /* Return the number of cache hits.  */
> >    unsigned int n_hits () const
> >    { return m_n_hits; }
> > diff --git a/gdb/dwarf2/public.h b/gdb/dwarf2/public.h
> > index a9d4682c856..9971654c62f 100644
> > --- a/gdb/dwarf2/public.h
> > +++ b/gdb/dwarf2/public.h
> > @@ -40,4 +40,6 @@ extern void dwarf2_initialize_objfile (struct objfile *objfile);
> >
> >  extern void dwarf2_build_frame_info (struct objfile *);
> >
> > +extern bool dwarf2_has_separate_index (struct objfile *);
> > +
> >  #endif /* DWARF2_PUBLIC_H */
> > diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
> > index 60e120a9d76..fff4b1eb136 100644
> > --- a/gdb/dwarf2/read.c
> > +++ b/gdb/dwarf2/read.c
> > @@ -93,6 +93,9 @@
> >  #include "split-name.h"
> >  #include "gdbsupport/parallel-for.h"
> >  #include "gdbsupport/thread-pool.h"
> > +#include "symfile.h"
> > +#include "inferior.h"
> > +#include "debuginfod-support.h"
> >
> >  /* When == 1, print basic high level tracing messages.
> >     When > 1, be more verbose.
> > @@ -1846,6 +1849,10 @@ struct dwarf2_base_index_functions : public quick_symbol_functions
> >       CORE_ADDR pc, struct obj_section *section, int warn_if_readin)
> >         override final;
> >
> > +  struct compunit_symtab *_find_pc_sect_compunit_symtab
> > +    (struct objfile *objfile, struct bound_minimal_symbol msymbol,
> > +     CORE_ADDR pc, struct obj_section *section, int warn_if_readin);
> > +
> >    struct compunit_symtab *find_compunit_symtab_by_address
> >      (struct objfile *objfile, CORE_ADDR address) override
> >    {
> > @@ -1911,6 +1918,16 @@ struct dwarf2_gdb_index : public dwarf2_base_index_functions
> >       block_search_flags search_flags,
> >       domain_enum domain,
> >       enum search_domain kind) override;
> > +
> > +  bool _expand_symtabs_matching
> > +    (struct objfile *objfile,
> > +     gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
> > +     const lookup_name_info *lookup_name,
> > +     gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
> > +     gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
> > +     block_search_flags search_flags,
> > +     domain_enum domain,
> > +     enum search_domain kind);
> >  };
> >
> >  struct dwarf2_debug_names_index : public dwarf2_base_index_functions
> > @@ -2677,28 +2694,31 @@ dwarf2_read_gdb_index
> >
> >    /* If there is a .dwz file, read it so we can get its CU list as
> >       well.  */
> > -  dwz = dwarf2_get_dwz_file (per_bfd);
> > -  if (dwz != NULL)
> > +  if (get_gdb_index_contents_dwz != nullptr)
> >      {
> > -      struct mapped_index dwz_map;
> > -      const gdb_byte *dwz_types_ignore;
> > -      offset_type dwz_types_elements_ignore;
> > +      dwz = dwarf2_get_dwz_file (per_bfd);
> > +      if (dwz != NULL)
> > +       {
> > +         struct mapped_index dwz_map;
> > +         const gdb_byte *dwz_types_ignore;
> > +         offset_type dwz_types_elements_ignore;
> >
> > -      gdb::array_view<const gdb_byte> dwz_index_content
> > -       = get_gdb_index_contents_dwz (objfile, dwz);
> > +         gdb::array_view<const gdb_byte> dwz_index_content
> > +           = get_gdb_index_contents_dwz (objfile, dwz);
> >
> > -      if (dwz_index_content.empty ())
> > -       return 0;
> > +         if (dwz_index_content.empty ())
> > +           return 0;
> >
> > -      if (!read_gdb_index_from_buffer (bfd_get_filename (dwz->dwz_bfd.get ()),
> > -                                      1, dwz_index_content, &dwz_map,
> > -                                      &dwz_list, &dwz_list_elements,
> > -                                      &dwz_types_ignore,
> > -                                      &dwz_types_elements_ignore))
> > -       {
> > -         warning (_("could not read '.gdb_index' section from %s; skipping"),
> > -                  bfd_get_filename (dwz->dwz_bfd.get ()));
> > -         return 0;
> > +         if (!read_gdb_index_from_buffer (bfd_get_filename (dwz->dwz_bfd.get ()),
> > +                                          1, dwz_index_content, &dwz_map,
> > +                                          &dwz_list, &dwz_list_elements,
> > +                                          &dwz_types_ignore,
> > +                                          &dwz_types_elements_ignore))
> > +           {
> > +             warning (_("could not read '.gdb_index' section from %s; skipping"),
> > +                      bfd_get_filename (dwz->dwz_bfd.get ()));
> > +             return 0;
> > +           }
> >         }
> >      }
> >
> > @@ -4192,8 +4212,10 @@ dw_expand_symtabs_matching_file_matcher
> >      }
> >  }
> >
> > +static bool read_full_dwarf_from_debuginfod (struct objfile *);
> > +
> >  bool
> > -dwarf2_gdb_index::expand_symtabs_matching
> > +dwarf2_gdb_index::_expand_symtabs_matching
> >      (struct objfile *objfile,
> >       gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
> >       const lookup_name_info *lookup_name,
> > @@ -4242,6 +4264,44 @@ dwarf2_gdb_index::expand_symtabs_matching
> >    return result;
> >  }
> >
> > +bool
> > +dwarf2_gdb_index::expand_symtabs_matching
> > +    (struct objfile *objfile,
> > +     gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
> > +     const lookup_name_info *lookup_name,
> > +     gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
> > +     gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
> > +     block_search_flags search_flags,
> > +     domain_enum domain,
> > +     enum search_domain kind)
> > +{
> > +  if (objfile->flags & OBJF_READNEVER)
> > +    return false;
> > +
> > +  try
> > +    {
> > +      return _expand_symtabs_matching (objfile, file_matcher, lookup_name,
> > +                                      symbol_matcher, expansion_notify,
> > +                                      search_flags, domain, kind);
> > +    }
> > +  catch (gdb_exception e)
> > +    {
> > +      if ((objfile->flags & OBJF_INDEX_READLATER) == 0)
> > +       {
> > +         exception_print (gdb_stderr, e);
> > +         return false;
> > +       }
> > +
> > +      /* Objfile is a stub holding only index information.  Try to reinitialize
> > +        objfile with the full debuginfo.  */
> > +      if (!read_full_dwarf_from_debuginfod (objfile))
> > +         return false;
> > +      return _expand_symtabs_matching (objfile, file_matcher, lookup_name,
> > +                                      symbol_matcher, expansion_notify,
> > +                                      search_flags, domain, kind);
> > +    }
> > +}
> > +
> >  /* A helper for dw2_find_pc_sect_compunit_symtab which finds the most specific
> >     symtab.  */
> >
> > @@ -4281,7 +4341,7 @@ dwarf2_base_index_functions::find_per_cu (dwarf2_per_bfd *per_bfd,
> >  }
> >
> >  struct compunit_symtab *
> > -dwarf2_base_index_functions::find_pc_sect_compunit_symtab
> > +dwarf2_base_index_functions::_find_pc_sect_compunit_symtab
> >       (struct objfile *objfile,
> >        struct bound_minimal_symbol msymbol,
> >        CORE_ADDR pc,
> > @@ -4312,6 +4372,40 @@ dwarf2_base_index_functions::find_pc_sect_compunit_symtab
> >    return result;
> >  }
> >
> > +struct compunit_symtab *
> > +dwarf2_base_index_functions::find_pc_sect_compunit_symtab
> > +     (struct objfile *objfile,
> > +      struct bound_minimal_symbol msymbol,
> > +      CORE_ADDR pc,
> > +      struct obj_section *section,
> > +      int warn_if_readin)
> > +{
> > +  if (objfile->flags & OBJF_READNEVER)
> > +    return nullptr;
> > +
> > +  try
> > +    {
> > +      return _find_pc_sect_compunit_symtab (objfile, msymbol, pc,
> > +                                           section, warn_if_readin);
> > +    }
> > +  catch (gdb_exception e)
> > +    {
> > +      if ((objfile->flags & OBJF_INDEX_READLATER) == 0)
> > +       {
> > +         exception_print (gdb_stderr, e);
> > +         return nullptr;
> > +       }
> > +
> > +      /* Objfile is a stub holding only index information.  Try to reinitialize
> > +        objfile with the full debuginfo.  */
> > +      if (!read_full_dwarf_from_debuginfod (objfile))
> > +       return nullptr;
> > +
> > +      return _find_pc_sect_compunit_symtab (objfile, msymbol, pc,
> > +                                           section, warn_if_readin);
> > +    }
> > +}
> > +
> >  void
> >  dwarf2_base_index_functions::map_symbol_filenames
> >       (struct objfile *objfile,
> > @@ -5417,6 +5511,180 @@ dwarf2_initialize_objfile (struct objfile *objfile)
> >    objfile->qf.push_front (make_cooked_index_funcs ());
> >  }
> >
> > +/* Query debuginfod for the .gdb_index matching OBJFILE's build-id.  Return the
> > +   contents if successful.  */
> > +
> > +static gdb::array_view<const gdb_byte>
> > +get_gdb_index_contents_from_debuginfod (objfile *objfile, dwarf2_per_bfd *per_bfd)
> > +{
> > +  const bfd_build_id *build_id = build_id_bfd_get (objfile->obfd.get ());
> > +  if (build_id == nullptr)
> > +    return {};
> > +
> > +  gdb::unique_xmalloc_ptr<char> index_path;
> > +  scoped_fd fd = debuginfod_section_query (build_id->data, build_id->size,
> > +                                          bfd_get_filename
> > +                                            (objfile->obfd.get ()),
> > +                                          ".gdb_index",
> > +                                          &index_path);
> > +  if (fd.get () < 0)
> > +    return {};
> > +
> > +  return global_index_cache.lookup_gdb_index_debuginfod
> > +    (index_path.get (), &per_bfd->index_cache_res);
> > +}
> > +
> > +/* If OBJFILE is a stub holding only information from a .gdb_index, then attempt
> > +   to download the full debuginfo and reinitialize OBJFILE with it.  */
> > +
> > +static bool
> > +read_full_dwarf_from_debuginfod (struct objfile *objfile)
> > +{
> > +  if ((objfile->flags & OBJF_INDEX_READLATER) == 0)
> > +    return false;
> > +
> > +  const struct bfd_build_id *build_id = build_id_bfd_get (objfile->obfd.get ());
> > +  if (build_id == nullptr)
> > +    return false;
> > +
> > +  const char *filename = bfd_get_filename (objfile->obfd.get ());
> > +  dwarf2_per_bfd *per_bfd;
> > +  dwarf2_per_objfile *per_objfile;
> > +  gdb_bfd_ref_ptr debug_bfd;
> > +  gdb::unique_xmalloc_ptr<char> symfile_path;
> > +
> > +  scoped_fd fd (debuginfod_debuginfo_query (build_id->data,
> > +                                           build_id->size,
> > +                                           filename,
> > +                                           &symfile_path));
> > +
> > +  if (fd.get () < 0)
> > +    goto fail;
> > +
> > +  /* File successfully retrieved from server.  Open as a bfd.  */
> > +  debug_bfd = symfile_bfd_open (symfile_path.get ());
> > +
> > +  if (debug_bfd == nullptr
> > +      || !build_id_verify (debug_bfd.get (), build_id->size, build_id->data))
> > +    {
> > +      warning (_("File \"%s\" from debuginfod cannot be opened as bfd"),
> > +              filename);
> > +      goto fail;
> > +    }
> > +
> > +  /* Fill in objfile's missing information using the debuginfo.  */
> > +  objfile->reinit (debug_bfd.release ());
> > +
> > +  /* Create new per_bfd and per_objfile.  Placeholders based on the
> > +     separate_debug_objfile_backlink were deleted during reinit.  */
> > +  per_bfd = new dwarf2_per_bfd (objfile->obfd.get (), nullptr, false);
> > +  dwarf2_per_bfd_objfile_data_key.set (objfile, per_bfd);
> > +  per_objfile = dwarf2_objfile_data_key.emplace (objfile, objfile, per_bfd);
> > +
> > +  objfile->flags &= ~OBJF_INDEX_READLATER;
> > +
> > +  /* Have to attach the separate index again.  The dwz will be downloaded at
> > +     this point if applicable.  */
> > +  if (dwarf2_read_gdb_index (per_objfile,
> > +                            get_gdb_index_contents_from_debuginfod,
> > +                            get_gdb_index_contents_from_section<dwz_file>))
> > +    {
> > +      dwarf_read_debug_printf ("found gdb index from debuginfod");
> > +      objfile->qf.push_front (per_objfile->per_bfd->index_table->make_quick_functions ());
> > +
> > +      objfile->flags &= ~OBJF_NOT_FILENAME;
> > +      return true;
> > +    }
> > +
> > +fail:
> > +  objfile->flags |= OBJF_READNEVER;
> > +  return false;
> > +}
> > +
> > +/* Query debuginfod for the separate .gdb_index associated with OBJFILE.  If
> > +   successful, create an objfile to hold the .gdb_index information and act
> > +   as a placeholder until the full debuginfo needs to be downloaded.  */
> > +
> > +bool
> > +dwarf2_has_separate_index (struct objfile *objfile)
> > +{
> > +  if (objfile->flags & OBJF_MAINLINE
> > +      || objfile->separate_debug_objfile_backlink != nullptr)
> > +    return 0;
> > +
> > +  if (objfile->flags & OBJF_INDEX_READLATER)
> > +    return 1;
> > +
> > +  gdb::unique_xmalloc_ptr<char> index_path;
> > +  const bfd_build_id *build_id = build_id_bfd_get (objfile->obfd.get ());
> > +
> > +  scoped_fd fd = debuginfod_section_query (build_id->data,
> > +                                          build_id->size,
> > +                                          bfd_get_filename
> > +                                            (objfile->obfd.get ()),
> > +                                          ".gdb_index",
> > +                                          &index_path);
> > +  if (fd.get () >= 0)
> > +    {
> > +      /* We have a separate .gdb_index file so a separate debuginfo file
> > +        should exist.  We just don't want to read it until we really
> > +        have to.  Create an objfile to own the index information and to
> > +        act as a placeholder for the debuginfo that we have the option
> > +        of aquiring later.  */
> > +      gdb_bfd_ref_ptr abfd (gdb_bfd_open (objfile_filename (objfile), gnutarget));
> > +      if (abfd == nullptr)
> > +       return false;
> > +
> > +      dwarf2_per_bfd_objfile_data_key.clear (objfile);
> > +      dwarf2_objfile_data_key.clear (objfile);
> > +
> > +      symbol_file_add_from_index
> > +       (abfd, current_inferior ()->symfile_flags | SYMFILE_NO_READ, objfile);
> > +
> > +      dwarf2_per_bfd *per_bfd;
> > +      dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
> > +
> > +      if (per_objfile == nullptr)
> > +       {
> > +         per_bfd = dwarf2_per_bfd_objfile_data_key.get (objfile);
> > +         if (per_bfd == nullptr)
> > +           {
> > +             per_bfd = new dwarf2_per_bfd (objfile->obfd.get (), nullptr, false);
> > +             dwarf2_per_bfd_objfile_data_key.set (objfile, per_bfd);
> > +           }
> > +         per_objfile = dwarf2_objfile_data_key.emplace (objfile, objfile, per_bfd);
> > +       }
> > +
> > +      struct objfile *stub = objfile->separate_debug_objfile;
> > +      per_objfile = get_dwarf2_per_objfile (stub);
> > +      if (per_objfile == nullptr)
> > +       {
> > +         per_bfd = dwarf2_per_bfd_objfile_data_key.get (stub);
> > +         if (per_bfd == nullptr)
> > +           {
> > +             per_bfd = new dwarf2_per_bfd (stub->obfd.get (), nullptr, false);
> > +             dwarf2_per_bfd_objfile_data_key.set (stub, per_bfd);
> > +           }
> > +         per_objfile = dwarf2_objfile_data_key.emplace (stub, stub, per_bfd);
> > +       }
> > +
> > +      if (dwarf2_read_gdb_index (per_objfile,
> > +                                get_gdb_index_contents_from_debuginfod,
> > +                                nullptr))
> > +       {
> > +         dwarf_read_debug_printf ("found .gdb_index from debuginfod");
> > +         stub->qf.push_front (per_bfd->index_table->make_quick_functions ());
> > +         return 1;
> > +       }
> > +
> > +      /* Unable to use the index.  Delete the stub.  */
> > +      objfile->flags &= ~OBJF_INDEX_READLATER;
> > +      stub->unlink ();
> > +    }
> > +
> > +  return 0;
> > +}
> > +
> >
> >
> >  /* Build a partial symbol table.  */
> > diff --git a/gdb/dwarf2/section.c b/gdb/dwarf2/section.c
> > index 32c86cc5d8d..4156ed2fdcb 100644
> > --- a/gdb/dwarf2/section.c
> > +++ b/gdb/dwarf2/section.c
> > @@ -54,7 +54,9 @@ dwarf2_section_info::get_bfd_owner () const
> >        section = get_containing_section ();
> >        gdb_assert (!section->is_virtual);
> >      }
> > -  gdb_assert (section->s.section != nullptr);
> > +  if (section->s.section == nullptr)
> > +    throw_error (NOT_FOUND_ERROR,
> > +                _("Can't find owner of DWARF2 section."));
> >    return section->s.section->owner;
> >  }
> >
> > diff --git a/gdb/elfread.c b/gdb/elfread.c
> > index 64aeb239670..c229575d1b3 100644
> > --- a/gdb/elfread.c
> > +++ b/gdb/elfread.c
> > @@ -1225,7 +1225,7 @@ elf_symfile_read_dwarf2 (struct objfile *objfile,
> >           symbol_file_add_separate (debug_bfd, debugfile.c_str (),
> >                                     symfile_flags, objfile);
> >         }
> > -      else
> > +      else if (!dwarf2_has_separate_index (objfile))
> >         {
> >           has_dwarf2 = false;
> >           const struct bfd_build_id *build_id
> > diff --git a/gdb/objfile-flags.h b/gdb/objfile-flags.h
> > index b2e07110571..df9bf27d778 100644
> > --- a/gdb/objfile-flags.h
> > +++ b/gdb/objfile-flags.h
> > @@ -68,6 +68,10 @@ enum objfile_flag : unsigned
> >      /* User requested that we do not read this objfile's symbolic
> >         information.  */
> >      OBJF_READNEVER = 1 << 7,
> > +
> > +    /* This objfile only holds information from an index.  It should
> > +       be reinitialized with full debuginfo before expanding symtabs.  */
> > +    OBJF_INDEX_READLATER = 1 << 8,
> >    };
> >
> >  DEF_ENUM_FLAGS_TYPE (enum objfile_flag, objfile_flags);
> > diff --git a/gdb/objfiles.c b/gdb/objfiles.c
> > index 09aba0f80f0..c2c16c97758 100644
> > --- a/gdb/objfiles.c
> > +++ b/gdb/objfiles.c
> > @@ -53,6 +53,7 @@
> >  #include "gdb_bfd.h"
> >  #include "btrace.h"
> >  #include "gdbsupport/pathstuff.h"
> > +#include "symfile.h"
> >
> >  #include <algorithm>
> >  #include <vector>
> > @@ -299,6 +300,16 @@ build_objfile_section_table (struct objfile *objfile)
> >                            objfile, 1);
> >  }
> >
> > +void
> > +objfile::reinit (struct bfd *abfd)
> > +{
> > +  if ((flags & OBJF_INDEX_READLATER) == 0)
> > +    return;
> > +
> > +  this->obfd.reset (abfd);
> > +  deferred_read_symbols (this, 0);
> > +}
> > +
> >  /* Given a pointer to an initialized bfd (ABFD) and some flag bits,
> >     initialize the new objfile as best we can and link it into the list
> >     of all known objfiles.
> > @@ -455,6 +466,11 @@ objfile::make (gdb_bfd_ref_ptr bfd_, const char *name_, objfile_flags flags_,
> >    if (parent != nullptr)
> >      add_separate_debug_objfile (result, parent);
> >
> > +  /* Objfile was initialized using only an index.  Borrow offsets from the
> > +     parent until debuginfo is read.  */
> > +  if (flags_ & OBJF_INDEX_READLATER)
> > +    result->section_offsets = parent->section_offsets;
> > +
> >    current_program_space->add_objfile (std::unique_ptr<objfile> (result),
> >                                       parent);
> >
> > diff --git a/gdb/objfiles.h b/gdb/objfiles.h
> > index 9a152cbc387..971fa7d587d 100644
> > --- a/gdb/objfiles.h
> > +++ b/gdb/objfiles.h
> > @@ -497,6 +497,11 @@ struct objfile
> >    /* See quick_symbol_functions.  */
> >    struct symtab *find_last_source_symtab ();
> >
> > +  /* Reinitialize this objfile using ABFD.  Objfile should have been originally
> > +     initialized using a separate index from ABFD.  Updates this objfile with
> > +     ABFD's symbols and section information.  */
> > +  void reinit (struct bfd *abfd);
> > +
> >    /* See quick_symbol_functions.  */
> >    void forget_cached_source_info ();
> >
> > diff --git a/gdb/symfile.c b/gdb/symfile.c
> > index eb27668f9d3..7edd50d92a2 100644
> > --- a/gdb/symfile.c
> > +++ b/gdb/symfile.c
> > @@ -1074,6 +1074,14 @@ symbol_file_add_with_addrs (const gdb_bfd_ref_ptr &abfd, const char *name,
> >      flags |= OBJF_MAINLINE;
> >    objfile = objfile::make (abfd, name, flags, parent);
> >
> > +  if (objfile->flags & OBJF_INDEX_READLATER)
> > +    {
> > +      /* objfile was initialized only using a separate index so don't
> > +        try to read symbols yet.  */
> > +      gdb::observers::new_objfile.notify (objfile);
> > +      return objfile;
> > +    }
> > +
> >    /* We either created a new mapped symbol table, mapped an existing
> >       symbol table file which has not had initial symbol reading
> >       performed, or need to read an unmapped symbol table.  */
> > @@ -1135,6 +1143,29 @@ symbol_file_add_with_addrs (const gdb_bfd_ref_ptr &abfd, const char *name,
> >    return (objfile);
> >  }
> >
> > +/* We know a separate debuginfo file should exist, but we don't want to
> > +   read it yet.  Infer some of it's properties from the parent objfile.  */
> > +
> > +void
> > +symbol_file_add_from_index (const gdb_bfd_ref_ptr &bfd,
> > +                           symfile_add_flags symfile_flags,
> > +                           struct objfile *parent)
> > +{
> > +  section_addr_info sap = build_section_addr_info_from_objfile (parent);
> > +
> > +  symbol_file_add_with_addrs
> > +    (bfd, "<separate .gdb_index stub>", symfile_flags, &sap,
> > +     (parent->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW
> > +                     | OBJF_USERLOADED | OBJF_MAINLINE | OBJF_PSYMTABS_READ))
> > +                  | OBJF_INDEX_READLATER | OBJF_NOT_FILENAME,
> > +     parent);
> > +
> > +  objfile *result = parent->separate_debug_objfile;
> > +  init_objfile_sect_indices (result);
> > +
> > +  return;
> > +}
> > +
> >  /* Add BFD as a separate debug file for OBJFILE.  For NAME description
> >     see the objfile constructor.  */
> >
> > @@ -2415,6 +2446,57 @@ remove_symbol_file_command (const char *args, int from_tty)
> >    clear_symtab_users (0);
> >  }
> >
> > +/* Read a separate debuginfo OBJFILE that was originally initialized using
> > +   only an index and section information from its parent file.  */
> > +
> > +void
> > +deferred_read_symbols (struct objfile *objfile, int from_tty)
> > +{
> > +  gdb_assert (objfile->flags & OBJF_INDEX_READLATER);
> > +
> > +  /* Nuke all the state that we will re-read.  */
> > +  objfile->registry_fields.clear_registry ();
> > +
> > +  objfile->sections = NULL;
> > +  objfile->sect_index_bss = -1;
> > +  objfile->sect_index_data = -1;
> > +  objfile->sect_index_rodata = -1;
> > +  objfile->sect_index_text = -1;
> > +  objfile->compunit_symtabs = NULL;
> > +  objfile->template_symbols = NULL;
> > +
> > +  {
> > +    gdb_bfd_ref_ptr obfd = objfile->obfd;
> > +    const char *obfd_filename;
> > +
> > +    obfd_filename = bfd_get_filename (objfile->obfd.get ());
> > +    /* Open the new BFD before freeing the old one, so that
> > +       the filename remains live.  */
> > +    gdb_bfd_ref_ptr temp (gdb_bfd_open (obfd_filename, gnutarget));
> > +    objfile->obfd = std::move (temp);
> > +    if (objfile->obfd == NULL)
> > +      error (_("Can't open %s to read symbols."), obfd_filename);
> > +  }
> > +
> > +  std::string original_name = objfile->original_name;
> > +
> > +  /* bfd_openr sets cacheable to true, which is what we want.  */
> > +  if (!bfd_check_format (objfile->obfd.get (), bfd_object))
> > +    error (_("Can't read symbols from %s: %s."), objfile_name (objfile),
> > +          bfd_errmsg (bfd_get_error ()));
> > +
> > +  objfile->original_name
> > +    = obstack_strdup (&objfile->objfile_obstack, original_name);
> > +
> > +  objfile_set_sym_fns (objfile, find_sym_fns (objfile->obfd.get ()));
> > +  build_objfile_section_table (objfile);
> > +  (*objfile->sf->sym_init) (objfile);
> > +  init_objfile_sect_indices (objfile);
> > +
> > +  read_symbols (objfile, 0);
> > +  objfile->mtime = bfd_get_mtime (objfile->obfd.get ());
> > +}
> > +
> >  /* Re-read symbols if a symbol-file has changed.  */
> >
> >  void
> > diff --git a/gdb/symfile.h b/gdb/symfile.h
> > index ffd1acddfdb..9b42ec64aeb 100644
> > --- a/gdb/symfile.h
> > +++ b/gdb/symfile.h
> > @@ -241,6 +241,9 @@ extern struct objfile *symbol_file_add_from_bfd (const gdb_bfd_ref_ptr &,
> >  extern void symbol_file_add_separate (const gdb_bfd_ref_ptr &, const char *,
> >                                       symfile_add_flags, struct objfile *);
> >
> > +extern void symbol_file_add_from_index (const gdb_bfd_ref_ptr &,
> > +                                       symfile_add_flags, struct objfile *);
> > +
> >  extern std::string find_separate_debug_file_by_debuglink (struct objfile *);
> >
> >  /* Build (allocate and populate) a section_addr_info struct from an
> > diff --git a/gdb/symtab.h b/gdb/symtab.h
> > index 4f3e84bbbe9..b5d266ae39b 100644
> > --- a/gdb/symtab.h
> > +++ b/gdb/symtab.h
> > @@ -2206,6 +2206,8 @@ extern bool find_pc_line_pc_range (CORE_ADDR, CORE_ADDR *, CORE_ADDR *);
> >
> >  extern void reread_symbols (int from_tty);
> >
> > +extern void deferred_read_symbols (struct objfile *, int from_tty);
> > +
> >  /* Look up a type named NAME in STRUCT_DOMAIN in the current language.
> >     The type returned must not be opaque -- i.e., must have at least one field
> >     defined.  */
> > --
> > 2.37.3
> >


  reply	other threads:[~2023-01-03 21:32 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-06  2:24 [RFC][PATCH] " Aaron Merey
2022-10-21 16:44 ` [PING][RFC PATCH] " Aaron Merey
2022-11-04 22:34   ` [PATCH] " Aaron Merey
2022-11-18 20:33     ` [PING*3][RFC PATCH] " Aaron Merey
2023-01-03 21:32       ` Aaron Merey [this message]
2023-01-11 21:25 ` [RFC][PATCH] " Tom Tromey
2023-01-13  0:49   ` Aaron Merey
2023-01-13  3:53     ` Tom Tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAJDtP-RHi7rmd9=nuU0gqFdxEuRkU0eo4sf1T708LhPNT6EY+Q@mail.gmail.com' \
    --to=amerey@redhat.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).