[PATCH v2] bfd/dwarf2: break equal-range function ties by DIE offset, not pointer

Jan Beulich jbeulich@suse.com
Thu Sep 10 11:35:54 GMT 2026


On 10.09.2026 04:55, Sam Price wrote:
> --- /dev/null
> +++ b/binutils/testsuite/binutils-all/dw2-inline-tie.S
> @@ -0,0 +1,215 @@
> +/* Copyright (C) 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/>.  */
> +
> +/* Nothing here emits a pointer-sized datum with .dc.a, and DW_AT_high_pc
> +   uses DW_FORM_data1 (an offset from DW_AT_low_pc) rather than DW_FORM_addr.
> +   That is deliberate.  Several assemblers align a multi-byte datum to its
> +   own size, or refuse it when it is misaligned: alpha and ia64 quietly pad,
> +   sh reports "misaligned data".  In a hand-written debug section that
> +   padding lands in the middle of the DWARF and corrupts it.  Every address
> +   here is zero, so .fill emits it without going through the alignment path
> +   and without needing a relocation, and the whole file assembles to the
> +   same bytes on every target of a given pointer size.
> +
> +   A function whose whole body came from one inlined call, so the
> +   DW_TAG_inlined_subroutine covers exactly the same range as the
> +   DW_TAG_subprogram containing it.  Two entries in the function table then
> +   have the same address range, and lookup_address_in_function_table has to
> +   break the tie.  It must pick the inlined routine -- the innermost one, and
> +   the one later in the DIE stream -- and it must pick it every time.
> +
> +   Historically the tie was broken by comparing the two funcinfo pointers,
> +   which made the answer depend on the addresses bfd_zalloc happened to
> +   return.  */
> +
> +	.text
> +	.globl outer_fn
> +	.type outer_fn, %function
> +outer_fn:
> +.Lfunc_begin:
> +	.4byte	0
> +	.4byte	0
> +.Lfunc_end:
> +	.size	outer_fn, .-outer_fn
> +
> +/* A pointer, purely so that the CU header's address_size below and the
> +   DW_FORM_addr attributes agree with the target without the test having to
> +   know how wide a pointer is.  */
> +
> +	.section .debug_ptrsize
> +	/* alpha's md_cons_align aligns every multi-byte datum to its own
> +	   size.  In a hand-written debug section that padding lands in the
> +	   middle of the DWARF and corrupts it: the DIE tree loses the
> +	   inlined subroutine and the line program will not decode.
> +	   ".align 0" turns that off, and is a no-op everywhere else.  ia64
> +	   aligns the same way but does not honour ".align 0"; it has its
> +	   own copy of this test, dw2-inline-tie-ia64.s.  */
> +.Lptr_begin:
> +	.dc.a	0
> +.Lptr_end:

This is (mildly) at risk of colliding with a future Dwarf version introducing
such a section. Can't you use .struct here, i.e. avoid actually emitting any
data to any real section?

Jan


More information about the Binutils mailing list