In message <202507021341.562dfueh023...@gitrepo.freebsd.org>, Mark Johnston 
wri
tes:
> The branch main has been updated by markj:
>
> URL: https://cgit.FreeBSD.org/src/commit/?id=aefae931820fe1e93a31855296851029
> 8c7941a0
>
> commit aefae931820fe1e93a318552968510298c7941a0
> Author:     Mark Johnston <ma...@freebsd.org>
> AuthorDate: 2025-07-02 13:34:47 +0000
> Commit:     Mark Johnston <ma...@freebsd.org>
> CommitDate: 2025-07-02 13:34:47 +0000
>
>     linker: Improve handling of ifuncs when fetching symbol metadata
>     
>     When looking up symbol values, we map ifunc symbols to the value
>     returned by the resolver.  However, the returned symbol size is still
>     that of the resolver.  Be consistent and provide the size of the
>     implementation symbol as well.
>     
>     This fixes an inconsistency in dtrace's FBT provider, which enumerates
>     all function symbols and disassembles their values, using the symbol
>     size as the bound for the disassembly loop.  In particular, for ifuncs,
>     we were not creating return probes.
>     
>     Reviewed by:    kib
>     MFC after:      2 weeks
>     Sponsored by:   Innovate UK
>     Differential Revision:  https://reviews.freebsd.org/D50683
> ---
>  sys/kern/link_elf.c     | 38 ++++++++++++++++++++++++++++++++++----
>  sys/kern/link_elf_obj.c | 31 +++++++++++++++++++++++++++++--
>  2 files changed, 63 insertions(+), 6 deletions(-)
>
> diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c
> index 53af1e164980..bbebadc4c395 100644
> --- a/sys/kern/link_elf.c
> +++ b/sys/kern/link_elf.c
> @@ -1628,6 +1628,30 @@ link_elf_lookup_debug_symbol_ctf(linker_file_t lf, con
> st char *name,
>       return (i < ef->ddbsymcnt ? link_elf_ctf_get_ddb(lf, lc) : ENOENT);
>  }
>  
> +static void
> +link_elf_ifunc_symbol_value(linker_file_t lf, caddr_t *valp, size_t *sizep)
> +{
> +     c_linker_sym_t sym;
> +     elf_file_t ef;
> +     const Elf_Sym *es;
> +     caddr_t val;
> +     long off;
> +
> +     val = *valp;
> +     ef = (elf_file_t)lf;
> +
> +     /* Provide the value and size of the target symbol, if available. */
> +     val = ((caddr_t (*)(void))val)();
> +     if (link_elf_search_symbol(lf, val, &sym, &off) == 0 && off == 0) {
> +             es = (const Elf_Sym *)sym;
> +             *valp = (caddr_t)ef->address + es->st_value;
> +             *sizep = es->st_size;
> +     } else {
> +             *valp = val;
> +             *sizep = 0;
> +     }
> +}
> +
>  static int
>  link_elf_symbol_values1(linker_file_t lf, c_linker_sym_t sym,
>      linker_symval_t *symval, bool see_local)
> @@ -1635,6 +1659,7 @@ link_elf_symbol_values1(linker_file_t lf, c_linker_sym_
> t sym,
>       elf_file_t ef;
>       const Elf_Sym *es;
>       caddr_t val;
> +     size_t size;
>  
>       ef = (elf_file_t)lf;
>       es = (const Elf_Sym *)sym;
> @@ -1644,9 +1669,11 @@ link_elf_symbol_values1(linker_file_t lf, c_linker_sym
> _t sym,
>               symval->name = ef->strtab + es->st_name;
>               val = (caddr_t)ef->address + es->st_value;
>               if (ELF_ST_TYPE(es->st_info) == STT_GNU_IFUNC)
> -                     val = ((caddr_t (*)(void))val)();
> +                     link_elf_ifunc_symbol_value(lf, &val, &size);
> +             else
> +                     size = es->st_size;
>               symval->value = val;
> -             symval->size = es->st_size;
> +             symval->size = size;
>               return (0);
>       }
>       return (ENOENT);
> @@ -1668,6 +1695,7 @@ link_elf_debug_symbol_values(linker_file_t lf, c_linker
> _sym_t sym,
>       elf_file_t ef = (elf_file_t)lf;
>       const Elf_Sym *es = (const Elf_Sym *)sym;
>       caddr_t val;
> +     size_t size;
>  
>       if (link_elf_symbol_values1(lf, sym, symval, true) == 0)
>               return (0);
> @@ -1678,9 +1706,11 @@ link_elf_debug_symbol_values(linker_file_t lf, c_linke
> r_sym_t sym,
>               symval->name = ef->ddbstrtab + es->st_name;
>               val = (caddr_t)ef->address + es->st_value;
>               if (ELF_ST_TYPE(es->st_info) == STT_GNU_IFUNC)
> -                     val = ((caddr_t (*)(void))val)();
> +                     link_elf_ifunc_symbol_value(lf, &val, &size);
> +             else
> +                     size = es->st_size;
>               symval->value = val;
> -             symval->size = es->st_size;
> +             symval->size = size;
>               return (0);
>       }
>       return (ENOENT);
> diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c
> index 02fd4caffcd9..3d18aed2b1c0 100644
> --- a/sys/kern/link_elf_obj.c
> +++ b/sys/kern/link_elf_obj.c
> @@ -1510,6 +1510,30 @@ link_elf_lookup_debug_symbol_ctf(linker_file_t lf, con
> st char *name,
>       return (link_elf_ctf_get_ddb(lf, lc));
>  }
>  
> +static void
> +link_elf_ifunc_symbol_value(linker_file_t lf, caddr_t *valp, size_t *sizep)
> +{
> +     c_linker_sym_t sym;
> +     elf_file_t ef;
> +     const Elf_Sym *es;
> +     caddr_t val;
> +     long off;
> +
> +     val = *valp;
> +     ef = (elf_file_t)lf;
> +
> +     /* Provide the value and size of the target symbol, if available. */
> +     val = ((caddr_t (*)(void))val)();
> +     if (link_elf_search_symbol(lf, val, &sym, &off) == 0 && off == 0) {
> +             es = (const Elf_Sym *)sym;
> +             *valp = (caddr_t)ef->address + es->st_value;
> +             *sizep = es->st_size;
> +     } else {
> +             *valp = val;
> +             *sizep = 0;
> +     }
> +}
> +
>  static int
>  link_elf_symbol_values1(linker_file_t lf, c_linker_sym_t sym,
>      linker_symval_t *symval, bool see_local)
> @@ -1517,6 +1541,7 @@ link_elf_symbol_values1(linker_file_t lf, c_linker_sym_
> t sym,
>       elf_file_t ef;
>       const Elf_Sym *es;
>       caddr_t val;
> +     size_t size;
>  
>       ef = (elf_file_t) lf;
>       es = (const Elf_Sym*) sym;
> @@ -1527,9 +1552,11 @@ link_elf_symbol_values1(linker_file_t lf, c_linker_sym
> _t sym,
>               symval->name = ef->ddbstrtab + es->st_name;
>               val = (caddr_t)es->st_value;
>               if (ELF_ST_TYPE(es->st_info) == STT_GNU_IFUNC)
> -                     val = ((caddr_t (*)(void))val)();
> +                     link_elf_ifunc_symbol_value(lf, &val, &size);
> +             else
> +                     size = es->st_size;
>               symval->value = val;
> -             symval->size = es->st_size;
> +             symval->size = size;
>               return (0);
>       }
>       return (ENOENT);
>

This commit may have caused a panic loading linux.ko.

#0  __curthread () at /opt/src/git-src/sys/amd64/include/pcpu_aux.h:57
#1  doadump (textdump=textdump@entry=1)
    at /opt/src/git-src/sys/kern/kern_shutdown.c:399
#2  0xffffffff806fad1e in kern_reboot (howto=260)
    at /opt/src/git-src/sys/kern/kern_shutdown.c:519
#3  0xffffffff806fb247 in vpanic (fmt=0xffffffff80b2e000 "%s", 
    ap=ap@entry=0xfffffe008c8e2450)
    at /opt/src/git-src/sys/kern/kern_shutdown.c:974
#4  0xffffffff806fb073 in panic (fmt=<unavailable>)
    at /opt/src/git-src/sys/kern/kern_shutdown.c:887
#5  0xffffffff80aa8e7a in trap_fatal (frame=<optimized out>, 
    eva=<optimized out>) at /opt/src/git-src/sys/amd64/amd64/trap.c:974
#6  0xffffffff80aa8e7a in trap_pfault (frame=0xfffffe008c8e24d0, 
    usermode=false, signo=<optimized out>, ucode=<optimized out>)
#7  <signal handler called>
#8  fbt_provide_module_function (lf=lf@entry=0xfffff80126035900, 
    symindx=symindx@entry=753, symval=symval@entry=0xfffffe008c8e25f0, 
    opaque=opaque@entry=0xfffffe008c8e2640)
    at /opt/src/git-src/sys/cddl/dev/fbt/x86/fbt_isa.c:205
#9  0xffffffff80ac870d in link_elf_each_function_nameval (
    file=0xfffff80126035900, 
    callback=0xffffffff81d916a0 <fbt_provide_module_function>, 
    opaque=0xfffffe008c8e2640) at /opt/src/git-src/sys/kern/link_elf_obj.c:1
685
--Type <RET> for more, q to quit, c to continue without paging--c
#10 0xffffffff81d9035f in fbt_provide_module (arg=<optimized out>, 
    lf=0xfffff80126035900) at /opt/src/git-src/sys/cddl/dev/fbt/fbt.c:221
#11 0xffffffff81cc87fb in dtrace_module_loaded (ctl=0xfffff80126035900)
    at /opt/src/git-src/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrac
e.c:16709
#12 dtrace_kld_load (arg=<optimized out>, lf=0xfffff80126035900)
    at /opt/src/git-src/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrac
e.c:16894
#13 0xffffffff806c4ecb in linker_load_file (
    filename=0xfffff80054e6d500 "/boot/kernel/linux.ko", 
    result=<optimized out>) at /opt/src/git-src/sys/kern/kern_linker.c:518
#14 linker_load_module (kldname=kldname@entry=0x0, 
    modname=0xfffff8005437c800 "linux", parent=parent@entry=0x0, 
    verinfo=verinfo@entry=0x0, lfpp=lfpp@entry=0xfffffe008c8e2da0)
    at /opt/src/git-src/sys/kern/kern_linker.c:2292
#15 0xffffffff806c69f5 in kern_kldload (td=td@entry=0xfffff8005ce3c780, 
    file=file@entry=0xfffff8005437c800 "linux", 
    fileid=fileid@entry=0xfffffe008c8e2de4)
    at /opt/src/git-src/sys/kern/kern_linker.c:1236
#16 0xffffffff806c6b09 in sys_kldload (td=0xfffff8005ce3c780, 
    uap=0xfffff8005ce3cba8) at /opt/src/git-src/sys/kern/kern_linker.c:1259
#17 0xffffffff80aa97d6 in syscallenter (td=0xfffff8005ce3c780)
    at /opt/src/git-src/sys/amd64/amd64/../../kern/subr_syscall.c:193
#18 amd64_syscall (td=0xfffff8005ce3c780, traced=0)
    at /opt/src/git-src/sys/amd64/amd64/trap.c:1215
#19 <signal handler called>
#20 0x00000ce63ecf8c3a in ?? ()


-- 
Cheers,
Cy Schubert <cy.schub...@cschubert.com>
FreeBSD UNIX:  <c...@freebsd.org>   Web:  https://FreeBSD.org
NTP:           <c...@nwtime.org>    Web:  https://nwtime.org

                        e**(i*pi)+1=0



Reply via email to