From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id MoTUIhhw7GnfLzoAWB0awg (envelope-from ) for ; Sat, 25 Apr 2026 03:41:12 -0400 Authentication-Results: simark.ca; dkim=pass (2048-bit key; unprotected) header.d=laposte.net header.i=@laposte.net header.a=rsa-sha256 header.s=lpn-wlmd header.b=WVE7vTau; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 7EF1F1E067; Sat, 25 Apr 2026 03:41:12 -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,FREEMAIL_FROM,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 B20931E067 for ; Sat, 25 Apr 2026 03:41:10 -0400 (EDT) Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id BCF764BB3BFA for ; Sat, 25 Apr 2026 07:41:09 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BCF764BB3BFA Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=laposte.net header.i=@laposte.net header.a=rsa-sha256 header.s=lpn-wlmd header.b=WVE7vTau Received: from smtp-outgoing-1701.laposte.net (smtp-outgoing-1701.laposte.net [160.92.124.99]) by sourceware.org (Postfix) with ESMTPS id 6D5194BB24FC for ; Sat, 25 Apr 2026 07:40:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6D5194BB24FC Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=laposte.net Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=laposte.net ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 6D5194BB24FC Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=160.92.124.99 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1777102842; cv=none; b=snJPWYuLEpkOBVJKcO4n8USW/GiWqsJdtKT391OUlkxZVNFYT/UiaDK/d8AAjz94rqCfF9jAP7gLa2T+6kbmlRqeEcvxz2Tg7l1oaZMPS/hXmZMgcLpmZ15E6OTOT4YqzW1+XNcJMoQbN9+DFOc7leDX0CXq7dqiqQzlPY4hBMA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1777102842; c=relaxed/simple; bh=LNG2DQ4AbA5Wfw9mD0pxU41su6Nfw52Ca2VKJ3tET+k=; h=From:To:Subject:Date:Message-ID:MIME-Version:DKIM-Signature; b=YfESScPML0nQ2rvFv6jiegCYadR2WdkEs32ehSq/n4apZbFcxy9MHkLWs4lj9Cr0r99r1y3p9L1jJNiYGstTyISffj0RABEkpMZK3PxtAoTsEHqCFrzscb4hTYhWBp3KwxraHrkcSgtKey+X2OrlSRGDY6pZlG7zSjjcGhEzEjQ= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6D5194BB24FC X-mail-filterd: {"version":"1.9.5","queueID":"4g2hZY1VqJzgY7m","contextId": "b46226b1-c25b-45f9-b69a-4e96ff6f382b"} Received: from outgoing-mail.laposte.net (localhost.localdomain [127.0.0.1]) by mlpnf0104.laposte.net (SMTP Server) with ESMTP id 4g2hZY1VqJzgY7m; Sat, 25 Apr 2026 09:40:37 +0200 (CEST) X-mail-filterd: {"version":"1.9.5","queueID":"4g2hZY0MzczgY7R","contextId": "2796af96-cc40-48d0-9f05-0e99d4360fd0"} X-lpn-mailing: LEGIT X-lpn-spamrating: 40 X-lpn-spamlevel: not-spam Received: from desktop.lan (unknown [82.67.162.110]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mlpnf0104.laposte.net (SMTP Server) with ESMTPSA id 4g2hZY0MzczgY7R; Sat, 25 Apr 2026 09:40:35 +0200 (CEST) From: Gregori Mignerot To: gdb-patches@sourceware.org Cc: Gregori Mignerot Subject: [PATCH] [gdb] Support default locations in DWARF5 loclists Date: Sat, 25 Apr 2026 09:39:39 +0200 Message-ID: <20260425073939.84434-1-gregori.mignerot@laposte.net> X-Mailer: git-send-email 2.53.0 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=laposte.net; s=lpn-wlmd; t=1777102837; bh=LNG2DQ4AbA5Wfw9mD0pxU41su6Nfw52Ca2VKJ3tET+k=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Transfer-Encoding; b=WVE7vTauLRViRevaWxBJokXQiQca/x0QC6V6iUHmOIxxMo1JGx6hMx1KRQZ6jQ6w1tbuoES/qtzMw2YvQwzLovql40JejwJcGSFdY9WmxUMgmBdSeGHK8ZjUCTcLDMeyK1K3YrrwlUtGe7fgPYK9YjdMyEw217sXcBhoLGScPrc665ZA/HgIF81RXyHDTNxPxOhnQlQi2zkAayztsi6rr5tEtvapAMiMV6W+hAO9VKLHLW12C8ClYYy76X+7LMwSsRbcmllGpH5kWbYovkLUt7bOXGDS9LHo0oXYs3lUmW0pjDER8duXehLG7L+lmwmC6PHFBRAx3ePB8cY10kM+WA==; 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 Add support and a test for default location entries in DWARF5 loclists (DW_LLE_default_location, section 2.6.2 in the DWARF5 standard) --- gdb/dwarf2/loc.c | 60 ++++++-- .../gdb.dwarf2/loclists-default-location.c | 37 +++++ .../gdb.dwarf2/loclists-default-location.exp | 144 ++++++++++++++++++ gdb/testsuite/lib/dwarf.exp | 33 +++- 4 files changed, 258 insertions(+), 16 deletions(-) create mode 100644 gdb/testsuite/gdb.dwarf2/loclists-default-location.c create mode 100644 gdb/testsuite/gdb.dwarf2/loclists-default-location.ex= p diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c index a493a46dcfc..214c81ec4ea 100644 --- a/gdb/dwarf2/loc.c +++ b/gdb/dwarf2/loc.c @@ -83,6 +83,10 @@ enum debug_loc_kind the applicable base address. */ DEBUG_LOC_OFFSET_PAIR =3D 4, =20 + /* This is followed by a normal location expression as in .debug_loc, + to use when no other entry matches the current PC */ + DEBUG_LOC_DEFAULT_LOCATION =3D 5, + /* An internal value indicating there is insufficient data. */ DEBUG_LOC_BUFFER_OVERFLOW =3D -1, =20 @@ -275,9 +279,12 @@ decode_debug_loclists_addresses (dwarf2_per_cu *per_= cu, *new_ptr =3D loc_ptr; return DEBUG_LOC_START_END; =20 + case DW_LLE_default_location: + *new_ptr =3D loc_ptr; + return DEBUG_LOC_DEFAULT_LOCATION; + /* Following cases are not supported yet. */ case DW_LLE_startx_endx: - case DW_LLE_default_location: default: return DEBUG_LOC_INVALID_ENTRY; } @@ -379,6 +386,11 @@ dwarf2_find_location_expression (const dwarf2_loclis= t_baton *baton, unrelocated_addr base_address =3D baton->base_address; const gdb_byte *loc_ptr, *buf_end; =20 + /* When no DEBUG_LOC_DEFAULT_LOCATION is found + return NULL with length 0 (=3D no location found) */ + const gdb_byte *default_loc_ptr =3D NULL; + size_t default_locexpr_length =3D 0; + loc_ptr =3D baton->data; buf_end =3D baton->data + baton->size; =20 @@ -410,8 +422,8 @@ dwarf2_find_location_expression (const dwarf2_loclist= _baton *baton, switch (kind) { case DEBUG_LOC_END_OF_LIST: - *locexpr_length =3D 0; - return NULL; + *locexpr_length =3D default_locexpr_length; + return default_loc_ptr; =20 case DEBUG_LOC_BASE_ADDRESS: base_address =3D high; @@ -420,6 +432,7 @@ dwarf2_find_location_expression (const dwarf2_loclist= _baton *baton, case DEBUG_LOC_START_END: case DEBUG_LOC_START_LENGTH: case DEBUG_LOC_OFFSET_PAIR: + case DEBUG_LOC_DEFAULT_LOCATION: break; =20 case DEBUG_LOC_BUFFER_OVERFLOW: @@ -458,6 +471,14 @@ dwarf2_find_location_expression (const dwarf2_loclis= t_baton *baton, loc_ptr +=3D bytes_read; } =20 + if (kind =3D=3D DEBUG_LOC_DEFAULT_LOCATION) + { + default_loc_ptr =3D loc_ptr; + default_locexpr_length =3D length; + loc_ptr +=3D length; + continue; + } + if (low =3D=3D high && unrel_pc =3D=3D low && at_entry) { /* This is entry PC record present only at entry point @@ -4031,6 +4052,18 @@ loclist_describe_location (struct symbol *symbol, = CORE_ADDR addr, &low, &high, byte_order, addr_size, signed_addr_p); loc_ptr =3D new_ptr; + if (dlbaton->dwarf_version < 5) + { + length =3D extract_unsigned_integer (loc_ptr, 2, byte_order); + loc_ptr +=3D 2; + } + else + { + unsigned int bytes_read; + length =3D read_unsigned_leb128 (NULL, loc_ptr, &bytes_read); + loc_ptr +=3D bytes_read; + } + switch (kind) { case DEBUG_LOC_END_OF_LIST: @@ -4043,6 +4076,15 @@ loclist_describe_location (struct symbol *symbol, = CORE_ADDR addr, paddress (gdbarch, (CORE_ADDR) base_address)); continue; =20 + case DEBUG_LOC_DEFAULT_LOCATION: + gdb_printf (stream, _(" Default location: ")); + locexpr_describe_location_1 (symbol, addr, stream, loc_ptr, length, + addr_size, offset_size, + dlbaton->per_cu, per_objfile); + gdb_printf(stream, "\n"); + loc_ptr +=3D length; + continue; +=09 case DEBUG_LOC_START_END: case DEBUG_LOC_START_LENGTH: case DEBUG_LOC_OFFSET_PAIR: @@ -4069,18 +4111,6 @@ loclist_describe_location (struct symbol *symbol, = CORE_ADDR addr, CORE_ADDR low_reloc =3D per_objfile->relocate (low); CORE_ADDR high_reloc =3D per_objfile->relocate (high); =20 - if (dlbaton->dwarf_version < 5) - { - length =3D extract_unsigned_integer (loc_ptr, 2, byte_order); - loc_ptr +=3D 2; - } - else - { - unsigned int bytes_read; - length =3D read_unsigned_leb128 (NULL, loc_ptr, &bytes_read); - loc_ptr +=3D bytes_read; - } - /* (It would improve readability to print only the minimum necessary digits of the second number of the range.) */ gdb_printf (stream, _(" Range %s-%s: "), diff --git a/gdb/testsuite/gdb.dwarf2/loclists-default-location.c b/gdb/t= estsuite/gdb.dwarf2/loclists-default-location.c new file mode 100644 index 00000000000..fc388dcb106 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/loclists-default-location.c @@ -0,0 +1,37 @@ +/* Copyright (C) 2026 Free Software Foundation, Inc. + * + * This file is part of GDB. + * + * This program is free software; you can redistribute it and/or modif= y + * it under the terms of the GNU General Public License as published b= y + * 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 . */ + +static int +func1 (void) +{ + asm ("func1_label: .global func1_label\n"); + return 1; +} + +static int +func2 (void) +{ + asm ("func2_label: .global func2_label\n"); + return 2; +} + +int +main (void) +{ + func1 (); + func2 (); +} diff --git a/gdb/testsuite/gdb.dwarf2/loclists-default-location.exp b/gdb= /testsuite/gdb.dwarf2/loclists-default-location.exp new file mode 100644 index 00000000000..76d46a4bc18 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/loclists-default-location.exp @@ -0,0 +1,144 @@ +# Copyright 2026 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 . + +# Test support for DW_LLE_default_location + +load_lib dwarf.exp + +require dwarf2_support + +# Test with 32-bit and 64-bit DWARF. +foreach_with_prefix is_64 {false true} { + if { $is_64 } { + standard_testfile .c -dw64.S + set testfile ${testfile}-dw64 + } else { + standard_testfile .c -dw32.S + set testfile ${testfile}-dw32 + } + + # Get the addresses / lengths of func1 and func2. + lassign [function_range func1 $srcdir/$subdir/$srcfile] func1_addr f= unc1_len + lassign [function_range func2 $srcdir/$subdir/$srcfile] func2_addr f= unc2_len + + set asm_file [standard_output_file $srcfile2] + Dwarf::assemble $asm_file { + global func1_addr func1_len + global func2_addr func2_len + global is_64 + + # The CU uses the DW_FORM_loclistx form to refer to the .debug_loclists + # section. + cu { + version 5 + is_64 $is_64 + } { + declare_labels int_type + + DW_TAG_compile_unit { + DW_AT_loclists_base cu_table DW_FORM_sec_offset + } { + int_type: DW_TAG_base_type { + DW_AT_byte_size 4 DW_FORM_data1 + DW_AT_encoding @DW_ATE_signed + DW_AT_name "int" + } + + DW_TAG_variable { + DW_AT_name "default_first" + DW_AT_location 0 DW_FORM_loclistx + DW_AT_type :$int_type + } + + DW_TAG_variable { + DW_AT_name "default_last" + DW_AT_location 1 DW_FORM_loclistx + DW_AT_type :$int_type + } + + DW_TAG_subprogram { + DW_AT_name "func1" + DW_AT_low_pc $func1_addr + DW_AT_high_pc $func1_len DW_FORM_udata + } + + DW_TAG_subprogram { + DW_AT_name "func2" + DW_AT_low_pc $func2_addr + DW_AT_high_pc $func2_len DW_FORM_udata + } + } + } + + loclists {is-64 $is_64} { + # The lists in this table are accessed by index (DW_FORM_loclistx). + table {post-header-label cu_table} { + # With the default location first in the list (default_first) + list_ { + # Applies by default in func2 + default_location { + DW_OP_constu 0x2222 + DW_OP_stack_value + } + + # When in func1. + start_end $func1_addr "$func1_addr + $func1_len" { + DW_OP_constu 0x1111 + DW_OP_stack_value + } + } + + # With the default location last in the list (default_last) + list_ { + # When in func1. + start_end $func1_addr "$func1_addr + $func1_len" { + DW_OP_constu 0x3333 + DW_OP_stack_value + } + + # Applies by default in func2 + default_location { + DW_OP_constu 0x4444 + DW_OP_stack_value + } + } + } + } + } + + if { [prepare_for_testing "failed to prepare" ${testfile} \ + [list $srcfile $asm_file] {nodebug}] } { + return -1 + } + + if { ![runto_main] } { + return + } + + gdb_breakpoint "func1" + gdb_breakpoint "func2" + + with_test_prefix "non-default location" { + gdb_continue_to_breakpoint "func1" + gdb_test "print /x default_first" " =3D 0x1111" + gdb_test "print /x default_last" " =3D 0x3333" + } + + with_test_prefix "default location" { + gdb_continue_to_breakpoint "func2" + gdb_test "print /x default_first" " =3D 0x2222" + gdb_test "print /x default_last" " =3D 0x4444" + } +} diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp index 5358dc317a1..5be57a74d42 100644 --- a/gdb/testsuite/lib/dwarf.exp +++ b/gdb/testsuite/lib/dwarf.exp @@ -2432,8 +2432,9 @@ namespace eval Dwarf { with_override Dwarf::start_length Dwarf::_loclists_start_length { with_override Dwarf::base_address Dwarf::_loclists_base_address { with_override Dwarf::start_end Dwarf::_loclists_start_end { + with_override Dwarf::default_location Dwarf::_loclists_default_location= { uplevel $_level $body - }}} + }}}} =20 # Emit end of list. _op .byte 0x00 "DW_LLE_end_of_list" @@ -2520,6 +2521,36 @@ namespace eval Dwarf { incr _debug_loclists_locdesc_count } =20 + # Emit a DW_LLE_default_location entry. + # + # This proc is meant to be used within proc _loclists_list's body. = It is + # made available as `default_location` while inside proc _loclists_l= ist's body. + + proc _loclists_default_location { locdesc } { + variable _debug_loclists_addr_size + variable _debug_loclists_offset_size + variable _debug_loclists_table_count + variable _debug_loclists_list_count + variable _debug_loclists_locdesc_count + variable _level + + set locdesc [uplevel $_level [list subst $locdesc]] + + _op .byte 0x05 "DW_LLE_default_location" + + # Length of location description. + set locdesc_start_label ".Lloclists_table_${_debug_loclists_table_count= }_list_${_debug_loclists_list_count}_locdesc_${_debug_loclists_locdesc_co= unt}_start" + set locdesc_end_label ".Lloclists_table_${_debug_loclists_table_count}_= list_${_debug_loclists_list_count}_locdesc_${_debug_loclists_locdesc_coun= t}_end" + _op .uleb128 "$locdesc_end_label - $locdesc_start_label" "locdesc lengt= h" + + define_label $locdesc_start_label + set dwarf_version 5 + _location $locdesc $dwarf_version $_debug_loclists_addr_size $_debug_lo= clists_offset_size + define_label $locdesc_end_label + + incr _debug_loclists_locdesc_count + } + # Emit a DWARF .debug_macro section. # # BODY must be Tcl code that emits the content of the section. It i= s --=20 2.53.0