[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