Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Simon Marchi <simon.marchi@efficios.com>
To: gdb-patches@sourceware.org
Cc: Simon Marchi <simon.marchi@efficios.com>
Subject: [PATCH 1/2] gdb/testsuite: add .debug_frame support in DWARF assembler
Date: Mon, 16 Mar 2026 13:22:26 -0400	[thread overview]
Message-ID: <20260316172239.349677-1-simon.marchi@efficios.com> (raw)

Add support to the DWARF assembler for generating .debug_frame sections.
My initial use case is to reproduce a crash happening when encountering
an empty FDE, but I suppose that other use cases will pop up in the
future.

 - Generate procs for the `DW_CFA_*` constants, similar to how the
   DW_OP_* constants are handled.  These `DW_CFA_*` procs are expected
   to be used in the CIE and FDE bodies, described below.

 - Add handlers for `DW_CFA_*` operations that take arguments.  I tried
   to cover everything that is in DWARF 5.

 - Add the `frame` proc, used to generate one .debug_frame section.

 - Add the `_frame_CIE` proc (available as `CIE` in the context of the
   frame proc), used to generate one Common Information Entry.

 - Add the `_frame_FDE` proc (available as `FDE` in the context of the
   frame proc), used to generate one Frame Description Entry.

Due to the nature of the .debug_frame contents (it describes how
specific machine registers get saved), I expect that most of
the tests written using this will be arch-specific.  But  I think it
will still be useful, as it will let us craft .debug_frame sections to
look exactly how we want.

I included a test (gdb.dwarf2/debug-frame.exp), which is more like a
proof that we can build something useful using this, and can serve as an
example for whoever wants to write a test case using this in the future.

Change-Id: I048568ded53883abf52d70139e5cd3e7b4ac3841
---
 gdb/testsuite/gdb.dwarf2/debug-frame.S   | 101 ++++++
 gdb/testsuite/gdb.dwarf2/debug-frame.exp | 130 ++++++++
 gdb/testsuite/lib/dwarf.exp              | 394 ++++++++++++++++++++++-
 3 files changed, 624 insertions(+), 1 deletion(-)
 create mode 100644 gdb/testsuite/gdb.dwarf2/debug-frame.S
 create mode 100644 gdb/testsuite/gdb.dwarf2/debug-frame.exp

diff --git a/gdb/testsuite/gdb.dwarf2/debug-frame.S b/gdb/testsuite/gdb.dwarf2/debug-frame.S
new file mode 100644
index 000000000000..231e2dc23704
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/debug-frame.S
@@ -0,0 +1,101 @@
+/* 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 <http://www.gnu.org/licenses/>.  */
+
+/* Hand-written x86-64 assembly with no .cfi directives.  The .debug_frame
+   section is supplied by the companion -dw.S file, generated by the DWARF
+   assembler.
+
+   The call chain: main -> caller -> callee.
+
+   caller sets some known register values, and callee saves those registers in
+   different way.  */
+
+	.text
+
+/* main */
+	.globl main
+	.type main, @function
+main:
+	pushq	%rbp
+	.globl main_after_push_rbp
+main_after_push_rbp:
+	movq	%rsp, %rbp
+	.globl main_after_set_rbp
+main_after_set_rbp:
+	call	caller
+	xorl	%eax, %eax
+	popq	%rbp
+	ret
+	.size main, . - main
+	.globl main_end
+main_end:
+	.globl main_len
+	.set main_len, main_end - main
+
+/* caller */
+	.globl caller
+	.type caller, @function
+caller:
+	pushq	%rbp
+	.globl caller_after_push_rbp
+caller_after_push_rbp:
+	movq	%rsp, %rbp
+	.globl caller_after_set_rbp
+caller_after_set_rbp:
+	movq	$0x11223344, %r12
+	movq	$0x55667788, %r13
+	.globl caller_call_callee
+caller_call_callee:
+	call	callee
+	popq	%rbp
+	ret
+	.size caller, . - caller
+	.globl caller_end
+caller_end:
+	.globl caller_len
+	.set caller_len, caller_end - caller
+
+/* callee */
+	.globl callee
+	.type callee, @function
+callee:
+	pushq	%rbp
+	.globl callee_after_push_rbp
+callee_after_push_rbp:
+	movq	%rsp, %rbp
+	.globl callee_after_set_rbp
+callee_after_set_rbp:
+	/* Save r12 in the stack, then clobber it.  */
+	pushq	%r12
+	xorq	%r12, %r12
+	/* Save r13 in rax, then clobber it.  */
+	movq	%r13, %rax
+	xorq	%r13, %r13
+	/* Clobber r14.  This one is described with a DWARF expression.  */
+	xorq	%r14, %r14
+	.globl callee_body
+callee_body:
+	nop
+	movq	%rax, %r13
+	popq	%r12
+	popq	%rbp
+	ret
+	.size callee, . - callee
+	.globl callee_end
+callee_end:
+	.globl callee_len
+	.set callee_len, callee_end - callee
+
+	.section	.note.GNU-stack,"",@progbits
diff --git a/gdb/testsuite/gdb.dwarf2/debug-frame.exp b/gdb/testsuite/gdb.dwarf2/debug-frame.exp
new file mode 100644
index 000000000000..ddadab7566ef
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/debug-frame.exp
@@ -0,0 +1,130 @@
+# 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 <http://www.gnu.org/licenses/>.
+
+# Test that GDB can unwind using a .debug_frame section generated by
+# the DWARF assembler.
+#
+# This test is amd64-specific, but could be ported to other
+# architectures if needed.
+
+load_lib dwarf.exp
+
+require dwarf2_support is_x86_64_m64_target
+
+standard_testfile .S -dw.S
+
+# AMD64 DWARF register numbers.
+set rax 0
+set rbp 6
+set rsp 7
+set r12 12
+set r13 13
+set r14 14
+set rip 16
+
+foreach_with_prefix is_64 { false true } {
+    set asm_file [standard_output_file ${testfile}-${is_64}-dw.S]
+
+    Dwarf::assemble $asm_file {
+	frame {
+	    declare_labels cie_label
+
+	    cie_label: CIE {
+		return_address_register $::rip
+		data_alignment_factor -8
+		is_64 $::is_64
+	    } {
+		DW_CFA_def_cfa $::rsp 8
+		DW_CFA_offset $::rip 1
+	    }
+
+	    # FDE for main
+	    FDE $cie_label main main_len {
+		is_64 $::is_64
+	    } {
+		DW_CFA_set_loc main_after_push_rbp
+		DW_CFA_def_cfa_offset 16
+		DW_CFA_offset $::rbp 2
+		DW_CFA_set_loc main_after_set_rbp
+		DW_CFA_def_cfa_register $::rbp
+	    }
+
+	    # FDE for caller
+	    FDE $cie_label caller caller_len {
+		is_64 $::is_64
+	    } {
+		DW_CFA_set_loc caller_after_push_rbp
+		DW_CFA_def_cfa_offset 16
+		DW_CFA_offset $::rbp 2
+		DW_CFA_set_loc caller_after_set_rbp
+		DW_CFA_def_cfa_register $::rbp
+	    }
+
+	    # FDE for callee
+	    FDE $cie_label callee callee_len {
+		is_64 $::is_64
+	    } {
+		DW_CFA_set_loc callee_after_push_rbp
+		DW_CFA_def_cfa_offset 16
+		DW_CFA_offset $::rbp 2
+		DW_CFA_set_loc callee_after_set_rbp
+		DW_CFA_def_cfa_register $::rbp
+
+		DW_CFA_set_loc callee_body
+		DW_CFA_offset $::r12 3
+		DW_CFA_register $::r13 $::rax
+
+		# r14's value is computed by an arbitrary expression.
+		DW_CFA_val_expression $::r14 {
+		    DW_OP_constu 0x99aabbcc
+		}
+	    }
+	}
+    }
+
+    if { [prepare_for_testing "failed to prepare" ${testfile}-${is_64} \
+	      [list $srcfile $asm_file] {nodebug}] } {
+	continue
+    }
+
+    # Stop in caller before the call, to capture rbp.
+    if { ![runto caller_call_callee] } {
+	continue
+    }
+
+    set caller_rbp [get_hexadecimal_valueof "\$rbp" "UNKNOWN"]
+
+    # Stop inside callee.
+    gdb_breakpoint callee_body
+    gdb_continue_to_breakpoint "callee_body"
+
+    # Verify backtrace shows the full call chain.
+    gdb_test "bt" "#0.*callee.*\r\n#1.*caller.*\r\n#2.*main.*"
+
+    # Select caller's frame and check saved registers.
+    gdb_test "frame 1" "#1.*caller.*"
+
+    # r12 was saved on the stack by callee.
+    gdb_test "p/x \$r12" "= 0x11223344"
+
+    # r13 was saved in rax by callee.
+    gdb_test "p/x \$r13" "= 0x55667788"
+
+    # r14's value is computed by a DWARF expression.
+    gdb_test "p/x \$r14" "= 0x99aabbcc"
+
+    # rbp should match what caller had.
+    gdb_test "p/x \$rbp" "= ${caller_rbp}"
+}
diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp
index 9fa5c4e297da..e545019e065b 100644
--- a/gdb/testsuite/lib/dwarf.exp
+++ b/gdb/testsuite/lib/dwarf.exp
@@ -602,6 +602,10 @@ namespace eval Dwarf {
     variable _loc_addr_size
     variable _loc_offset_size
 
+    # Variables used when generating a .debug_frame section.
+    variable _frame_addr_size
+    variable _frame_offset_size
+
     proc _process_one_constant {name value} {
 	variable _constants
 	variable _FORM
@@ -618,7 +622,6 @@ namespace eval Dwarf {
 	}
 
 	# We only try to shorten some very common things.
-	# FIXME: CFA?
 	switch -exact -- $prefix {
 	    TAG {
 		# Create two procedures for the tag.  These call
@@ -667,6 +670,57 @@ namespace eval Dwarf {
 		} $name $name $handler]
 	    }
 
+	    CFA {
+		# Create procs for DW_CFA_* instructions, used in
+		# .debug_frame CIE/FDE bodies.
+
+		# DW_CFA_advance_loc, DW_CFA_offset and
+		# DW_CFA_restore encode the operand in the low 6
+		# bits of the opcode byte.  They need special
+		# handling.
+		switch -exact -- $name {
+		    DW_CFA_advance_loc {
+			proc DW_CFA_advance_loc {delta} {
+			    _op .byte \
+				"$Dwarf::_constants(DW_CFA_advance_loc) + $delta" \
+				DW_CFA_advance_loc
+			}
+		    }
+
+		    DW_CFA_offset {
+			proc DW_CFA_offset {register offset} {
+			    _op .byte \
+				"$Dwarf::_constants(DW_CFA_offset) + $register" \
+				DW_CFA_offset
+			    _op .uleb128 $offset "offset"
+			}
+		    }
+
+		    DW_CFA_restore {
+			proc DW_CFA_restore {register} {
+			    _op .byte \
+				"$Dwarf::_constants(DW_CFA_restore) + $register" \
+				DW_CFA_restore
+			}
+		    }
+
+		    default {
+			# Standard CFA instruction: emit opcode
+			# byte then delegate to handler.
+			set handler _handle_default_CFA
+			if {[llength [info procs _handle_$name]] > 0} {
+			    set handler _handle_$name
+			}
+
+			# tclint-disable-next-line command-args
+			proc $name {args} [format {
+			    _op .byte $Dwarf::_constants(%s) %s
+			    %s {*}$args
+			} $name $name $handler]
+		    }
+		}
+	    }
+
 	    default {
 		return
 	    }
@@ -1456,6 +1510,127 @@ namespace eval Dwarf {
 	# error.
     }
 
+    # Helper to emit a DWARF expression block (ULEB128 length followed
+    # by the expression bytes) inside a .debug_frame CIE or FDE body.
+    # BODY is a Tcl code containing DW_OP_* calls.
+    proc _emit_cfa_expression {body} {
+	set start [new_label "cfa_expr_start"]
+	set end [new_label "cfa_expr_end"]
+	_op .uleb128 "$end - $start" "expression length"
+	define_label $start
+
+	# Pass 5 as the DWARF version, since we need to pass something, but it
+	# doesn't matter.  The DWARF version is checked only for DW_OP_* ops
+	# that don't make sense in CFI.
+	_location $body 5 $Dwarf::_frame_addr_size $Dwarf::_frame_offset_size
+	define_label $end
+    }
+
+    #
+    # Handlers for DW_CFA_* instructions.
+    #
+    # A handler is only needed if the instruction requires operands.
+    # Generic code handles emitting the opcode byte itself, so a
+    # handler should not do this.
+    #
+    # Handlers are found by name when processing the .def file.  If a
+    # handler isn't found, the default (_handle_default_CFA) is used.
+    #
+
+    proc _handle_default_CFA {} {
+	# Do nothing; if arguments are passed, Tcl will cause an
+	# error.
+    }
+
+    proc _handle_DW_CFA_set_loc {address} {
+	_op .${Dwarf::_frame_addr_size}byte $address "address"
+    }
+
+    proc _handle_DW_CFA_advance_loc1 {delta} {
+	_op .byte $delta "delta"
+    }
+
+    proc _handle_DW_CFA_advance_loc2 {delta} {
+	_op .2byte $delta "delta"
+    }
+
+    proc _handle_DW_CFA_advance_loc4 {delta} {
+	_op .4byte $delta "delta"
+    }
+
+    proc _handle_DW_CFA_offset_extended {register offset} {
+	_op .uleb128 $register "register"
+	_op .uleb128 $offset "offset"
+    }
+
+    proc _handle_DW_CFA_restore_extended {register} {
+	_op .uleb128 $register "register"
+    }
+
+    proc _handle_DW_CFA_undefined {register} {
+	_op .uleb128 $register "register"
+    }
+
+    proc _handle_DW_CFA_same_value {register} {
+	_op .uleb128 $register "register"
+    }
+
+    proc _handle_DW_CFA_register {register1 register2} {
+	_op .uleb128 $register1 "register"
+	_op .uleb128 $register2 "register"
+    }
+
+    proc _handle_DW_CFA_def_cfa {register offset} {
+	_op .uleb128 $register "register"
+	_op .uleb128 $offset "offset"
+    }
+
+    proc _handle_DW_CFA_def_cfa_register {register} {
+	_op .uleb128 $register "register"
+    }
+
+    proc _handle_DW_CFA_def_cfa_offset {offset} {
+	_op .uleb128 $offset "offset"
+    }
+
+    proc _handle_DW_CFA_def_cfa_expression {body} {
+	_emit_cfa_expression $body
+    }
+
+    proc _handle_DW_CFA_expression {register body} {
+	_op .uleb128 $register "register"
+	_emit_cfa_expression $body
+    }
+
+    proc _handle_DW_CFA_offset_extended_sf {register offset} {
+	_op .uleb128 $register "register"
+	_op .sleb128 $offset "offset"
+    }
+
+    proc _handle_DW_CFA_def_cfa_sf {register offset} {
+	_op .uleb128 $register "register"
+	_op .sleb128 $offset "offset"
+    }
+
+    proc _handle_DW_CFA_def_cfa_offset_sf {offset} {
+	_op .sleb128 $offset "offset"
+    }
+
+    proc _handle_DW_CFA_val_offset {register offset} {
+	_op .uleb128 $register "register"
+	_op .uleb128 $offset "offset"
+    }
+
+    proc _handle_DW_CFA_val_offset_sf {register offset} {
+	_op .uleb128 $register "register"
+	_op .sleb128 $offset "offset"
+    }
+
+    proc _handle_DW_CFA_val_expression {register body} {
+	_op .uleb128 $register "register"
+	_emit_cfa_expression $body
+    }
+
     # This is a miniature assembler for location expressions.  It is
     # suitable for use in the attributes to a DIE.
     #
@@ -3554,6 +3729,223 @@ namespace eval Dwarf {
 	debug_str_offsets_end:
     }
 
+    # Emit a DWARF .debug_frame section.
+    #
+    # BODY is Tcl code that emits the CIEs and FDEs which make up the
+    # section.  It is evaluated in the caller's context.
+    #
+    # Within BODY, the following commands are available:
+    #
+    #   CIE options body
+    #     -- emit a Common Information Entry.  See _frame_CIE for details.
+    #
+    #   FDE cie_label initial_location address_range body
+    #     -- emit a Frame Description Entry.  See _frame_FDE for details.
+    proc frame { body } {
+	_section .debug_frame
+
+	with_override Dwarf::CIE Dwarf::_frame_CIE {
+	    with_override Dwarf::FDE Dwarf::_frame_FDE {
+		uplevel $Dwarf::_level $body
+	    }
+	}
+    }
+
+    # Available as proc CIE when in the body of proc debug_frame.
+    #
+    # OPTIONS is a list of option-name/option-value pairs.  Supported
+    # options are (default values are shown in parentheses):
+    #
+    #   is_64 (false)
+    #     -- if true, emit a 64-bit CIE.
+    #
+    #   cie_id (default)
+    #     -- the CIE id value.  When "default", uses 0xffffffff for
+    #        32-bit and 0xffffffffffffffff for 64-bit.  Should typically not be
+    #        used unless trying to craft an invalid CIE.
+    #
+    #   version (4)
+    #     -- the CIE version number.  Note that this is version independent
+    #        from the DWARF version.  DWARF 4 and 5 both use .debug_frame
+    #        version 4.
+    #
+    #   augmentation ("")
+    #     -- the augmentation string.
+    #
+    #   addr_size (default)
+    #     -- the address size in bytes.  When "default", use 8 for 64-bit
+    #        targets and 4 for 32-bit targets.
+    #
+    #   segment_selector_size (0)
+    #     -- the segment selector size in bytes.
+    #
+    #   code_alignment_factor (1)
+    #     -- the code alignment factor.
+    #
+    #   data_alignment_factor (1)
+    #     -- the data alignment factor.
+    #
+    #   return_address_register (0)
+    #     -- the number of the "column" containing the return address.
+    #
+    # BODY is Tcl code that emits the CIE's initial instructions using
+    # DW_CFA_* operations.  It is evaluated in the caller's context.
+    proc _frame_CIE {options body} {
+	parse_options {
+	    { is_64 false }
+	    { cie_id default }
+	    { version 4 }
+	    { augmentation "" }
+	    { addr_size default }
+	    { segment_selector_size 0 }
+	    { code_alignment_factor 1 }
+	    { data_alignment_factor 1 }
+	    { return_address_register 0 }
+	}
+
+	if { $is_64 } {
+	    set Dwarf::_frame_offset_size 8
+	} else {
+	    set Dwarf::_frame_offset_size 4
+	}
+
+	if { $cie_id == "default" } {
+	    if { $is_64 } {
+		set cie_id 0xffffffffffffffff
+	    } else {
+		set cie_id 0xffffffff
+	    }
+	}
+
+	if {$addr_size == "default"} {
+	    if {[is_64_target]} {
+		set Dwarf::_frame_addr_size 8
+	    } else {
+		set Dwarf::_frame_addr_size 4
+	    }
+	} else {
+	    set Dwarf::_frame_addr_size $addr_size
+	}
+
+	declare_labels cie_post_length cie_end
+
+	# Length.
+	if { $is_64 } {
+	    _op .4byte 0xffffffff "length 1/2"
+	    _op .8byte "$cie_end - $cie_post_length" "length 2/2"
+	} else {
+	    _op .4byte "$cie_end - $cie_post_length" "length"
+	}
+
+	define_label $cie_post_length
+
+	# CIE_id
+	_op .${Dwarf::_frame_offset_size}byte $cie_id "CIE_id"
+
+	# Version.
+	_op .byte $version "version"
+
+	# Augmentation string.
+	_op .ascii [_quote $augmentation] "augmentation"
+
+	# Address size.
+	_op .byte $Dwarf::_frame_addr_size "address_size"
+
+	# Segment selector size.
+	_op .byte 0 "segment_size"
+
+	# Code alignment factor.
+	_op .uleb128 $code_alignment_factor "code_alignment_factor"
+
+	# Data alignment factor.
+	_op .sleb128 $data_alignment_factor "data_alignment_factor"
+
+	# Return address register.
+	_op .uleb128 $return_address_register "return_address_register"
+
+	# Initial instructions.
+	uplevel $Dwarf::_level $body
+
+	# Padding up to the address size.  Fill with DW_CFA_nop (zeroes).
+	_op .align $Dwarf::_frame_addr_size "padding"
+
+	define_label $cie_end
+    }
+
+    # Available as proc FDE when in the body of proc debug_frame.
+    #
+    # CIE_LABEL is the label of the CIE this FDE refers to.
+    #
+    # INITIAL_LOCATION is the address of the first instruction covered
+    # by this FDE.
+    #
+    # ADDRESS_RANGE is the number of bytes of instructions covered by
+    # this FDE.
+    #
+    # OPTIONS is a list of option-name/option-value pairs.  Supported
+    # options are (default values are shown in parentheses):
+    #
+    #   is_64 (false)
+    #     -- if true, emit a 64-bit CIE.
+    #
+    #   addr_size (default)
+    #     -- the address size in bytes.  When "default", use 8 for 64-bit
+    #        targets and 4 for 32-bit targets.
+    #
+    # BODY is Tcl code that emits the FDE's call frame instructions using
+    # DW_CFA_* operations.  It is evaluated in the caller's context.
+    proc _frame_FDE { cie_label initial_location address_range options
+		      body } {
+	parse_options {
+	    { is_64 false }
+	    { addr_size default }
+	}
+
+	if { $is_64 } {
+	    set Dwarf::_frame_offset_size 8
+	} else {
+	    set Dwarf::_frame_offset_size 4
+	}
+
+	if {$addr_size == "default"} {
+	    if {[is_64_target]} {
+		set Dwarf::_frame_addr_size 8
+	    } else {
+		set Dwarf::_frame_addr_size 4
+	    }
+	} else {
+	    set Dwarf::_frame_addr_size $addr_size
+	}
+
+	declare_labels fde_post_length fde_end
+
+	# Length.
+	if { $is_64 } {
+	    _op .4byte 0xffffffff "length 1/2"
+	    _op .8byte "$fde_end - $fde_post_length" "length 2/2"
+	} else {
+	    _op .4byte "$fde_end - $fde_post_length" "length"
+	}
+	define_label $fde_post_length
+
+	# CIE pointer, offset of the CIE into the .debug_frame section.
+	_op .${Dwarf::_frame_offset_size}byte $cie_label "CIE pointer"
+
+	# Initial location.
+	_op .${Dwarf::_frame_addr_size}byte $initial_location "initial_location"
+
+	# Address range.
+	_op .${Dwarf::_frame_addr_size}byte $address_range "address_range"
+
+	# Instructions.
+	uplevel $Dwarf::_level $body
+
+	# Padding up to the address size.  Fill with DW_CFA_nop (zeroes).
+	_op .align $Dwarf::_frame_addr_size "padding"
+
+	define_label $fde_end
+    }
+
     # The top-level interface to the DWARF assembler.
     # OPTIONS is a list with an even number of elements containing
     # option-name and option-value pairs.

base-commit: 07caff21f90c2f0c9b7b0e79b00b774be668594c
-- 
2.53.0


             reply	other threads:[~2026-03-16 17:23 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-16 17:22 Simon Marchi [this message]
2026-03-16 17:22 ` [PATCH 2/2] gdb/dwarf: fix internal error when FDEs do not describe the CFA Simon Marchi
2026-03-17 19:33   ` Simon Marchi
2026-03-18 20:27   ` [PATCH v2 1/2] gdb/testsuite: add .debug_frame support in DWARF assembler simon.marchi
2026-03-18 20:27     ` [PATCH v2 2/2] gdb/dwarf: fix internal error when FDEs do not describe the CFA simon.marchi
2026-04-06 18:10       ` Tom Tromey
2026-04-11  2:47         ` Simon Marchi
2026-04-04  1:25     ` [PATCH v2 1/2] gdb/testsuite: add .debug_frame support in DWARF assembler Simon Marchi
2026-04-06 17:45     ` Tom Tromey
2026-04-11  2:46       ` Simon Marchi

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=20260316172239.349677-1-simon.marchi@efficios.com \
    --to=simon.marchi@efficios.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