From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id 4eCwOJQx1WoDYCwAWB0awg (envelope-from ) for ; Sun, 18 Oct 2026 16:52:36 -0400 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=RtNJGqKF; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id DE54E1E050; Sun, 18 Oct 2026 16:52:36 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-6.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [IPv6:2620:52:6:3111::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 8F0501E04E for ; Sun, 18 Oct 2026 16:52:35 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E1E464BA23C4 for ; Sun, 18 Oct 2026 20:52:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E1E464BA23C4 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=RtNJGqKF Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 8E9D94BA23D6 for ; Sun, 18 Oct 2026 20:51:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 8E9D94BA23D6 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 8E9D94BA23D6 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1792356660; cv=none; b=GdsQ1F82w93SKaj7VlJGMbkgPPdqv4mvPOV7096hMUtDah99k42pF7PCsC9EAwFUemWkcVa79PUaGlo43f2Yn/E2SgrmH8C+2K/SZbKo2vI6ZqK36eneW8fdiEqTs7i7zFZpCbPIG6NYBT1jXGPZJg7XkzQVlTxDm0S87AUDKiA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1792356660; c=relaxed/simple; bh=phz0hMLc2dWYMbeEdEIynjDj9yTiXBx3WsjaHkWXSYY=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=SjoYZie5I1XIFQYDEvy4vIYRw4/qtr6vRPO83kYL3WgAqFN5NPPNwj29MJUCHxARdo6AU7/+lVY9htzisav72rdnhkFsguP4l/g2DL/7U1uGykBD5YNzRJqLBe5+wnavPRHy+WjTQigSStt6wer9klshe9lPqPHtTWQtuBzFHgY= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=RtNJGqKF DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8E9D94BA23D6 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1792356660; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Z0YhHW1kcEBXgW+T3Xt3354UXtdr3RJoSU9OICd9SXk=; b=RtNJGqKFGe3+sK5ESYdQWYx7kcmrNbtc2wlR9tA7quS9WQ7TtPt/Op2Bp/r0iKCYeT/BA9 1pAJFjm7yfPH8TcvsPWgTH5PRa5XD+bs0FD2/qs/s4fv4KH3AyapmutOPn7r4XEyXgtkNq 6tvw8HYfUe7WSBk3wfzH9pHIo0q3Tso= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-593-dEvgTc2NMNWTR1U0bzsiTA-1; Sun, 18 Oct 2026 20:50:52 +0000 X-MC-Unique: dEvgTc2NMNWTR1U0bzsiTA-1 X-Mimecast-MFC-AGG-ID: dEvgTc2NMNWTR1U0bzsiTA_1792356652 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-48e0389d6f9so898701f8f.1 for ; Sun, 18 Oct 2026 13:50:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1792356651; x=1792961451; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=Z0YhHW1kcEBXgW+T3Xt3354UXtdr3RJoSU9OICd9SXk=; b=1D+1kkhhOFuTk/jIBjhPakkhAocepoB4vpKEccYImp7svoNfMrmQfhEFCTQ1KKa9Lt datIZmcyL3foJFMET5WIFG3I0z00i2NdxDUan4pd4qu4pd0GUy/IH41hrF0ixBv8ZHyz zFP8tCLnQW+oSNNiP4Q5WzXs9lya19O2uxWA5TYw8lqdXiCYEqoIzzNGAwpbKs/LaGhH gAVmYSSCS5TN1L1L8YOLf2s/M/8AIcXMgqYNnAspknmFR+CKFUnf+Bh805QzqpjmTTtb KOje/b71SLR7L8wgJxjsF9uxC9T54q5mINnoIfWU1fZEizEYIe2iMnXPtW5gU+/DLGvL SXow== X-Gm-Message-State: AFq9FYLL7LR9VTooJ5dGj/FL/sAKHF6cIfWG7+ul4n6CaAdLgSGtNDxn tpb5YsVpi+mjW416/tz1rgju4syjyzjg3XBanVDPeSD0q6ClgvmnKONu35qfDRVlA5e+AJ+jyQT mzZ6fGc1KGJpgmLCVBQrlvh9UH7Q8rDUUPVuhLg296sHB37jqOQzJhSBy8LBqUtryzqEjOMr4CT 6KkSc7TKJcxBF7GsT54ezUzJaz56B/8r+KW4xQK5juJq9EwHI= X-Gm-Gg: AYBFou0gT3ZGnJS7eiSc8XiFtFeO1xKQEBL6CF8Cm0MhbivjTG2RKbq7gwkg7R1KbMe rt6ZmHlFi8ihIxpZ5ll7TrpVbLRiT6MeLJn8xOr+PEX0dRh2YDCJi2AP+s6waOhkGK/AE//QUk1 nslig1O7qOf67nwTabzM6vO5pXOl2yIDKrGfANyjkZfEiytBXkqEhMeJtegXMHRR7S0HB+6w8WL 0xhjYOuUmaOqbpBtec8PMljMRkRI8nz0EEEPSU4T77vJuOOKDXs/EpBx19Kq5hApHXnif73+qwf MvfWkcoM008sVEuVmaBYeRFbc1cnr2NWonZs0JPKSMISshrujcuXLL+WwPqb3Ntrrjhy X-Received: by 2002:a05:6000:454c:b0:48b:5e2:52c7 with SMTP id ffacd0b85a97d-48e079857c7mr7995492f8f.8.1792356651481; Sun, 18 Oct 2026 13:50:51 -0700 (PDT) X-Received: by 2002:a05:6000:454c:b0:48b:5e2:52c7 with SMTP id ffacd0b85a97d-48e079857c7mr7995478f8f.8.1792356650880; Sun, 18 Oct 2026 13:50:50 -0700 (PDT) Received: from localhost ([213.31.44.29]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-48dfd4d4dddsm18583791f8f.22.2026.10.18.13.50.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Oct 2026 13:50:50 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess Subject: [PATCH 6/6] gdb: extend .gdb_index tests to skip all data blocks Date: Sun, 18 Oct 2026 21:50:35 +0100 Message-Id: <03e5fe9a7996d105cde0aef714392776acf2dcae.1792356284.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 2JtMEq_07rYY9oZMytDdRfgNJS16qh8Dk3Eu6A1wO1k_1792356652 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit content-type: text/plain; charset="US-ASCII"; x-default=true X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org We already had a skip-constant-pool test in gdb.dwarf2/gdb-index-corrupted.exp. I added this early on as I could see that skipping the constant-pool was going to trigger some bugs, I added that test and fixed the bugs. This commit extends the skip_index_part mechanism, that previously only allowed skipping of the constant pool, to allow skipping of all the index parts. There was only a single bug exposed by this set of tests. When the CU list is missing GDB would still try to use the index, however, thanks to earlier patches in this series, every symbol in the symbol table was ignored as its CU index was outside the (non-existent) CU list. We already have some code in read_gdb_index_from_buffer (dwarf2/read-gdb-index.c) which clears the symbol table if the constant pool is empty. This results in GDB ignoring the index. I have extended this logic to also check the CU list. Now, if either the CU list or the constant pool are empty, and the symbol table is not empty, then we clear the symbol table, which results in GDB ignoring the index. For every other part of the index, either that part can legitimately be empty, or GDB already handled that part being empty. But having the extra testing is a good thing I think. --- gdb/dwarf2/read-gdb-index.c | 8 +- .../gdb.dwarf2/gdb-index-corrupted.exp | 79 ++++++++++++++++- gdb/testsuite/lib/dwarf.exp | 85 ++++++++++++------- 3 files changed, 138 insertions(+), 34 deletions(-) diff --git a/gdb/dwarf2/read-gdb-index.c b/gdb/dwarf2/read-gdb-index.c index 5959b0ba6bc..d624ba1779c 100644 --- a/gdb/dwarf2/read-gdb-index.c +++ b/gdb/dwarf2/read-gdb-index.c @@ -606,10 +606,12 @@ read_gdb_index_from_buffer (const char *filename, map->constant_pool = buffer.slice (metadata[i]); - if (map->constant_pool.empty () && !map->symbol_table.empty ()) + if ((map->constant_pool.empty () || *cu_list_elements == 0) + && !map->symbol_table.empty ()) { - /* An empty constant pool implies that all symbol table entries are - empty. Make map->symbol_table.empty () == true. */ + /* An empty constant pool or an empty CU list implies that all symbol + table entries are empty. Recreate the symbol table as empty so + this index will be ignored. */ map->symbol_table = offset_view (gdb::array_view (symbol_table, symbol_table)); diff --git a/gdb/testsuite/gdb.dwarf2/gdb-index-corrupted.exp b/gdb/testsuite/gdb.dwarf2/gdb-index-corrupted.exp index 865e5e50f97..56cdf895033 100644 --- a/gdb/testsuite/gdb.dwarf2/gdb-index-corrupted.exp +++ b/gdb/testsuite/gdb.dwarf2/gdb-index-corrupted.exp @@ -141,6 +141,55 @@ proc run_test { testname } { cu cu_label name _start {{cu_label function global}} } + } elseif { $testname eq "skip-cu-list" } { + # Create a .gdb_index with an empty CU list, but with a symbol + # that refers to a CU. The CU reference is now out of range, so + # GDB should ignore this .gdb_index. + gdb_index { + skip_index_part { cu_list } + } { + cu cu_label + name _start {{cu_label function global}} + } + } elseif { $testname eq "skip-tu-list" } { + # Skip the TU list. The TU list is always empty anyway, so this + # produces a perfectly valid .gdb_index; it is a sanity check + # that skipping an already-empty part changes nothing. + gdb_index { + skip_index_part { tu_list } + } { + cu cu_label + name _start {{cu_label function global}} + } + } elseif { $testname eq "skip-address-table" } { + # Skip the address table. An empty address table is valid, so + # GDB should still use this .gdb_index. + gdb_index { + skip_index_part { address_table } + } { + cu cu_label + name _start {{cu_label function global}} + } + } elseif { $testname eq "skip-symbol-table" } { + # Skip the symbol table. GDB treats an index with an empty + # symbol table as unusable and should ignore this .gdb_index. + gdb_index { + skip_index_part { symbol_table } + } { + cu cu_label + name _start {{cu_label function global}} + } + } elseif { $testname eq "skip-shortcut" } { + # Skip the shortcut table, but record a main function. With no + # shortcut table GDB cannot find the main function, but the + # index is otherwise valid and should still be used. + gdb_index { + skip_index_part { shortcut } + } { + cu cu_label + name _start {{cu_label function global}} + main DW_LANG_C99 _start + } } elseif { $testname eq "long-cu-vector" } { # Create a .gdb_index containing a CU vector in the # constant pool where the vector length is invalid. @@ -386,7 +435,14 @@ proc run_test { testname } { || $testname eq "cu-vector-offset-1" \ || $testname eq "cu-vector-offset-2" \ || $testname eq "cu-vector-offset-3" \ - || $testname eq "bad-cu-length" } { + || $testname eq "bad-cu-length" \ + || $testname eq "skip-tu-list" \ + || $testname eq "skip-address-table" \ + || $testname eq "skip-shortcut" } { + # These produce an index that GDB still uses and in which the symbol + # _start is visible, but with no recognised main function. For the + # skip-shortcut test a main function was recorded, but GDB cannot + # find it with the shortcut table missing. set expect_gdb_index_ignored false set expect_start true set expect_method false @@ -461,7 +517,21 @@ proc run_test { testname } { set expect_addr_map {} set expect_warning_re "" } elseif { $testname eq "no-null" - || $testname eq "skip-constant-pool" } { + || $testname eq "skip-constant-pool" + || $testname eq "skip-cu-list" + || $testname eq "skip-symbol-table" } { + # For the three skip-* cases, these parts of the .gdb_index are + # critical. If the symbol table is missing (or empty) then the + # index contains no useful symbols, so GDB ignores the index. If + # either of the constant pool or the CU list are missing (or empty) + # then any symbols in the symbol list cannot be instantiated, so the + # symbol table is effectively empty, again GDB ignores the index in + # these cases. + # + # The no-null case means that the constant pool is malformed + # (missing its trailing null byte). GDB ignores the constant pool + # in this case, effectively making it empty. This renders the + # symbol table useless, so GDB ignores the index. set expect_gdb_index_ignored true if { $testname eq "no-null" } { set expect_warning_re "\r\nwarning: skipping .gdb_index in \[^\r\n\]+, null byte at end of constant pool is missing\r\n" @@ -579,6 +649,11 @@ set tests { empty-component \ main-language \ no-null \ skip-constant-pool \ + skip-cu-list \ + skip-tu-list \ + skip-address-table \ + skip-symbol-table \ + skip-shortcut \ long-cu-vector \ name-offset-1 \ name-offset-2 \ diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp index b2b23167671..d0333c34fc9 100644 --- a/gdb/testsuite/lib/dwarf.exp +++ b/gdb/testsuite/lib/dwarf.exp @@ -3820,7 +3820,8 @@ namespace eval Dwarf { # has zero length. This option is only useful for # generating invalid .gdb_index sections for testing GDB's # error handling. The supported part names are: - # 'constant_pool'. + # 'cu_list', 'tu_list', 'address_table', 'symbol_table', + # 'shortcut' (version 9 only) and 'constant_pool'. # (default {} -- no .gdb_index parts are skipped) # header_override # - a dict specifying overrides for header fields. Each @@ -3955,7 +3956,8 @@ namespace eval Dwarf { # Validate the names passed to skip_index_part to catch typos in # tests. foreach part $skip_index_part { - if { [lsearch -exact { constant_pool } $part] == -1 } { + if { [lsearch -exact { cu_list tu_list address_table symbol_table \ + shortcut constant_pool } $part] == -1 } { error "gdb_index: unknown skip_index_part '$part'" } } @@ -4256,31 +4258,44 @@ namespace eval Dwarf { # CU list. gdb_index_cu_list: - foreach cu_rec $_gdb_index_cus { - lassign $cu_rec cu length - upvar $cu tmp - _op_offset 8 $tmp "CU offset" - # Record the CU's length into the index. In a well formed - # index the length recorded here must match the actual - # length of the CU in .debug_info. We allow the length to - # be overridden, for testing purposes, by passing a bogus - # length to the 'cu' command. If that was done then use - # that length instead. - if { $length ne "" } { - set cu_length $length - } elseif { [info exists _cu_lengths($tmp)] } { - set cu_length $_cu_lengths($tmp) - } else { - error "gdb_index: unknown length for CU '$cu'" + if { [lsearch -exact $skip_index_part cu_list] != -1 } { + # We've been asked to not generate the CU list. This results in + # an invalid .gdb_index. We only support this as an option for + # error testing. + } else { + foreach cu_rec $_gdb_index_cus { + lassign $cu_rec cu length + upvar $cu tmp + _op_offset 8 $tmp "CU offset" + # Record the CU's length into the index. In a well formed + # index the length recorded here must match the actual + # length of the CU in .debug_info. We allow the length to + # be overridden, for testing purposes, by passing a bogus + # length to the 'cu' command. If that was done then use + # that length instead. + if { $length ne "" } { + set cu_length $length + } elseif { [info exists _cu_lengths($tmp)] } { + set cu_length $_cu_lengths($tmp) + } else { + error "gdb_index: unknown length for CU '$cu'" + } + _op_offset 8 "$cu_length" "CU length" } - _op_offset 8 "$cu_length" "CU length" } - # TU list (empty for now). + # TU list. This is always empty for now. Skipping it (via + # SKIP_INDEX_PART) is therefore a no-op so we don't even check. gdb_index_tu_list: # Address table. gdb_index_addr_table: + if { [lsearch -exact $skip_index_part address_table] != -1 } { + # We've been asked to not generate the address table. An empty + # address table is actually valid, this exists for completeness + # and for error testing. + set _gdb_index_addrs {} + } foreach addr_entry $_gdb_index_addrs { lassign $addr_entry entry_type low high @@ -4309,6 +4324,12 @@ namespace eval Dwarf { # Symbol table. gdb_index_symtab: + if { [lsearch -exact $skip_index_part symbol_table] != -1 } { + # We've been asked to not generate the symbol table. GDB treats + # an index with an empty symbol table as unusable. This exists + # for error testing. + set table_size 0 + } for {set i 0} {$i < $table_size} {incr i} { if {$slot_occupied($i)} { set idx $slot_name_idx($i) @@ -4358,16 +4379,22 @@ namespace eval Dwarf { # Shortcut table (version 9 only). if { $version >= 9 } { gdb_index_shortcut: - _op .4byte $_gdb_index_main_lang "Language" - if { $_gdb_index_main_lang == 0 } { - _op .4byte 0 "Name offset" - } elseif { $_gdb_index_main_name_idx eq "end" } { - _op .4byte \ - "$gdb_index_constant_pool_end - $gdb_index_constant_pool" \ - "Name offset" + if { [lsearch -exact $skip_index_part shortcut] != -1 } { + # We've been asked to not generate the shortcut table. GDB + # copes with a missing shortcut table by not recording a + # main function. This exists for error testing. } else { - _op .4byte "$_gdb_index_main_name_idx" \ - "Name offset" + _op .4byte $_gdb_index_main_lang "Language" + if { $_gdb_index_main_lang == 0 } { + _op .4byte 0 "Name offset" + } elseif { $_gdb_index_main_name_idx eq "end" } { + _op .4byte \ + "$gdb_index_constant_pool_end - $gdb_index_constant_pool" \ + "Name offset" + } else { + _op .4byte "$_gdb_index_main_name_idx" \ + "Name offset" + } } } -- 2.25.4