From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id ScQeETkpsGlrviEAWB0awg (envelope-from ) for ; Tue, 10 Mar 2026 10:22:49 -0400 Authentication-Results: simark.ca; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha256 header.s=default header.b=P+n6+sQN; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 3F7AC1E0DD; Tue, 10 Mar 2026 10:22:49 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_VALIDITY_CERTIFIED_BLOCKED, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 603781E08D for ; Tue, 10 Mar 2026 10:22:47 -0400 (EDT) Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id DDFBB4BA2E0B for ; Tue, 10 Mar 2026 14:22:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DDFBB4BA2E0B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1773152566; bh=XNmjFOB9b83N0oTL+B/o8x4P/xrNu28SR3yAOZS1e3U=; h=To:Cc:Subject:In-Reply-To:References:Date:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=P+n6+sQNZznXo3CqlZTV35gcK9utyyzqOq4FlmXwPo1EIxINVgCpGY1lDUPU4+QI1 eebH+ow8ND65epHsfN0JjBs0HW+iLuZ13GOseuvlSciyGpNbo1F8PMKnOvZ8dFQKNE Leb7hJDyt0N6EBXYQ7yFUEvvD5ZaA1rmMCux4srI= Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id AB7F14BA23D0 for ; Tue, 10 Mar 2026 14:20:24 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AB7F14BA23D0 ARC-Filter: OpenARC Filter v1.0.0 sourceware.org AB7F14BA23D0 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1773152424; cv=none; b=xdFCHQxi73vk+51fcBbpjHybzstPe/vz2enKRTMFXfTNvFkaa0qeAmj2hG0E2ZVDerFdWXVYNX858lSh9A2DjHHNULX4HSaqEc58Rxxx3rMIPL+2U1SuEx26HYBVn9EptuHKUnuCMLAx291jZxxkDAywS6aMpSjW4cCR4wo7anU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1773152424; c=relaxed/simple; bh=h9lZ5/ssYKN1/VklDOvgaCJqdWz4T3M+0N9XYtFf+hQ=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=X0BCk7BTaxUpkOJPjeA/1L21l/kivRKk4pKiGKLNdFZ29yFx5Dp739I4PvT8s5vTJvGhL9M9myIJv6gb4bEL3ohnurVIyy8Ymat+O17Y9pEzWR52TNhjAccTplIUXOE0CFttfUgYhHNIeo2PgcrcQl6j/k/P5q7yv/gSO7P7Uvc= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AB7F14BA23D0 Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-660-G56HOKP6PbuPGkHrNLQENQ-1; Tue, 10 Mar 2026 10:20:21 -0400 X-MC-Unique: G56HOKP6PbuPGkHrNLQENQ-1 X-Mimecast-MFC-AGG-ID: G56HOKP6PbuPGkHrNLQENQ_1773152420 Received: by mail-wm1-f71.google.com with SMTP id 5b1f17b1804b1-4853b474594so13050945e9.1 for ; Tue, 10 Mar 2026 07:20:21 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773152420; x=1773757220; h=content-transfer-encoding:mime-version:message-id:date:references :in-reply-to:subject:cc:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=0cS4GRT3KDv/+Qa8lw8A5CuF795pnEmUV8MWbwalMow=; b=lDrpfmx4sYyihRofqPwDT0Y2s/4gzSvVbNgruWlJM18LnKBmSLO7qSzAM9i2vPZyWx a1/GTA7EtFP1hArRTQJcNpRKYm17wyh4l8OeTuBptm6ObjGM6cHX6zFueQkIbaX9yHPE 4SpHzrklBMhUDxJ7BWmimzyC43eGIpbgi1wfI0roEitW4Ib+FzRaHorxmsrjfthrJZFc LWj20Sy89nvrTPsVPVjG+vw3fcgZgyWf5JhXjInl4DAZzs9+/ys6B0jjvqBzWEAtAP7N kXSOIM3uJu7W1wPfRaQjBVde8A53rbHchuvr5GM64QisZRTmhbp8AAxEkAK5bpZxoB2I 2gkg== X-Gm-Message-State: AOJu0Yyiq2gmpJwnG17vK/02GXu23S40/yi7ez/rfcvKmjU+J/bc4/jm eRitPI574YBCFm51/MLAuPDIbMkXqqEeOBG8hFzAlb6VsTWyijJSIBdbtgb+qJTsdj14UtNa+MT YGnLkBcMjm65TV6Dbe6AlV6BSuTbr4hm2NrfZd3pJ1n4Y9xssk5aY0xm7apJo X-Gm-Gg: ATEYQzxA2Fr+6UKMafHcvxFO5YtecxfbUQZe7ahOwlXgiEr4IpGSSRFMI4BTnUla4+H 0B5WI5AEVrPwjcLJxOE4xLStO4ULhgQoVuNj081651ZEEwXfhe24mFy31rcaHFnITKe3+TzhaoL YsTIkuB5uycLpwwd/+0s6CXwrXI2maV7wlafdRU/HFtIm4EUb3SGeL4f5opazpNRR6Khxx+BgHV 9YPkDW0VJ35ikldLO3wlx2XsAkA6N673hgKPaGkCMEA2vDnovPHR2bNsjo5zWLTbaSW2BXfo/Ja yIyGbtKM4rYAVMF5AqLtqFlAZwGfPLXqwAPjt5FopTC+42gu6rj38f+I4drTm3Z77SeScNf9pyX /MgSKS0RWCLDS1OyM X-Received: by 2002:a05:600d:6450:10b0:485:3f58:da2 with SMTP id 5b1f17b1804b1-48541a28f73mr43254005e9.16.1773152419708; Tue, 10 Mar 2026 07:20:19 -0700 (PDT) X-Received: by 2002:a05:600d:6450:10b0:485:3f58:da2 with SMTP id 5b1f17b1804b1-48541a28f73mr43253365e9.16.1773152418881; Tue, 10 Mar 2026 07:20:18 -0700 (PDT) Received: from localhost ([31.111.84.232]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48541b7f406sm74745485e9.13.2026.03.10.07.20.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Mar 2026 07:20:18 -0700 (PDT) To: psmith@gnu.org Cc: gdb@sourceware.org Subject: Re: Does gdb debuginfod download libc etc.? In-Reply-To: References: <86wlzmfyep.fsf@aarsen.me> <4844fe241f5524951dc68a6ce05e450897342034.camel@gnu.org> <8c514818-14bd-462d-8aed-0c323327acae@simark.ca> <7949b3d7727ab11f6bc3c833fae81f485c345c47.camel@gnu.org> <87ldg16ivz.fsf@redhat.com> <421fe2ad615c4af1443ddbd3955ee65cb7feb9ee.camel@gnu.org> Date: Tue, 10 Mar 2026 14:20:17 +0000 Message-ID: <878qbz936m.fsf@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: C8Zxx_x37RYbnyY_Qw-8kIwQKG4n0X4rSa9L4tooWMs_1773152420 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-BeenThere: gdb@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Andrew Burgess via Gdb Reply-To: Andrew Burgess Errors-To: gdb-bounces~public-inbox=simark.ca@sourceware.org Sender: "Gdb" Paul Smith writes: > On Mon, 2026-03-09 at 16:32 -0400, Paul Smith via Gdb wrote: >> Ah, this is very useful.=C2=A0 Unfortunately it leads me to this >> discovery; >> the only output I get from this is: >>=20 >> (gdb) core-file /data/psh13/tmp/core >> [core-load] build_file_mappings: enter >> [core-load] build_file_mappings: exit > > More debugging shows that linux_read_core_file_mappings() is returning > early due to this: > > /* It's not required that the NT_FILE note exists, so return silently > if it's not found. Beyond this point though, we'll complain > if problems are found. */ > asection *section =3D bfd_get_section_by_name (cbfd, ".note.linuxcore.= file"); > if (section =3D=3D nullptr) > return; > > (Most of) my core files are generated by the Google coredumper library, > not by the Linux kernel, and I guess they don't have this note section. > > It appears that this note section isn't actually required in order for > us to access the build ID values (after all, elfutils does it), but > this function gives up if the section doesn't exist. > > I can look into how to force my cores to have this section, but I'd > really like to teach GDB how to handle core files without it, since I > have a lot of them and will likely continue to get them for some time > even if I do manage to make this change to new releases. Attached below is a **VERY** rough patch which might get things going for you. This patch applies on gdb-17-branch and includes the previous changes I sent, so you should probably revert them and then try this patch to avoid conflicts. Just to be clear what this is: this is a proof of concept. A very, very, rough first cut. It has had minimal testing (just core file related tests from the testsuite), and I've given no real though to structure, performance, or improving the naming of functions or variables as things have changed. With that said, what's actually happening here? GDB uses the same technique as elfutils (thanks for the info Mark) for finding the build-ids; for every LOAD segment we treat this as if it were the start of an ELF, and try to find the build-id. For those LOAD segments that actually represent the start of an ELF, this will work. As you spotted, GDB only does this if the NT_FILE note exists, that's because we link the filename to the build-id. And historically, the only way we could lookup the build-id for a shared library was via the filename, so storing information about mappings without filenames was pointless. However, I recently reworked a lot of the code in this area, and (I think) improved things. One case that interested me was shared libraries with alternative names via symlinks. The filename stored in the NT_FILE is the absolute filename, while the shared library name will usually be the symlink name (if that's how the library was loaded). This meant that GDB couldn't just match the shared library name to the NT_FILE filename. Now GDB used to try and work around this by also matching via the libraries SONAME attribute. But when I was working on this I ran into libraries that didn't have the SONAME attribute, and so GDB would fail to figure out the build-id for the shared library. So in addition to keeping the previous lookup, I also added an address to build-id map. Now, when libraries try to find the required build-id, not only do we try the filename lookup, but we can also take an address which we know is within the library, and look to see if we have a build-id for that address, this filled the gap for libraries without a SONAME attribute. But, what remained is that all of the lookup data structures, the filename to build-id, the soname to build-id, and the address to build-id maps, are only created for mappings which are covered by NT_FILE. And that brings us to this patch. In the linux-tdep code, after processing the NT_FILE (or if it's missing), I walk the segment table looking for LOAD segments. If there was no NT_FILE entry for the same address then I create an anonymous mapping. This mapping is passed back to corelow.c. In corelow.c the anonymous mapping is used to add additional entries into the address to build-id mapping table. Now, when we try to load a shared library, we try the filename based lookups as before, but don't find anything. Then we try the address to build-id lookup and now we find a match. Anyway. Feel free to give this a go and let me know if it does what you need. If this resolves the problems you're having then I'll clean this code up and submit it for inclusion. Thanks, Andrew --- diff --git i/gdb/corelow.c w/gdb/corelow.c index 29eafe8bdfd..d9c19315adf 100644 --- i/gdb/corelow.c +++ w/gdb/corelow.c @@ -58,6 +58,29 @@ #define O_LARGEFILE 0 #endif =20 +/* When true emit 'core-load' debug messages. */ + +static bool debug_core_load =3D false; + +/* Handle 'show debug core-load' command. */ + +static void +show_core_load_debug (struct ui_file *file, int from_tty, +=09=09 struct cmd_list_element *c, const char *value) +{ + gdb_printf (file, _("Core-load debugging is %s.\n"), value); +} + +/* Print a "core-load" debug statement. */ + +#define core_load_debug_printf(fmt, ...) \ + debug_prefixed_printf_cond (debug_core_load, "core-load", fmt, ##__VA_AR= GS__) + +/* Print "core-load" enter/exit debug statements. */ + +#define CORE_LOAD_SCOPED_DEBUG_ENTER_EXIT \ + scoped_debug_enter_exit (debug_core_load, "core-load") + /* Forward declarations. */ =20 static void core_target_open (const char *arg, int from_tty); @@ -365,6 +388,8 @@ core_target::core_target () void core_target::build_file_mappings () { + CORE_LOAD_SCOPED_DEBUG_ENTER_EXIT; + /* 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. */ @@ -410,6 +435,8 @@ core_target::build_file_mappings () /* All files mapped into the core file. The key is the filename. */ gdb::unordered_map mapped_files; =20 + std::vector mapped_anon_regions; + /* 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, @@ -426,25 +453,39 @@ core_target::build_file_mappings () [&] (int num, ULONGEST start, ULONGEST end, ULONGEST file_ofs, =09 const char *filename, const bfd_build_id *build_id) { -=09/* Architecture-specific read_core_mapping methods are expected to -=09 weed out non-file-backed mappings. */ -=09gdb_assert (filename !=3D nullptr); =20 -=09/* Add this mapped region to the data for FILENAME. */ -=09mapped_file &file_data =3D mapped_files[filename]; -=09file_data.regions.emplace_back (start, end, file_ofs); -=09if (build_id !=3D nullptr && !file_data.ignore_build_id_p) +=09core_load_debug_printf ("start =3D 0x%s, end =3D 0x%s, filename =3D %s,= build-id =3D %s", +=09=09=09=09phex_nz (start), phex_nz (end), +=09=09=09=09(filename =3D=3D nullptr ? "NONE" : filename), +=09=09=09=09(build_id =3D=3D nullptr +=09=09=09=09 ? "NONE" +=09=09=09=09 : build_id_to_string (build_id).c_str ())); + +=09if (filename !=3D nullptr) =09 { -=09 if (file_data.build_id =3D=3D nullptr) -=09 file_data.build_id =3D build_id; -=09 else if (!build_id_equal (build_id, file_data.build_id)) +=09 /* Add this mapped region to the data for FILENAME. */ +=09 mapped_file &file_data =3D mapped_files[filename]; +=09 file_data.regions.emplace_back (start, end, file_ofs); +=09 if (build_id !=3D nullptr && !file_data.ignore_build_id_p) =09 { -=09=09warning (_("Multiple build-ids found for %ps"), -=09=09=09 styled_string (file_name_style.style (), filename)); -=09=09file_data.build_id =3D nullptr; -=09=09file_data.ignore_build_id_p =3D true; +=09=09if (file_data.build_id =3D=3D nullptr) +=09=09 file_data.build_id =3D build_id; +=09=09else if (!build_id_equal (build_id, file_data.build_id)) +=09=09 { +=09=09 warning (_("Multiple build-ids found for %ps"), +=09=09=09 styled_string (file_name_style.style (), filename)); +=09=09 file_data.build_id =3D nullptr; +=09=09 file_data.ignore_build_id_p =3D true; +=09=09 } =09 } =09 } +=09else if (build_id !=3D nullptr) +=09 { +=09 mapped_file data =3D { .build_id =3D build_id }; +=09 gdb_assert (file_ofs =3D=3D 0); +=09 data.regions.emplace_back (start, end, file_ofs); +=09 mapped_anon_regions.push_back (std::move (data)); +=09 } }); =20 /* Get the build-id of the core file. */ @@ -453,6 +494,8 @@ core_target::build_file_mappings () =20 for (const auto &[filename, file_data] : mapped_files) { + core_load_debug_printf ("checking mapped file: %s", filename.c_str (= )); + /* If this mapped file has the same build-id as was discovered for =09 the core-file itself, then we assume this is the main =09 executable. Record the filename as we can use this later. */ @@ -468,6 +511,11 @@ core_target::build_file_mappings () gdb::unique_xmalloc_ptr expanded_fname =09=3D exec_file_find (filename.c_str (), nullptr); =20 + core_load_debug_printf ("expanded filename: %s", +=09=09=09 (expanded_fname.get () =3D=3D nullptr +=09=09=09 ? "NONE" +=09=09=09 : expanded_fname.get ())); + bool build_id_mismatch =3D false; if (expanded_fname !=3D nullptr && file_data.build_id !=3D nullptr) =09{ @@ -491,6 +539,11 @@ core_target::build_file_mappings () =09=09=3D build_id_bfd_get (tmp_bfd.get ()); =09 if (!build_id_equal (found, file_data.build_id)) =09=09build_id_mismatch =3D true; + +=09 core_load_debug_printf ("for expanded filename, build-id is %s%s"= , +=09=09=09=09 build_id_to_string (found).c_str (), +=09=09=09=09 (build_id_mismatch +=09=09=09=09 ? "\t[mismatched]" : "")); =09 } =09} =20 @@ -522,6 +575,8 @@ core_target::build_file_mappings () =09 struct bfd *b =3D bfd_openr (expanded_fname.get (), "binary"); =09 gdb_assert (b !=3D nullptr); =09 abfd =3D gdb_bfd_ref_ptr::new_reference (b); +=09 core_load_debug_printf +=09=09("found a suitable objfile based on build-id"); =09 } =09} =20 @@ -533,6 +588,8 @@ core_target::build_file_mappings () =09 || abfd =3D=3D nullptr =09 || !bfd_check_format (abfd.get (), bfd_object)) =09{ +=09 core_load_debug_printf ("failed to find a suitable objfile"); + =09 /* If ABFD was opened, but the wrong format, close it now. */ =09 abfd =3D nullptr; =20 @@ -652,12 +709,40 @@ core_target::build_file_mappings () =09 soname =3D gdb_bfd_read_elf_soname (actual_filename); =09 } =20 +=09 core_load_debug_printf ("recording file for soname lookup"); +=09 core_load_debug_printf (" soname =3D %s", +=09=09=09=09 (soname.get () =3D=3D nullptr +=09=09=09=09 ? "NONE" : soname.get ())); +=09 core_load_debug_printf (" actual filename =3D %s", +=09=09=09=09 (actual_filename =3D=3D nullptr +=09=09=09=09 ? "NONE" : actual_filename)); + =09 m_mapped_file_info.add (soname.get (), filename.c_str (), =09=09=09=09 actual_filename, std::move (ranges), =09=09=09=09 file_data.build_id); =09} } =20 + for (auto &r : mapped_anon_regions) + { + std::vector ranges; + for (const mapped_file::region ®ion : r.regions) +=09ranges.emplace_back (region.start, region.end - region.start); + + normalize_mem_ranges (&ranges); + + gdb_assert (r.build_id !=3D nullptr); + + core_load_debug_printf ("recording anon region for build-id %s", +=09=09=09 build_id_to_string (r.build_id).c_str ()); + + m_mapped_file_info.add (nullptr, nullptr, nullptr, std::move (ranges= ), +=09=09=09 r.build_id); + } + + core_load_debug_printf ("expected executable name: %s", +=09=09=09 m_expected_exec_filename.c_str ()); + normalize_mem_ranges (&m_core_unavailable_mappings); } =20 @@ -2026,7 +2111,6 @@ mapped_file_info::add (const char *soname, =09=09 const bfd_build_id *build_id) { gdb_assert (build_id !=3D nullptr); - gdb_assert (expected_filename !=3D nullptr); =20 if (soname !=3D nullptr) { @@ -2050,9 +2134,13 @@ mapped_file_info::add (const char *soname, parsed, we group the build-id information based on the file name. As a consequence, we should see each EXPECTED_FILENAME value exactly once. This means that each insertion should always succeed. */ - const auto inserted - =3D m_filename_to_build_id_map.emplace (expected_filename, build_id).s= econd; - gdb_assert (inserted); + if (expected_filename !=3D nullptr) + { + const auto inserted +=09=3D m_filename_to_build_id_map.emplace (expected_filename, +=09=09=09=09=09 build_id).second; + gdb_assert (inserted); + } =20 /* Setup the reverse build-id to file name map. */ if (actual_filename !=3D nullptr) @@ -2164,7 +2252,16 @@ core_target_find_mapped_file (const char *filename, if (targ =3D=3D nullptr || current_program_space->cbfd.get () =3D=3D nul= lptr) return {}; =20 - return targ->lookup_mapped_file_info (filename, addr); + std::optional result + =3D targ->lookup_mapped_file_info (filename, addr); + + core_load_debug_printf ("filename =3D %s, addr =3D %s%s", +=09=09=09 (filename =3D=3D nullptr ? "NONE" : filename), +=09=09=09 (addr.has_value () +=09=09=09 ? core_addr_to_string_nz (addr.value ()) : "NONE"), +=09=09=09 (result.has_value () ? "\t[found]" : "")); + + return result; } =20 INIT_GDB_FILE (corelow) @@ -2175,4 +2272,13 @@ INIT_GDB_FILE (corelow) =09 maintenance_print_core_file_backed_mappings, =09 _("Print core file's file-backed mappings."), =09 &maintenanceprintlist); + + /* Debug this files internals. */ + add_setshow_boolean_cmd ("core-load", class_maintenance, &debug_core_loa= d, _("\ +Set core-load debugging."), _("\ +Show core-load debugging."), _("\ +When on, core-load specific internal debugging is enabled."), +=09=09=09 NULL, +=09=09=09 show_core_load_debug, +=09=09=09 &setdebuglist, &showdebuglist); } diff --git i/gdb/linux-tdep.c w/gdb/linux-tdep.c index f07f9879614..27443f7fb4b 100644 --- i/gdb/linux-tdep.c +++ w/gdb/linux-tdep.c @@ -1136,70 +1136,7 @@ linux_read_core_file_mappings /* Ensure that ULONGEST is big enough for reading 64-bit core files. */ static_assert (sizeof (ULONGEST) >=3D 8); =20 - /* It's not required that the NT_FILE note exists, so return silently - if it's not found. Beyond this point though, we'll complain - if problems are found. */ - asection *section =3D bfd_get_section_by_name (cbfd, ".note.linuxcore.fi= le"); - if (section =3D=3D nullptr) - return; - - unsigned int addr_size_bits =3D gdbarch_addr_bit (gdbarch); - unsigned int addr_size =3D addr_size_bits / 8; - size_t note_size =3D bfd_section_size (section); - - if (note_size < 2 * addr_size) - { - warning (_("malformed core note - too short for header")); - return; - } - - gdb::byte_vector contents (note_size); - if (!bfd_get_section_contents (cbfd, section, contents.data (), 0, -=09=09=09=09 note_size)) - { - warning (_("could not get core note contents")); - return; - } - - gdb_byte *descdata =3D contents.data (); - char *descend =3D (char *) descdata + note_size; - - if (descdata[note_size - 1] !=3D '\0') - { - warning (_("malformed note - does not end with \\0")); - return; - } - - ULONGEST count =3D bfd_get (addr_size_bits, cbfd, descdata); - descdata +=3D addr_size; - - ULONGEST page_size =3D bfd_get (addr_size_bits, cbfd, descdata); - descdata +=3D addr_size; - - if (note_size < 2 * addr_size + count * 3 * addr_size) - { - warning (_("malformed note - too short for supplied file count")); - return; - } - - char *filenames =3D (char *) descdata + count * 3 * addr_size; - - /* Make sure that the correct number of filenames exist. Complain - if there aren't enough or are too many. */ - char *f =3D filenames; - for (int i =3D 0; i < count; i++) - { - if (f >=3D descend) -=09{ -=09 warning (_("malformed note - filename area is too small")); -=09 return; -=09} - f +=3D strnlen (f, descend - f) + 1; - } - /* Complain, but don't return early if the filename area is too big. */ - if (f !=3D descend) - warning (_("malformed note - filename area is too big")); - + /* Get build-id from every loadable section that can provide one. */ const bfd_build_id *orig_build_id =3D cbfd->build_id; gdb::unordered_map vma_map; =20 @@ -1216,26 +1153,145 @@ linux_read_core_file_mappings } =20 cbfd->build_id =3D orig_build_id; - pre_loop_cb (count); =20 - for (int i =3D 0; i < count; i++) + /* Vector to collect proc mappings. */ + struct proc_mapping + { + int num; + ULONGEST start; + ULONGEST end; + ULONGEST file_ofs; + const char *filename; + const bfd_build_id *build_id; + }; + std::vector proc_mappings; + + /* The start address of each mapping. */ + gdb::unordered_set mapping_start_addr_set; + + /* It's not required that the NT_FILE note exists, so return silently + if it's not found. Beyond this point though, we'll complain + if problems are found. */ + asection *section =3D bfd_get_section_by_name (cbfd, ".note.linuxcore.fi= le"); + if (section !=3D nullptr) { - ULONGEST start =3D bfd_get (addr_size_bits, cbfd, descdata); - descdata +=3D addr_size; - ULONGEST end =3D bfd_get (addr_size_bits, cbfd, descdata); - descdata +=3D addr_size; - ULONGEST file_ofs =3D bfd_get (addr_size_bits, cbfd, descdata) * pag= e_size; - descdata +=3D addr_size; - char * filename =3D filenames; - filenames +=3D strlen ((char *) filenames) + 1; - const bfd_build_id *build_id =3D nullptr; - auto vma_map_it =3D vma_map.find (start); + unsigned int addr_size_bits =3D gdbarch_addr_bit (gdbarch); + unsigned int addr_size =3D addr_size_bits / 8; + size_t note_size =3D bfd_section_size (section); =20 - if (vma_map_it !=3D vma_map.end ()) -=09build_id =3D vma_map_it->second; + if (note_size < 2 * addr_size) +=09{ +=09 warning (_("malformed core note - too short for header")); +=09 return; +=09} =20 - loop_cb (i, start, end, file_ofs, filename, build_id); + gdb::byte_vector contents (note_size); + if (!bfd_get_section_contents (cbfd, section, contents.data (), 0, +=09=09=09=09 note_size)) +=09{ +=09 warning (_("could not get core note contents")); +=09 return; +=09} + + gdb_byte *descdata =3D contents.data (); + char *descend =3D (char *) descdata + note_size; + + if (descdata[note_size - 1] !=3D '\0') +=09{ +=09 warning (_("malformed note - does not end with \\0")); +=09 return; +=09} + + ULONGEST count =3D bfd_get (addr_size_bits, cbfd, descdata); + descdata +=3D addr_size; + + ULONGEST page_size =3D bfd_get (addr_size_bits, cbfd, descdata); + descdata +=3D addr_size; + + if (note_size < 2 * addr_size + count * 3 * addr_size) +=09{ +=09 warning (_("malformed note - too short for supplied file count")); +=09 return; +=09} + + char *filenames =3D (char *) descdata + count * 3 * addr_size; + + /* Make sure that the correct number of filenames exist. Complain +=09 if there aren't enough or are too many. */ + char *f =3D filenames; + for (int i =3D 0; i < count; i++) +=09{ +=09 if (f >=3D descend) +=09 { +=09 warning (_("malformed note - filename area is too small")); +=09 return; +=09 } +=09 f +=3D strnlen (f, descend - f) + 1; +=09} + /* Complain, but don't return early if the filename area is too big.= */ + if (f !=3D descend) +=09warning (_("malformed note - filename area is too big")); + + /* Collect proc mappings. */ + for (int i =3D 0; i < count; i++) +=09{ +=09 struct proc_mapping m =3D { .num =3D i }; +=09 m.start =3D bfd_get (addr_size_bits, cbfd, descdata); +=09 descdata +=3D addr_size; +=09 m.end =3D bfd_get (addr_size_bits, cbfd, descdata); +=09 descdata +=3D addr_size; +=09 m.file_ofs =3D bfd_get (addr_size_bits, cbfd, descdata) * page_size; +=09 descdata +=3D addr_size; +=09 m.filename =3D filenames; +=09 filenames +=3D strlen ((char *) filenames) + 1; + +=09 m.build_id =3D nullptr; +=09 auto vma_map_it =3D vma_map.find (m.start); +=09 if (vma_map_it !=3D vma_map.end ()) +=09 m.build_id =3D vma_map_it->second; + +=09 proc_mappings.push_back (m); +=09 mapping_start_addr_set.insert (m.start); +=09} } + + for (bfd_section *sec =3D cbfd->sections; sec !=3D nullptr; sec =3D sec-= >next) + { + /* The NUM field is never used, this should probably just be +=09 removed. */ + struct proc_mapping m =3D { .num =3D -1 }; + + bfd_vma start =3D bfd_section_vma (sec); + + if (mapping_start_addr_set.contains (start)) +=09continue; + + m.start =3D start; + m.end =3D start + bfd_section_size (sec); + m.file_ofs =3D 0; + m.filename =3D nullptr; + + m.build_id =3D nullptr; + auto vma_map_it =3D vma_map.find (m.start); + if (vma_map_it !=3D vma_map.end ()) +=09m.build_id =3D vma_map_it->second; + + proc_mappings.push_back (m); + mapping_start_addr_set.insert (m.start); + } + + /* Sort proc mappings. */ + std::sort (proc_mappings.begin (), proc_mappings.end (), +=09 [] (const proc_mapping &a, const proc_mapping &b) +=09 { +=09=09 return a.start < b.start; +=09 }); + + pre_loop_cb (proc_mappings.size ()); + + /* Call loop_cb with sorted proc mappings. */ + for (const auto &m : proc_mappings) + loop_cb (m.num, m.start, m.end, m.file_ofs, m.filename, m.build_id); } =20 /* Implement "info proc mappings" for corefile CBFD. */