diff --git a/gdb/corelow.c b/gdb/corelow.c
index 4a489d95706..28d619594d8 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -53,6 +53,7 @@
 #include "cli/cli-cmds.h"
 #include "xml-tdesc.h"
 #include "memtag.h"
+#include "cli/cli-style.h"
 
 #ifndef O_LARGEFILE
 #define O_LARGEFILE 0
@@ -277,6 +278,48 @@ core_target::build_file_mappings ()
   std::unordered_map<std::string, struct bfd *> bfd_map;
   std::unordered_set<std::string> unavailable_paths;
 
+  /* Type holding information about a single file mapped into the inferior
+     at the point when the core file was created.  Associates a build-id
+     with the list of regions the file is mapped into.  */
+  struct mapped_file
+  {
+    /* Type for a region of a file that was mapped into the inferior when
+       the core file was generated.  */
+    struct region
+    {
+      /* Constructor.   See member variables for argument descriptions.  */
+      region (CORE_ADDR start_, CORE_ADDR end_, CORE_ADDR file_ofs_)
+	: start (start_),
+	  end (end_),
+	  file_ofs (file_ofs_)
+      { /* Nothing.  */ }
+
+      /* The inferior address for the start of the mapped region.  */
+      CORE_ADDR start;
+
+      /* The inferior address immediately after the mapped region.  */
+      CORE_ADDR end;
+
+      /* The offset within the mapped file for this content.  */
+      CORE_ADDR file_ofs;
+    };
+
+    /* If not nullptr, then this is the build-id associated with this
+       file.  */
+    const bfd_build_id *build_id = nullptr;
+
+    /* If true then we have seen multiple different build-ids associated
+       with the same filename.  The build_id field will have been set back
+       to nullptr, and we should not set build_id in future.  */
+    bool ignore_build_id_p = false;
+
+    /* All the mapped regions of this file.  */
+    std::vector<region> regions;
+  };
+
+  /* All files mapped into the core file.  The key is the filename.  */
+  std::unordered_map<std::string, mapped_file> mapped_files;
+
   /* See linux_read_core_file_mappings() in linux-tdep.c for an example
      read_core_file_mappings method.  */
   gdbarch_read_core_file_mappings (m_core_gdbarch,
@@ -297,87 +340,172 @@ core_target::build_file_mappings ()
 	   weed out non-file-backed mappings.  */
 	gdb_assert (filename != nullptr);
 
-	if (unavailable_paths.find (filename) != unavailable_paths.end ())
+	/* Add this mapped region to the data for FILENAME.  */
+	mapped_file &file_data = mapped_files[filename];
+	file_data.regions.emplace_back (start, end, file_ofs);
+	if (build_id != nullptr && !file_data.ignore_build_id_p)
 	  {
-	    /* We have already seen some mapping for FILENAME but failed to
-	       find/open the file.  There is no point in trying the same
-	       thing again so just record that the range [start, end) is
-	       unavailable.  */
-	    m_core_unavailable_mappings.emplace_back (start, end - start);
-	    return;
-	  }
-
-	struct bfd *bfd = bfd_map[filename];
-	if (bfd == nullptr)
-	  {
-	    /* Use exec_file_find() to do sysroot expansion.  It'll
-	       also strip the potential sysroot "target:" prefix.  If
-	       there is no sysroot, an equivalent (possibly more
-	       canonical) pathname will be provided.  */
-	    gdb::unique_xmalloc_ptr<char> expanded_fname
-	      = exec_file_find (filename, NULL);
-
-	    if (expanded_fname == nullptr && build_id != nullptr)
-	      debuginfod_exec_query (build_id->data, build_id->size,
-				     filename, &expanded_fname);
-
-	    if (expanded_fname == nullptr)
+	    if (file_data.build_id == nullptr)
+	      file_data.build_id = build_id;
+	    else if (!build_id_equal (build_id, file_data.build_id))
 	      {
-		m_core_unavailable_mappings.emplace_back (start, end - start);
-		unavailable_paths.insert (filename);
-		warning (_("Can't open file %s during file-backed mapping "
-			   "note processing"),
-			 filename);
-		return;
+		warning (_("Multiple build-ids found for %ps"),
+			 styled_string (file_name_style.style (), filename));
+		file_data.build_id = nullptr;
+		file_data.ignore_build_id_p = true;
 	      }
+	  }
+      });
 
-	    bfd = bfd_openr (expanded_fname.get (), "binary");
+  for (const auto &iter : mapped_files)
+    {
+      const std::string &filename = iter.first;
+      const mapped_file &file_data = iter.second;
+
+      /* Use exec_file_find() to do sysroot expansion.  It'll
+	 also strip the potential sysroot "target:" prefix.  If
+	 there is no sysroot, an equivalent (possibly more
+	 canonical) pathname will be provided.  */
+      gdb::unique_xmalloc_ptr<char> expanded_fname
+	= exec_file_find (filename.c_str (), nullptr);
+
+      bool build_id_mismatch = false;
+      if (expanded_fname != nullptr && file_data.build_id != nullptr)
+	{
+	  /* We temporarily open the bfd as a structured target, this
+	     allows us to read the build-id from the bfd if there is one.
+	     For this task it's OK if we reuse an already open bfd object,
+	     so we make this call through GDB's bfd cache.  Once we've
+	     checked the build-id (if there is one) we'll drop this
+	     reference and re-open the bfd using the "binary" target.  */
+	  gdb_bfd_ref_ptr tmp_bfd
+	    = gdb_bfd_open (expanded_fname.get (), gnutarget);
+
+	  if (tmp_bfd != nullptr
+	      && bfd_check_format (tmp_bfd.get (), bfd_object)
+	      && build_id_bfd_get (tmp_bfd.get ()) != nullptr)
+	    {
+	      /* The newly opened TMP_BFD has a build-id, and this mapped
+		 file has a build-id extracted from the core-file.  Check
+		 the build-id's match, and if not, reject TMP_BFD.  */
+	      const struct bfd_build_id *found
+		= build_id_bfd_get (tmp_bfd.get ());
+	      if (!build_id_equal (found, file_data.build_id))
+		build_id_mismatch = true;
+	    }
+	}
 
-	    if (bfd == nullptr || !bfd_check_format (bfd, bfd_object))
-	      {
-		m_core_unavailable_mappings.emplace_back (start, end - start);
-		unavailable_paths.insert (filename);
-		warning (_("Can't open file %s which was expanded to %s "
+      gdb_bfd_ref_ptr abfd;
+      if (expanded_fname != nullptr && !build_id_mismatch)
+	{
+	  struct bfd *b = bfd_openr (expanded_fname.get (), "binary");
+	  abfd = gdb_bfd_ref_ptr::new_reference (b);
+	}
+
+      if ((expanded_fname == nullptr
+	   || abfd == nullptr
+	   || !bfd_check_format (abfd.get (), bfd_object))
+	  && file_data.build_id != nullptr)
+	{
+	  expanded_fname = nullptr;
+	  debuginfod_exec_query (file_data.build_id->data,
+				 file_data.build_id->size,
+				 filename.c_str (), &expanded_fname);
+	  if (expanded_fname != nullptr)
+	    {
+	      struct bfd *b = bfd_openr (expanded_fname.get (), "binary");
+	      abfd = gdb_bfd_ref_ptr::new_reference (b);
+	    }
+	}
+
+      if (expanded_fname == nullptr
+	  || abfd == nullptr
+	  || !bfd_check_format (abfd.get (), bfd_object))
+	{
+	  /* If ABFD was opened, but the wrong format, close it now.  */
+	  abfd = nullptr;
+
+	  /* Record all regions for this file as unavailable.  */
+	  for (const mapped_file::region &region : file_data.regions)
+	    m_core_unavailable_mappings.emplace_back (region.start,
+						      region.end
+						      - region.start);
+
+	  /* And give the user an appropriate warning.  */
+	  if (build_id_mismatch)
+	    {
+	      if (expanded_fname == nullptr
+		  || filename == expanded_fname.get ())
+		warning (_("File %ps doesn't match build-id from core-file "
+			   "during file-backed mapping processing"),
+			 styled_string (file_name_style.style (),
+					filename.c_str ()));
+	      else
+		warning (_("File %ps which was expanded to %ps, doesn't match "
+			   "build-id from core-file during file-backed "
+			   "mapping processing"),
+			 styled_string (file_name_style.style (),
+					filename.c_str ()),
+			 styled_string (file_name_style.style (),
+					expanded_fname.get ()));
+	    }
+	  else
+	    {
+	      if (expanded_fname == nullptr
+		  || filename == expanded_fname.get ())
+		warning (_("Can't open file %ps during file-backed mapping "
+			   "note processing"),
+			 styled_string (file_name_style.style (),
+					filename.c_str ()));
+	      else
+		warning (_("Can't open file %ps which was expanded to %ps "
 			   "during file-backed mapping note processing"),
-			 filename, expanded_fname.get ());
+			 styled_string (file_name_style.style (),
+					filename.c_str ()),
+			 styled_string (file_name_style.style (),
+					expanded_fname.get ()));
+	    }
+	}
+      else
+	{
+	  /* Ensure that the bfd will be closed when core_bfd is closed.
+	     This can be checked before/after a core file detach via "maint
+	     info bfds".  */
+	  gdb_bfd_record_inclusion (current_program_space->core_bfd (),
+				    abfd.get ());
+
+	  /* Create sections for each mapped region.  */
+	  for (const mapped_file::region &region : file_data.regions)
+	    {
+	      /* Make new BFD section.  All sections have the same name,
+		 which is permitted by bfd_make_section_anyway().  */
+	      asection *sec = bfd_make_section_anyway (abfd.get (), "load");
+	      if (sec == nullptr)
+		error (_("Can't make section"));
+	      sec->filepos = region.file_ofs;
+	      bfd_set_section_flags (sec, SEC_READONLY | SEC_HAS_CONTENTS);
+	      bfd_set_section_size (sec, region.end - region.start);
+	      bfd_set_section_vma (sec, region.start);
+	      bfd_set_section_lma (sec, region.start);
+	      bfd_set_section_alignment (sec, 2);
+
+	      /* Set target_section fields.  */
+	      m_core_file_mappings.emplace_back (region.start, region.end, sec);
+	    }
+	}
 
-		if (bfd != nullptr)
-		  bfd_close (bfd);
-		return;
-	      }
-	    /* Ensure that the bfd will be closed when core_bfd is closed. 
-	       This can be checked before/after a core file detach via
-	       "maint info bfds".  */
-	    gdb_bfd_record_inclusion (current_program_space->core_bfd (), bfd);
-	    bfd_map[filename] = bfd;
-	  }
+      /* If this is a bfd of a shared library, record its soname and
+	 build-id.  */
+      if (file_data.build_id != nullptr && abfd != nullptr)
+	{
+	  gdb::unique_xmalloc_ptr<char> soname
+	    = gdb_bfd_read_elf_soname (bfd_get_filename (abfd.get ()));
 
-	/* Make new BFD section.  All sections have the same name,
-	   which is permitted by bfd_make_section_anyway().  */
-	asection *sec = bfd_make_section_anyway (bfd, "load");
-	if (sec == nullptr)
-	  error (_("Can't make section"));
-	sec->filepos = file_ofs;
-	bfd_set_section_flags (sec, SEC_READONLY | SEC_HAS_CONTENTS);
-	bfd_set_section_size (sec, end - start);
-	bfd_set_section_vma (sec, start);
-	bfd_set_section_lma (sec, start);
-	bfd_set_section_alignment (sec, 2);
-
-	/* Set target_section fields.  */
-	m_core_file_mappings.emplace_back (start, end, sec);
-
-	/* If this is a bfd of a shared library, record its soname
-	   and build id.  */
-	if (build_id != nullptr)
-	  {
-	    gdb::unique_xmalloc_ptr<char> soname
-	      = gdb_bfd_read_elf_soname (bfd->filename);
-	    if (soname != nullptr)
-	      set_cbfd_soname_build_id (current_program_space->cbfd,
-					soname.get (), build_id);
-	  }
-      });
+	  if (soname != nullptr)
+	    set_cbfd_soname_build_id (current_program_space->cbfd,
+				      soname.get (), file_data.build_id);
+	}
+    }
 
   normalize_mem_ranges (&m_core_unavailable_mappings);
 }
diff --git a/gdb/testsuite/gdb.debuginfod/corefile-mapped-file-1.c b/gdb/testsuite/gdb.debuginfod/corefile-mapped-file-1.c
new file mode 100644
index 00000000000..dd6b3f105f2
--- /dev/null
+++ b/gdb/testsuite/gdb.debuginfod/corefile-mapped-file-1.c
@@ -0,0 +1,24 @@
+/* Copyright 2024 Free Software Foundation, Inc.
+
+   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/>.  */
+
+/* This is in the shared library.  */
+extern int foo (void);
+
+int
+main (void)
+{
+  int res = foo ();
+  return res;
+}
diff --git a/gdb/testsuite/gdb.debuginfod/corefile-mapped-file-2.c b/gdb/testsuite/gdb.debuginfod/corefile-mapped-file-2.c
new file mode 100644
index 00000000000..ccf35b75ef8
--- /dev/null
+++ b/gdb/testsuite/gdb.debuginfod/corefile-mapped-file-2.c
@@ -0,0 +1,22 @@
+/* Copyright 2024 Free Software Foundation, Inc.
+
+   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/>.  */
+
+volatile int *library_ptr = (int *) POINTER_VALUE;
+
+int
+foo (void)
+{
+  return *library_ptr;
+}
diff --git a/gdb/testsuite/gdb.debuginfod/corefile-mapped-file-3.c b/gdb/testsuite/gdb.debuginfod/corefile-mapped-file-3.c
new file mode 100644
index 00000000000..45d78336930
--- /dev/null
+++ b/gdb/testsuite/gdb.debuginfod/corefile-mapped-file-3.c
@@ -0,0 +1,45 @@
+/* Copyright 2024 Free Software Foundation, Inc.
+
+   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 <assert.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+volatile void* library_base_address = 0;
+volatile int *ptr = 0;
+
+int
+main ()
+{
+  struct stat buf;
+  int res;
+
+  int fd = open (SHLIB_FILENAME, O_RDONLY);
+  assert (fd != -1);
+
+  res = fstat (fd, &buf);
+  assert (res == 0);
+
+  library_base_address
+    = mmap (NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+
+  res = *ptr;	/* Undefined behaviour here.  */
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.debuginfod/corefile-mapped-file.exp b/gdb/testsuite/gdb.debuginfod/corefile-mapped-file.exp
new file mode 100644
index 00000000000..c789be87ba3
--- /dev/null
+++ b/gdb/testsuite/gdb.debuginfod/corefile-mapped-file.exp
@@ -0,0 +1,304 @@
+# Copyright 2024 Free Software Foundation, Inc.
+#
+# 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/>.  */
+
+# This test checks GDB's ability to use build-ids when setting up file backed
+# mappings as part of reading a core-file.
+#
+# A core-file contains a list of the files that were mapped into the process
+# at the time of the core-file creation.  If the file was mapped read-only
+# then the file contents will not be present in the core-file, but instead GDB
+# is expected to open the mapped file and read the contents from there if
+# needed.  And this is what GDB does.
+#
+# GDB (via the BFD library) will also spot if a mapped looks like a valid ELF
+# and contains a build-id, this build-id is passed back to GDB so that GDB can
+# validate the on-disk file it finds matches the file that was mapped when the
+# core-file was created.
+#
+# In addition, if the on-disk file is found to have a non-matching build-id
+# then GDB can use debuginfod to (try) and download a suitable file.
+#
+# This test is about checking that this file backed mapping mechanism works
+# correctly; that GDB will spot when the build-ids fail to match and will
+# refuse to load an incorrect file.  Additionally we check that the correct
+# file can be downloaded from debuginfod.
+#
+# The test is rather contrived though.  Instead of relying on having a shared
+# library mapped at the time of crash we mmap a shared library into the
+# process and then check this mapping within the test.
+#
+# The problem with using a normal shared library load for this test is that
+# the shared library list is processed as part of a separate step when opening
+# the core file.  Right now this separate step doesn't check the build-ids
+# correctly, so GDB will potentially open the wrong shared library file.  The
+# sections of this incorrect shared library are then added to GDB's list of
+# target sections, and are used to satisfy memory reads, which can give the
+# wrong results.
+#
+# This obviously needs fixing, but is a separate problem from the one being
+# tested here, so this test deliberately checks the mapping using a file that
+# is mmaped rather than loaded as a shared library, as such the file is in the
+# core-files list of mapped files, but is not in the shared library list.
+#
+# Despite this test living in the gdb.debuginfod/ directory, only the last
+# part of this test actually uses debuginfod, everything up to that point is
+# pretty generic.
+
+load_lib debuginfod-support.exp
+
+require allow_shlib_tests
+
+standard_testfile -1.c -2.c -3.c
+
+# Compile an executable that loads the shared library as an actual
+# shared library, then use GDB to figure out the offset of the
+# variable 'library_ptr' within the library.
+set library_filename [standard_output_file "libfoo.so"]
+set binfile2 [standard_output_file "library_loader"]
+
+if {[prepare_for_testing_full "build exec which loads the shared library" \
+	 [list $library_filename \
+	      { debug shlib build-id \
+		    additional_flags=-DPOINTER_VALUE=0x12345678 } \
+	      $srcfile2 {}] \
+	 [list $binfile2 [list debug shlib=$library_filename ] \
+	      $srcfile { debug }]] != 0} {
+    return
+}
+
+if {![runto_main]} {
+    return
+}
+
+if { [is_address_zero_readable] } {
+    return
+}
+
+set ptr_address [get_hexadecimal_valueof "&library_ptr" "unknown"]
+
+set ptr_offset "unknown"
+gdb_test_multiple "info proc mappings" "" {
+    -re "^\\s+($hex)\\s+($hex)\\s+$hex\\s+($hex)\[^\r\n\]+$library_filename\r\n" {
+	set low_addr $expect_out(1,string)
+	set high_addr $expect_out(2,string)
+	set file_offset $expect_out(3,string)
+
+	if {[expr $ptr_address >= $low_addr] && [expr $ptr_address < $high_addr]} {
+	    set mapping_offset [expr $ptr_address - $low_addr]
+	    set ptr_offset [format 0x%x [expr $file_offset + $mapping_offset]]
+	}
+
+	exp_continue
+    }
+
+    -re "^$gdb_prompt $" {
+    }
+
+    -re "(^\[^\r\n\]*)\r\n" {
+	set tmp $expect_out(1,string)
+	exp_continue
+    }
+}
+
+gdb_assert { $ptr_offset ne "unknown" } \
+    "found pointer offset"
+
+set ptr_size [get_integer_valueof "sizeof (library_ptr)" "unknown"]
+set ptr_format_char ""
+if { $ptr_size == 2 } {
+    set ptr_format_char "b"
+} elseif { $ptr_size == 4 } {
+    set ptr_format_char "w"
+} elseif { $ptr_size == 8 } {
+    set ptr_format_char "g"
+}
+if { $ptr_format_char eq "" } {
+    untested "could not figure out size of library_ptr variable"
+    return
+}
+
+# Helper proc to read a value from inferior memory.  Reads at address held in
+# global PTR_ADDRESS, and use PTR_FORMAT_CHAR for the size of the read.
+proc read_ptr_value {  } {
+    set value ""
+    gdb_test_multiple "x/1${::ptr_format_char}x ${::ptr_address}" "" {
+	-re -wrap "^${::hex}(?:\\s+<\[^>\]+>)?:\\s+($::hex)" {
+	    set value $expect_out(1,string)
+	}
+	-re -wrap "^${::hex}(?:\\s+<\[^>\]+>)?:\\s+Cannot access memory at address ${::hex}" {
+	    set value "unavailable"
+	}
+    }
+    return $value
+}
+
+set ptr_expected_value [read_ptr_value]
+if { $ptr_expected_value eq "" } {
+    untested "could not find expected value for library_ptr"
+    return
+}
+
+# Now compile a second executable.  This one doesn't load the shared
+# library as an actual shared library, but instead mmaps the library
+# into the executable.
+#
+# Load this executable within GDB and confirm that we can use the
+# offset we calculated previously to view the value of 'library_ptr'.
+set opts [list debug additional_flags=-DSHLIB_FILENAME=\"$library_filename\"]
+if {[prepare_for_testing "prepare second executable" $binfile \
+	 $srcfile3 $opts] != 0} {
+    return
+}
+
+if {![runto_main]} {
+    return
+}
+
+gdb_breakpoint [gdb_get_line_number "Undefined behaviour here" $srcfile3]
+gdb_continue_to_breakpoint "run to breakpoint"
+
+set library_base_address \
+    [get_hexadecimal_valueof "library_base_address" "unknown"]
+set ptr_address [format 0x%x [expr $library_base_address + $ptr_offset]]
+
+set ptr_value [read_ptr_value]
+gdb_assert { $ptr_value == $ptr_expected_value } \
+    "check value of pointer variable"
+
+# Now rerun the second executable outside of GDB.  The executable should crash
+# and generate a corefile.
+set corefile [core_find $binfile]
+if {$corefile eq ""} {
+    untested "could not generate core file"
+    return
+}
+
+# And now restart GDB, load the core-file and check that the library shows as
+# being mapped in, and that we can still read the library_ptr value from
+# memory.
+clean_restart $binfile
+
+gdb_test "core-file $corefile" \
+    [multi_line \
+	 "\\\[\[^\r\n\]+\\\]" \
+	 "Core was generated by \[^\r\n\]+" \
+	 "Program terminated with signal SIGSEGV, Segmentation fault\\." \
+	 "#0  main \\(\\) at \[^\r\n\]+" \
+	 "$decimal\\s+\[^\r\n\]+/\\* Undefined behaviour here\\.  \\*/"] \
+    "load corefile"
+
+set library_base_address [get_hexadecimal_valueof "library_base_address" \
+			      "unknown" "get library_base_address in core-file"]
+set ptr_address [format 0x%x [expr $library_base_address + $ptr_offset]]
+
+set ptr_value [read_ptr_value]
+gdb_assert { $ptr_value == $ptr_expected_value } \
+    "check value of pointer variable from core-file"
+
+# Now move the shared library file away and restart GDB.  This time when we
+# load the core-file we should see a warning that GDB has failed to map in the
+# library file.  An attempt to read the variable from the library file should
+# fail / give a warning.
+set library_backup_filename [standard_output_file "libfoo.so.backup"]
+remote_exec host "mv \"$library_filename\" \"$library_backup_filename\""
+
+clean_restart $binfile
+
+gdb_test "core-file $corefile" \
+    [multi_line \
+	 "warning: Can't open file [string_to_regexp $library_filename] during file-backed mapping note processing" \
+	 "\\\[\[^\r\n\]+\\\]" \
+	 "Core was generated by \[^\r\n\]+" \
+	 "Program terminated with signal SIGSEGV, Segmentation fault\\." \
+	 "#0  main \\(\\) at \[^\r\n\]+" \
+	 "$decimal\\s+\[^\r\n\]+/\\* Undefined behaviour here\\.  \\*/"] \
+    "load corefile with library file missing"
+
+set ptr_value [read_ptr_value]
+gdb_assert { $ptr_value eq "unavailable" } \
+    "check value of pointer is unavailable with library file missing"
+
+# Build a new version of the shared library, keep the library the same size,
+# but change the contents so the build-id changes.  Then restart GDB and load
+# the core-file again.  GDB should spot that the build-id for the shared
+# library is not as expected, and should refuse to map in the shared library.
+if {[build_executable "build second version of shared library" \
+	 $library_filename $srcfile2 \
+	 { debug shlib build-id \
+	       additional_flags=-DPOINTER_VALUE=0x11223344 }] != 0} {
+    return
+}
+
+clean_restart $binfile
+
+gdb_test "core-file $corefile" \
+    [multi_line \
+	 "warning: File [string_to_regexp $library_filename] doesn't match build-id from core-file during file-backed mapping processing" \
+	 "\\\[\[^\r\n\]+\\\]" \
+	 "Core was generated by \[^\r\n\]+" \
+	 "Program terminated with signal SIGSEGV, Segmentation fault\\." \
+	 "#0  main \\(\\) at \[^\r\n\]+" \
+	 "$decimal\\s+\[^\r\n\]+/\\* Undefined behaviour here\\.  \\*/"] \
+    "load corefile with wrong library in place"
+
+set ptr_value [read_ptr_value]
+gdb_assert { $ptr_value eq "unavailable" } \
+    "check value of pointer is unavailable with wrong library in place"
+
+# Setup a debuginfod server which can serve the original shared library file.
+# Then restart GDB and load the core-file.  GDB should download the original
+# shared library from debuginfod and use that to provide the file backed
+# mapping.
+if {![allow_debuginfod_tests]} {
+    untested "skippig debuginfod parts of this test"
+    return
+}
+
+set server_dir [standard_output_file "debuginfod.server"]
+file mkdir $server_dir
+file rename -force $library_backup_filename $server_dir
+
+prepare_for_debuginfod cache db
+
+set url [start_debuginfod $db $server_dir]
+if { $url eq "" } {
+    unresolved "failed to start debuginfod server"
+    return
+}
+
+with_debuginfod_env $cache {
+    setenv DEBUGINFOD_URLS $url
+
+    clean_restart
+    gdb_test_no_output "set debuginfod enabled on" \
+	"enabled debuginfod for initial test"
+    gdb_load $binfile
+
+    gdb_test "core-file $corefile" \
+	[multi_line \
+	     "Downloading\[^\r\n\]* executable for [string_to_regexp $library_filename]\\.\\.\\." \
+	     "\\\[\[^\r\n\]+\\\](?:\r\nDownloading separate debug info for \[^\r\n\]+)*" \
+	     "Core was generated by \[^\r\n\]+" \
+	     "Program terminated with signal SIGSEGV, Segmentation fault\\." \
+	     "#0  main \\(\\) at \[^\r\n\]+" \
+	     "$decimal\\s+\[^\r\n\]+/\\* Undefined behaviour here\\.  \\*/"] \
+	"load corefile, download library from debuginfod"
+
+    set ptr_value [read_ptr_value]
+    gdb_assert { $ptr_value == $ptr_expected_value } \
+	"check value of pointer variable after downloading library file"
+}
+
+stop_debuginfod
