From nobody Wed Jul 2 13:41:56 2025 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4bXLfY0y4sz60QsX; Wed, 02 Jul 2025 13:41:57 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4bXLfX4vjNz3m7p; Wed, 02 Jul 2025 13:41:56 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1751463716; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=LSM1wgM8hilfDPOpQA2fTkwyB283Z1A42ue9gzH3mr0=; b=qSC5bhE//VrlhoFo8MYNUoWmcgmcotH/LMnpWIuolb16faUpU1H5LQ5u09TVOq6lbc9HAU NxKmcadarBTrqGh7BPuOMSxYpaEJoJgpH83R/A3GokAPhOKCRWYET5jsbdRT2OVlaEU6Da 7vBua7k4PWQ7vRlAazfDioUVwtnwgzpF3CWQGa14UbkNyD46aYYO0iyBGIwCkOjG4LBn2l nAlsxjAwUvMLktxLABSJWokg/Nhps/aKeW26AIUQCek2Q0sIHgLNrqApbleGvbt5UTpjA3 /5LHykeCJNJ1tVbSQKMtHzxz+TmYnxug1L0y3s+WiiczC4gy0K3V4uvWTBSK6Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1751463716; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=LSM1wgM8hilfDPOpQA2fTkwyB283Z1A42ue9gzH3mr0=; b=If/Pa9UUkOs2Nl/CO0IyVmAzfFrrAXujjm2JlRY6GCSWZq2yin/OhlwY+gDeI5cqPtkpFH HFBMpIPfngvl8Bem2JQetrPdSUiheC1gmnw5ZeY+7TDU1ykMur+PmwWlweWrDM3oiwyACB fYjMokJVhfNLQeFTfBMbsTdqwiLY9fSSAE2o2hKH7u/zbeLyfs6P/nh2abt/VRV6xowwr7 FldN90s3o+EbFxeUEY2/euO4o5bzWvnaVvTSM768YgjIY+GLNEQuZzJBAwfR8r5quvNk9Z uiYFOJ4+ji8Jl33eeNgbPRDVR0C7bWBJd3mWIhkYguJzvwf0Z1CIAreLNtknqg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1751463716; a=rsa-sha256; cv=none; b=TWlZ61y0tXW+rDWmtlxBW7vhJbYwgnbrYC+4kTB46wbj7nUGrzDaHl0tdBpDXIeZhPBnYo ElYePb8DYf3+lnIJ6dfnwfLWTnjXuJcExlJ2CYwR2e/bTUw2yr9Zqgo4wBMFc+1gW9Vxv7 2SybNSA5WKVIADDvz+9ZvJ95yFE+jaErJt3847RyXrSIicB8eqoM+GjwYxLYoNQNy/Dcuw yyaUcJvn89MD1KMxCYpDTLh/xD1OTaSaFpkaQ/QWybtS2Dl3NyIGw3i6vSTm3pdi5YXBiH x7fm6LP7wQWbIfM/R7bQ6ss/bQX8bIQoAW8e0DbrykG2u7jORki45VvjJ7MMyg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4bXLfX4V27z6cx; Wed, 02 Jul 2025 13:41:56 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 562DfuGM023671; Wed, 2 Jul 2025 13:41:56 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 562DfuEh023668; Wed, 2 Jul 2025 13:41:56 GMT (envelope-from git) Date: Wed, 2 Jul 2025 13:41:56 GMT Message-Id: <202507021341.562DfuEh023668@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mark Johnston Subject: git: aefae931820f - main - linker: Improve handling of ifuncs when fetching symbol metadata List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: aefae931820fe1e93a318552968510298c7941a0 Auto-Submitted: auto-generated The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=aefae931820fe1e93a318552968510298c7941a0 commit aefae931820fe1e93a318552968510298c7941a0 Author: Mark Johnston AuthorDate: 2025-07-02 13:34:47 +0000 Commit: Mark Johnston 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, const 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_linker_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, const 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);