https://sourceware.org/bugzilla/show_bug.cgi?id=33958

Mark Wielaard <mark at klomp dot org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |mark at klomp dot org
         Resolution|---                         |FIXED

--- Comment #2 from Mark Wielaard <mark at klomp dot org> ---
commit 2e7f09629f817ca60a462a64f3ed71097970698c
Author: Mark Wielaard <[email protected]>
Date:   Mon Mar 2 15:51:48 2026 +0100

    libdwfl: Work around ET_REL files with sh_addr fields set to non-zero

    libdwfl tries to model the loading of modules (executables, shared
    libraries, the linux kernel and/or kernel modules) in
    memory. Depending on the (offline) load address it then also applies
    (simple) relocations for ET_REL (object files or kernel modules). Load
    addresses are normally represented through phdr segments for ET_EXEC
    or ET_DYN, but for ET_REL files (which don't have phdrs) the Elf
    section sh_addr fields are used.

    The sh_addr fields of the ET_REL Elf images are updated in two places
    __libdwfl_elf_address_range (through __libdwfl_report_elf) and
    __libdwfl_relocate (through dwfl_module_getelf and
    dwfl_module_getdwarf). Both rely on sh_addr being zero if no load
    address has been set yet, so the address layout for each (SHF_ALLOC)
    section is done only once.

    Recent linux kernels use a linker script that does set the sh_addr
    fields to (random, linker assigned) non-zero addresses. See commit
    1ba9f8979426 ("vmlinux.lds: Unify TEXT_MAIN, DATA_MAIN, and related
    macros").

    The sh_addr values seems unnecessary, but because they aren't zero
    anymore our layout/relocation code doesn't know it still has to figure
    out a "real" load value for these sections.

    Introduce __libdwfl_reset_sh_addr which resets all sh_addr fields to
    zero for SHF_ALLOC sections in ET_REL files.

    We don't call __libdwfl_reset_sh_addr on aux_sym files (from
    .gnu_debugdata) and when constructing an Elf from a core file. In all
    other cases we know (or assume) that the Elf file is being opened
    through libdw_open_elf (called indirectly through __libdw_open_elf,
    __libdwfl_report_offline, dwfl_module_getelf and dwfl_module_getdwarf)

    This technically changes the Elf that goes through libdwfl, but we
    would already update the sh_addr fields for ET_REL Elf sections in
    memory anyway to represent the load address as libdwfl would see
    them. So this isn't really a change in behavior (it just might update
    the sh_addr field twice).

            * libdwfl/libdwflP.h (__libdwfl_reset_sh_addr): Define new
            internal function.
            * libdwfl/relocate.c (__libdwfl_reset_sh_addr): New internal
            function.
            * libdwfl/open.c (libdw_open_elf): Call __libdwfl_reset_sh_addr.
            * libdwfl/dwfl_module_getdwarf.c (open_elf_file): Add comment.
            (find_aux_sym): Likewise.
            (find_dw): Likewise.
            * libdwfl/dwfl_segment_report_module.c
            (dwfl_segment_report_module): Likewise.
            * libdwfl/dwfl_report_elf.c (__libdwfl_report_elf): Likewise.

    https://sourceware.org/bugzilla/show_bug.cgi?id=33958

    Signed-off-by: Mark Wielaard <[email protected]>

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Reply via email to