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