From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8CAAB25EF96; Fri, 9 May 2025 20:17:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821864; cv=none; b=CV90uabmV4WYSj3qXlRo2khER8SPi0eXXeW+9kpEbcGWd30YcQXiMlbH9GHzOF0dE98jNafLvwXqCxPtoxJ/cdgghFdDiUJWMA3ZFTBQQwUXJ6mWa5RcCkgJK8czi2w0yCETvy3IfOZAydWnpgi9WpkiR/ORYZ4aOy22vt/tT08= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821864; c=relaxed/simple; bh=EiuK1X9yLyff3oe0kJ8VsJ5+DhDW2GwGgf3p+fKQ2NM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZdZwpxHPhjTMiaQLXLmlPV1wMYuGT3ghpH1WaVn43TpEc4QGgnJXH8faCXiKETejM1wrxrQVXhY2q9Frm9HhQw5Ej53pm0hwqO87XNlpn+bpo6fijF2JtkMN+SDS0LpKuWVViQ7FgjnaEpM4AML+D4MKRSWWPdWv38A6+omHNEc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=c21BYl2r; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="c21BYl2r" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CA34DC4CEEF; Fri, 9 May 2025 20:17:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821864; bh=EiuK1X9yLyff3oe0kJ8VsJ5+DhDW2GwGgf3p+fKQ2NM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=c21BYl2rdLgF+eH3o2JamZr/mX7tkuutuMO3Ug4Ak4+y1JmUHQ1nb7AW5g3TJUjJE 2a2KZuTl6V1WVFi9hVkrXn0ZndyycOw60emEAshUzL21lLV3XoX/nrTQFxIvqWhLSY PpenhAp0tZF2LeM46MZ0qoEdQwdLD6j8+OiW54JncQRjAguwJlL2lsXW8Dfz+wML6Z +qrsxdYBPXzJZb0CUtobmUff+IWWYruLrEfXO3gCTtM7m12HhX3w4sQIICTQ8WpUew kTXNz53eJMRBlC+7GYs5VoSQ6/fKCySFmzZyzj0Fzg2jxwOrwkiCWATQLg8xEQYBIt mVBvwYFKyTLaQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan , Heiko Carstens , Vasily Gorbik , Alexander Gordeev Subject: [PATCH v2 01/62] s390/vmlinux.lds.S: Prevent thunk functions from getting placed with normal text Date: Fri, 9 May 2025 13:16:25 -0700 Message-ID: <5547e8efe2291df0c8acf06a9bbc8f3129cbe229.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The s390 indirect thunks are placed in the .text.__s390_indirect_jump_* sections. Certain config options which enable -ffunction-sections have a custom version of the TEXT_TEXT macro: .text.[0-9a-zA-Z_]* That unintentionally matches the thunk sections, causing them to get grouped with normal text rather than being handled by their intended rule later in the script: *(.text.*_indirect_*) Fix that by adding another period to the thunk section names, following the kernel's general convention for distinguishing code-generated text sections from compiler-generated ones. Cc: Heiko Carstens Cc: Vasily Gorbik Cc: Alexander Gordeev Signed-off-by: Josh Poimboeuf --- arch/s390/include/asm/nospec-insn.h | 2 +- arch/s390/kernel/vmlinux.lds.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/s390/include/asm/nospec-insn.h b/arch/s390/include/asm/no= spec-insn.h index cb15dd25bf21..84372c3f313a 100644 --- a/arch/s390/include/asm/nospec-insn.h +++ b/arch/s390/include/asm/nospec-insn.h @@ -18,7 +18,7 @@ #ifdef CONFIG_EXPOLINE_EXTERN SYM_CODE_START(\name) #else - .pushsection .text.\name,"axG",@progbits,\name,comdat + .pushsection .text..\name,"axG",@progbits,\name,comdat .globl \name .hidden \name .type \name,@function diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index ff1ddba96352..fbd6d1f83b67 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -51,7 +51,7 @@ SECTIONS IRQENTRY_TEXT SOFTIRQENTRY_TEXT FTRACE_HOTPATCH_TRAMPOLINES_TEXT - *(.text.*_indirect_*) + *(.text..*_indirect_*) *(.gnu.warning) . =3D ALIGN(PAGE_SIZE); _etext =3D .; /* End of text section */ --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CCE6E25F793; Fri, 9 May 2025 20:17:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821865; cv=none; b=jzhVn9rcqSY1z9wSSewyhzayxD2DG4Rkl0SF5YNDhBdxDspooc2DgR3DiPcjo/oj04LR6YbI6DiZRnL9MN5iFowZfwrB3R6Xb6LJ1Tvk2wnMngcR0/bzll+5agt76orrRvBN27FvhYUYzkIuA1+kotoZxDVtsGdgQ2C5wxXsZwI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821865; c=relaxed/simple; bh=4TA+WNxTrns2N3CKVtMj7arg+1eFOn6rCtTLzKHGzU4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SKH+0KIWHcsdCh4ivybMBi1g6GbVjn2ZXOQQVrHFZMA0jWakCfev9Ly3JLc5/i43u3W2zMP//ZL2awWspsYgTE7IySH+wBkWm4JZBJvAOSA1F1HVzP1tB/7XNUh4APPeGw+GHQxfl48O33smw7uAkArFkc/dqzw14YM9jHzeYGc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eqEfFw+o; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="eqEfFw+o" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 989CBC4CEE4; Fri, 9 May 2025 20:17:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821865; bh=4TA+WNxTrns2N3CKVtMj7arg+1eFOn6rCtTLzKHGzU4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eqEfFw+olaGYPSpB3Ec/rsQfz8WWspeqonPWN/YLgGrhRdVX9jdfzXdJ7Jxx0QCXn YaOqPJkIo3WoZmaiPyjrz0rsq19lJzPJ9C1jjhHv7L+DFNIg2jvuWOJG9jfV2I8sZQ 10Eysk/zAASwGxAwWslfoH3/M0KDItA1dDG3XTe/lntr6mT0YoaFSlW45gCxn0KR+M GQnrNxMC2hTlNpitl/eLfsvppF2CiD6Kab/uK290NAPACrp8ZsOPjx2pJAIzhy/XQs fHLvjFos76WRmVN8EfRshE/FIkCuUZTiAyWOqh+Jd47FzdM0RmlgoS0vLhWo8EGD0r yGb5eTmPuwiig== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan , Heiko Carstens , Vasily Gorbik , Alexander Gordeev Subject: [PATCH v2 02/62] vmlinux.lds: Unify TEXT_MAIN, DATA_MAIN, and related macros Date: Fri, 9 May 2025 13:16:26 -0700 Message-ID: <47f63106a68a38d5a2003ca2989b3512e1338ddc.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" TEXT_MAIN, DATA_MAIN and friends are defined differently depending on whether certain config options enable -ffunction-sections and/or -fdata-sections. There's no technical reason for that beyond voodoo coding. Keeping the separate implementations adds unnecessary complexity, fragments the logic, and increases the risk of subtle bugs. Unify the macros by using the same input section patterns across all configs. This is a prerequisite for the upcoming livepatch klp-build tooling which will manually enable -ffunction-sections and -fdata-sections via KCFLAGS. Cc: Heiko Carstens Cc: Vasily Gorbik Cc: Alexander Gordeev Signed-off-by: Josh Poimboeuf --- include/asm-generic/vmlinux.lds.h | 40 ++++++++++--------------------- scripts/module.lds.S | 16 ++++--------- 2 files changed, 17 insertions(+), 39 deletions(-) diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinu= x.lds.h index 66409bc3a4e0..9417c7501018 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -87,39 +87,24 @@ #define ALIGN_FUNCTION() . =3D ALIGN(CONFIG_FUNCTION_ALIGNMENT) =20 /* - * LD_DEAD_CODE_DATA_ELIMINATION option enables -fdata-sections, which - * generates .data.identifier sections, which need to be pulled in with - * .data. We don't want to pull in .data..other sections, which Linux - * has defined. Same for text and bss. + * Support -ffunction-sections by matching .text and .text.*, + * but exclude '.text..*'. * - * With LTO_CLANG, the linker also splits sections by default, so we need - * these macros to combine the sections during the final link. - * - * With AUTOFDO_CLANG and PROPELLER_CLANG, by default, the linker splits - * text sections and regroups functions into subsections. - * - * RODATA_MAIN is not used because existing code already defines .rodata.x - * sections to be brought in with rodata. + * Special .text.* sections that are typically grouped separately, such as + * .text.unlikely or .text.hot, must be matched explicitly before invoking + * TEXT_MAIN. */ -#if defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) || defined(CONFIG_LTO_CL= ANG) || \ -defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG) #define TEXT_MAIN .text .text.[0-9a-zA-Z_]* -#else -#define TEXT_MAIN .text -#endif -#if defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION) || defined(CONFIG_LTO_CL= ANG) + +/* + * Support -fdata-sections by matching .data, .data.*, and others, + * but exclude '.data..*'. + */ #define DATA_MAIN .data .data.[0-9a-zA-Z_]* .data.rel.* .data..L* .data..c= ompoundliteral* .data.$__unnamed_* .data.$L* #define SDATA_MAIN .sdata .sdata.[0-9a-zA-Z_]* #define RODATA_MAIN .rodata .rodata.[0-9a-zA-Z_]* .rodata..L* #define BSS_MAIN .bss .bss.[0-9a-zA-Z_]* .bss..L* .bss..compoundliteral* #define SBSS_MAIN .sbss .sbss.[0-9a-zA-Z_]* -#else -#define DATA_MAIN .data .data.rel .data.rel.local -#define SDATA_MAIN .sdata -#define RODATA_MAIN .rodata -#define BSS_MAIN .bss -#define SBSS_MAIN .sbss -#endif =20 /* * GCC 4.5 and later have a 32 bytes section alignment for structures. @@ -580,9 +565,8 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELL= ER_CLANG) * during second ld run in second ld pass when generating System.map * * TEXT_MAIN here will match symbols with a fixed pattern (for example, - * .text.hot or .text.unlikely) if dead code elimination or - * function-section is enabled. Match these symbols first before - * TEXT_MAIN to ensure they are grouped together. + * .text.hot or .text.unlikely). Match those before TEXT_MAIN to ensure + * they get grouped together. * * Also placing .text.hot section at the beginning of a page, this * would help the TLB performance. diff --git a/scripts/module.lds.S b/scripts/module.lds.S index 450f1088d5fd..0b5ea63d1c67 100644 --- a/scripts/module.lds.S +++ b/scripts/module.lds.S @@ -38,12 +38,10 @@ SECTIONS { __kcfi_traps : { KEEP(*(.kcfi_traps)) } #endif =20 -#ifdef CONFIG_LTO_CLANG - /* - * With CONFIG_LTO_CLANG, LLD always enables -fdata-sections and - * -ffunction-sections, which increases the size of the final module. - * Merge the split sections in the final binary. - */ + .text : { + *(.text .text.[0-9a-zA-Z_]*) + } + .bss : { *(.bss .bss.[0-9a-zA-Z_]*) *(.bss..L*) @@ -59,11 +57,7 @@ SECTIONS { *(.rodata .rodata.[0-9a-zA-Z_]*) *(.rodata..L*) } -#else - .data : { - MOD_CODETAG_SECTIONS() - } -#endif + MOD_SEPARATE_CODETAG_SECTIONS() } =20 --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1CE3925F79D; Fri, 9 May 2025 20:17:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821866; cv=none; b=VIC/uChrvXQNWBCO4j48M1ZkB2tDbQ2OGKN+a+YF5iYx7GZaZuStX7HS7rWsFbYQY9DuUKWrFBQsh8nsMVnV2WQRk5vWm4SClLe9Lr9TkKFhZiKzj3dw4mLyyeZI8xSYRI5tKfVIUFSNGbVJsyOcGfEOdC2mS7LcKEdattMq3bA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821866; c=relaxed/simple; bh=YunupWvf1Grsy+KVLlB9E51u4IP/VSauVQ+LZWaBxJ4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uy93DeKOTBavmVUyf5T3RW6WoDPztpiaK5XbIdpszSLbmMx45TmgToDshuLtJ9UIuWfFVvo2/YT5lxg9/i0BbYGuzkgByNmzXa7nji4JL/hxsQSwGfmVbZNXeSq8M7CjsDrA+pLnHO6+cKtpZ/Zjyh+/qYn6SUY8QazXJeWXc+Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IDfdI0+3; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="IDfdI0+3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 66E88C4CEF0; Fri, 9 May 2025 20:17:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821865; bh=YunupWvf1Grsy+KVLlB9E51u4IP/VSauVQ+LZWaBxJ4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IDfdI0+3vErMoqOzN3uzoKfgVhhuL/5JPZHkZLKWF4yAHc1Eu6JF1hQstNDdwyRAC f1cRJR4S15YMN0RvmeFQUwcNctvcmP7CMUFrtduMNMcHywBY749HUxj6Ze31BJp1Mb DZeJm4z9NC8cXCnRg001sOQ5mHQXoI9loZHnF7WRUYaOkX9zinrg02HgnPk7/zk35N u+db1icUbfWAtjy7YgB3Uj+PXgUSBunvJSi0Mivgyjfbi79RywgTam4I0Mr07RHZzx AV8z9bShOBLqbg21Et44rq1Xe7ebNBgKBtTSZaedP8OHVGRZElKCzonOocjyJ9liVU dJCVXJZAWfguA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 03/62] x86/module: Improve relocation error messages Date: Fri, 9 May 2025 13:16:27 -0700 Message-ID: <9a93844560bef1c6c5aa3121c454fc32316bb120.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add the section number and reloc index to relocation error messages to help find the faulty relocation. Signed-off-by: Josh Poimboeuf --- arch/x86/kernel/module.c | 15 +++++++++------ kernel/livepatch/core.c | 4 ++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c index 231d6326d1fd..ff64f3c6642b 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c @@ -97,6 +97,7 @@ static int __write_relocate_add(Elf64_Shdr *sechdrs, DEBUGP("%s relocate section %u to %u\n", apply ? "Applying" : "Clearing", relsec, sechdrs[relsec].sh_info); + for (i =3D 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { size_t size; =20 @@ -162,15 +163,17 @@ static int __write_relocate_add(Elf64_Shdr *sechdrs, =20 if (apply) { if (memcmp(loc, &zero, size)) { - pr_err("x86/modules: Invalid relocation target, existing value is nonz= ero for type %d, loc %p, val %Lx\n", - (int)ELF64_R_TYPE(rel[i].r_info), loc, val); + pr_err("x86/modules: Invalid relocation target, existing value is nonz= ero for sec %u, idx %u, type %d, loc %lx, val %llx\n", + relsec, i, (int)ELF64_R_TYPE(rel[i].r_info), + (unsigned long)loc, val); return -ENOEXEC; } write(loc, &val, size); } else { if (memcmp(loc, &val, size)) { - pr_warn("x86/modules: Invalid relocation target, existing value does n= ot match expected value for type %d, loc %p, val %Lx\n", - (int)ELF64_R_TYPE(rel[i].r_info), loc, val); + pr_warn("x86/modules: Invalid relocation target, existing value does n= ot match expected value for sec %u, idx %u, type %d, loc %lx, val %llx\n", + relsec, i, (int)ELF64_R_TYPE(rel[i].r_info), + (unsigned long)loc, val); return -ENOEXEC; } write(loc, &zero, size); @@ -179,8 +182,8 @@ static int __write_relocate_add(Elf64_Shdr *sechdrs, return 0; =20 overflow: - pr_err("overflow in relocation type %d val %Lx\n", - (int)ELF64_R_TYPE(rel[i].r_info), val); + pr_err("overflow in relocation type %d val %llx sec %u idx %d\n", + (int)ELF64_R_TYPE(rel[i].r_info), val, relsec, i); pr_err("`%s' likely not compiled with -mcmodel=3Dkernel\n", me->name); return -ENOEXEC; diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 0e73fac55f8e..7e443c2cf7d4 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -217,8 +217,8 @@ static int klp_resolve_symbols(Elf_Shdr *sechdrs, const= char *strtab, for (i =3D 0; i < relasec->sh_size / sizeof(Elf_Rela); i++) { sym =3D (Elf_Sym *)sechdrs[symndx].sh_addr + ELF_R_SYM(relas[i].r_info); if (sym->st_shndx !=3D SHN_LIVEPATCH) { - pr_err("symbol %s is not marked as a livepatch symbol\n", - strtab + sym->st_name); + pr_err("symbol %s at rela sec %u idx %d is not marked as a livepatch sy= mbol\n", + strtab + sym->st_name, symndx, i); return -EINVAL; } =20 --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4E0FB25F971; Fri, 9 May 2025 20:17:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821867; cv=none; b=aKfYwnvMqRa1iud0KjsiQVcWjuw/r3moxkWzXwEimAeOKIqFvQP1QC5wCR2EyPINHwCRUdgrZL9Wh2RKU32MjbHynbuaIWLxlDF209Lv6kOatss4tllX19+XF/EOWFibrp23X2uX0KewzqmAm+R9GcVjbxzFtHFiV56fN3EF2iA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821867; c=relaxed/simple; bh=SsRyTzAom/Wft869KnQ9Qt38Extxe2ej+kbogzcDl+g=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UdLyH2QzMub+zYBIRoQWMYqs/irLaPrAnDd7aYBQcExW/1ipRpvniNt7pimVFAlxYftV19TpYr1+n4bB4rh1s1j3wZmJ7/ja4u7Qk593fzj5uKa+j9e3Kt6+zosfhQYFLToFqrvXTt9k6P/bZa8F3Jzt+xyjqBpLTuhWnKPZ8Rs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZpE/gM0u; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ZpE/gM0u" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1B7D6C4CEF2; Fri, 9 May 2025 20:17:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821866; bh=SsRyTzAom/Wft869KnQ9Qt38Extxe2ej+kbogzcDl+g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZpE/gM0uGypZ5l7V2yRKKHZDrK7FrXSNT9r/tDEZIlya7qMkH/UNCreoisXNpW1+z i04wAoMGLNQwl76gM1xMoWmRaGLKY54M1k0ZHZ/O4lSPw1H/M1Hq+dtx9B1ZucnIdt r/Fv7OIliSH78V+uDDYPp3hdJCzX+3TtqgChNi5nBnECD2h/g2iXavn1BxgPZ3mRNQ McKJjCXE33d72v/Rr7aB9MmX2BAX+qbn3RX+AB9dVz9fQAVm6MG7BVagNx2ZD3PtjS AnMYlAQXFeqmiszRZHPK4fFLNd1v/cCs2P46EZRoIvOcbTDS1RCpfoiLvFG1iEB/Oo FnyM/YjLtmENA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 04/62] x86/kprobes: Remove STACK_FRAME_NON_STANDARD annotation Date: Fri, 9 May 2025 13:16:28 -0700 Message-ID: <2b2dffdf237d36e6184f0cd948b3ee36e8b1dadc.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Since commit 877b145f0f47 ("x86/kprobes: Move trampoline code into RODATA"), the optprobe template code is no longer analyzed by objtool so it doesn't need to be ignored. Signed-off-by: Josh Poimboeuf --- arch/x86/kernel/kprobes/opt.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c index 0aabd4c4e2c4..6f826a00eca2 100644 --- a/arch/x86/kernel/kprobes/opt.c +++ b/arch/x86/kernel/kprobes/opt.c @@ -103,7 +103,6 @@ static void synthesize_set_arg1(kprobe_opcode_t *addr, = unsigned long val) =20 asm ( ".pushsection .rodata\n" - "optprobe_template_func:\n" ".global optprobe_template_entry\n" "optprobe_template_entry:\n" #ifdef CONFIG_X86_64 @@ -160,9 +159,6 @@ asm ( "optprobe_template_end:\n" ".popsection\n"); =20 -void optprobe_template_func(void); -STACK_FRAME_NON_STANDARD(optprobe_template_func); - #define TMPL_CLAC_IDX \ ((long)optprobe_template_clac - (long)optprobe_template_entry) #define TMPL_MOVE_IDX \ --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DC54A25F993; Fri, 9 May 2025 20:17:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821868; cv=none; b=rLqANfR8PPjLgCBDHhTa9gSNKwUPmzX93xZbXsfTDyck2HDRalcr1XZHeUBHPL7qOT/OUfwzK9ABf3fs1TGf/ORVEy1MuC/BYAIYS0hAxCTYUy88GSulbsckRWpS1KSMr4UhN1xcsZHbmp6A0sZjFgsopObDjmKRXq+5DEawelg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821868; c=relaxed/simple; bh=3DCMHlXEkaRnvAyL0pRaZ+Z/6H4tZRgc5zFZ9hxwIjY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rxco0rXThG/Cu6Cx1FRzfpsBVvKNOrlxsnnGoWlVw63KFcXcWoJ2+dIehAysOB9UikMzuvja83wSR1Byvq8vRwZRjz40hRD6MmmWSYZE5depMKXXvlgGPCB5ViLYp0/Aw7/t8HfICkw93E7NzDZBQ5N6i0iBLgABwwQApfMxv04= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=BSNPsosT; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="BSNPsosT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D252DC4CEF4; Fri, 9 May 2025 20:17:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821867; bh=3DCMHlXEkaRnvAyL0pRaZ+Z/6H4tZRgc5zFZ9hxwIjY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BSNPsosT0X5Rrpd3GpV03Wf1lDsBOTd1U+y2oWlG88xzwDDhVBTUd1W0i51jwXfT7 xS7631jfxOs50kznyakE5HG45Wjxz1CktlNMZ7YGkE8Pet/fEewbNP1LITq63v580w /Y0ux1kF6eFbinlcqt2xM/cTDaEw9numldGT03pMInvEZdTAlqBtIMw7GCX4w+gIBY 98Buhv+VdfEq5Wo6FSDe98I9SUr0esPJXq9zbEiQ+m9mKwiQapsl0Eezdt3KFZ5mgF 8C5BeckBcjWy9v+apE6+uyPK7rryAbuQgFyo7epT9Lg0lcvwTb5KWQZjYankwJD99F Qg6LeieCPuMrA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 05/62] compiler: Tweak __UNIQUE_ID() naming Date: Fri, 9 May 2025 13:16:29 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for the objtool klp diff subcommand, add an underscore between the name and the counter. This will make it possible for objtool to distinguish between the non-unique and unique parts of the symbol name so it can properly correlate the symbols. Signed-off-by: Josh Poimboeuf --- include/linux/compiler.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 27725f1ab5ab..0efcfa6dab0f 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -163,7 +163,11 @@ void ftrace_likely_update(struct ftrace_likely_data *f= , int val, __asm__ ("" : "=3Dr" (var) : "0" (var)) #endif =20 -#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNT= ER__) +/* Format: __UNIQUE_ID__<__COUNTER__> */ +#define __UNIQUE_ID(name) \ + __PASTE(__UNIQUE_ID_, \ + __PASTE(name, \ + __PASTE(_, __COUNTER__))) =20 /** * data_race - mark an expression as containing intentional data races --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4079525FA11; Fri, 9 May 2025 20:17:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821868; cv=none; b=I2Owb4e6/peu8BOvF6NV4uLvjr4p5+xwwSnWkPlpXBp9Ot/5J510RIMU7n8dQs+UmK5goCsaFAg+yDwgcdbKTCCGMb7X78aLshkOQn31LvU4TZSYBiDZef4JPwHBZv4iYkXhvS2m5RZ1s659qDWQNLyOF0LB7Sa9Fal6rmd8iG4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821868; c=relaxed/simple; bh=3tlymgvkIpuX/jFV9LwurncZOXQItfZudGI+G+KrCR4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XLJl2kjbvqyKgu/lQPJHfbCR9XKcPgDi0mFx0vfbPxCqCnu2ykZ7bSb7Lr44tVOv6VhpUn+B9t7ciHe1ff3iL5XNLLKwpevxcT20bve7aipZKwmtWMLkzpIAwBnDAl6DVVU7zro7j7+oB1I3RAuUDsMSCGdD1s5XSdy8u3a/yyk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=E7zilWZM; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="E7zilWZM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 881C4C4CEF5; Fri, 9 May 2025 20:17:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821868; bh=3tlymgvkIpuX/jFV9LwurncZOXQItfZudGI+G+KrCR4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=E7zilWZMDyqkeZxOb8AHXNr5hpEKIS0O6+t5jLElB4bI/87rGlRjtuarUGKZ0Igvl uOjj4CshgSa+X2qRVY3RQcyGbtu9ni1dhoUIL02dHJsTygV4HhUfdT/cOnoHfSjvmS NLVtxIPNnv6boDruYmYC0UY2x7hymjA5iV3Q4fSh2S+yntZ0VHaJZxGb3OSOIqCI+x qUP5HYhNVeMSRdYRZaL2biEgNVdMSR3LLpREq5j94QsiyjD6Lh/tW16vgn/yHC7QkJ xERsk0I4oO8eWoZxaJz5u6MMVdwGdD3gngqv5f/3vQ1GSRsJWvAARpfrzFPCk7QAtD 7IjsmlqxXbJQA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 06/62] compiler.h: Make addressable symbols less of an eyesore Date: Fri, 9 May 2025 13:16:30 -0700 Message-ID: <7a2ba63aa1d1d3a6a904dd31188d910a8b647ba1.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Avoid underscore overload by changing: __UNIQUE_ID___addressable_loops_per_jiffy_868 to the following: __UNIQUE_ID_addressable_loops_per_jiffy_868 This matches the format used by other __UNIQUE_ID()-generated symbols and improves readability for those who stare at ELF symbol table dumps. Signed-off-by: Josh Poimboeuf --- include/linux/compiler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 0efcfa6dab0f..1390d5cb2359 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -287,7 +287,7 @@ static inline void *offset_to_ptr(const int *off) */ #define ___ADDRESSABLE(sym, __attrs) \ static void * __used __attrs \ - __UNIQUE_ID(__PASTE(__addressable_,sym)) =3D (void *)(uintptr_t)&sym; + __UNIQUE_ID(__PASTE(addressable_,sym)) =3D (void *)(uintptr_t)&sym; =20 #define __ADDRESSABLE(sym) \ ___ADDRESSABLE(sym, __section(".discard.addressable")) --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E69FA2253B2; Fri, 9 May 2025 20:17:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821869; cv=none; b=H8ITegvrLNgH+lRdyJt0jUUdCCvlJjcuemJry40Rx0zWtdGSpqKXtZFE88dyMdSkgjwNmkz030WmK2R9VP41MEFu8cQVLCrCJ1DOFUWS9CCftN/C2PzpAUXwNQrxxakwvlSbc/5zbTbhaWI1vxDONmv9tZKy72TIoZ9cqv2Az/Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821869; c=relaxed/simple; bh=CzL97ppEFIAqWlaw5ziqGUhqojWDK7zAj1wMTi9L81o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IHkGjLxOqzuIkaVRz/SUxXU0hscltKeIuud8miMfdo+CI0pWaUmHTZDK/cofoEAGekaVAyfwhZHLhV8WaupQJaih3zlWoCpxTY2cZXBFu6VU4EeIlGl5pCbkP9tAAQAwewffz8fUAEWEKJRaja7EiObJwbF550O9RtHE9OBWM3A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qJhDkWKq; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="qJhDkWKq" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 48192C4CEE9; Fri, 9 May 2025 20:17:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821868; bh=CzL97ppEFIAqWlaw5ziqGUhqojWDK7zAj1wMTi9L81o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qJhDkWKqUgHYWVYXXKx7Hih56KQo88qiJq9j5h6ll9U+mWnhJCF2hi0ellmWZelAl vQD/hIff0kzT/3HulQybXajooBX3k53HU/5CNcfPAATls8rCuRydcXAYwfaT7Mhh2C StfWE6SqYrVzKkacONPBvHKKXJZCNk39Axs4dv0rqJNsRFXudoIV8xwGuqgBCZ53D/ lNDn2fsZYg7IZkoI6vgP17f9oFGBKKNS9c6OdBw9WDa3Iuq1Z/3OkpXDhZYBblbd8c ZKQ2fM6Z4JHyUT3O0jusG2IxdBdMYdR+IBj3Xs2tGhuvN3e9xcwKpUNRgvsfuIaIue 4fVDcIsL0+DfQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 07/62] elfnote: Change ELFNOTE() to use __UNIQUE_ID() Date: Fri, 9 May 2025 13:16:31 -0700 Message-ID: <3509a9a8896dfc3f9c54f8eeb36ed77326827564.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for the objtool klp diff subcommand, replace the custom unique symbol name generation in ELFNOTE() with __UNIQUE_ID(). This standardizes the naming format for all "unique" symbols, which will allow objtool to properly correlate them. Note this also removes the "one ELF note per line" limitation. Signed-off-by: Josh Poimboeuf --- include/linux/elfnote.h | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/include/linux/elfnote.h b/include/linux/elfnote.h index 69b136e4dd2b..bb3dcded055f 100644 --- a/include/linux/elfnote.h +++ b/include/linux/elfnote.h @@ -60,23 +60,21 @@ =20 #else /* !__ASSEMBLER__ */ #include +#include /* * Use an anonymous structure which matches the shape of * Elf{32,64}_Nhdr, but includes the name and desc data. The size and * type of name and desc depend on the macro arguments. "name" must - * be a literal string, and "desc" must be passed by value. You may - * only define one note per line, since __LINE__ is used to generate - * unique symbols. + * be a literal string, and "desc" must be passed by value. */ -#define _ELFNOTE_PASTE(a,b) a##b -#define _ELFNOTE(size, name, unique, type, desc) \ +#define ELFNOTE(size, name, type, desc) \ static const struct { \ struct elf##size##_note _nhdr; \ unsigned char _name[sizeof(name)] \ __attribute__((aligned(sizeof(Elf##size##_Word)))); \ typeof(desc) _desc \ __attribute__((aligned(sizeof(Elf##size##_Word)))); \ - } _ELFNOTE_PASTE(_note_, unique) \ + } __UNIQUE_ID(note) \ __used \ __attribute__((section(".note." name), \ aligned(sizeof(Elf##size##_Word)), \ @@ -89,11 +87,10 @@ name, \ desc \ } -#define ELFNOTE(size, name, type, desc) \ - _ELFNOTE(size, name, __LINE__, type, desc) =20 #define ELFNOTE32(name, type, desc) ELFNOTE(32, name, type, desc) #define ELFNOTE64(name, type, desc) ELFNOTE(64, name, type, desc) + #endif /* __ASSEMBLER__ */ =20 #endif /* _LINUX_ELFNOTE_H */ --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2E1A82620C1; Fri, 9 May 2025 20:17:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821870; cv=none; b=G+0WDIMvPOVTgD5Osd/Frvwkzy9NeEf2KjdKYh4Aadh1wyJqJj3coFif2ZRZpBMxBFF7kfyvoM6NCjH6Zba2WQM4WjtyfQOCqPbVQA0yBOpnSxrKRAuggDahFf17RkxZiybvi1HclblhnHfh6wo4syx2m3/bGM5qsF8NSRmwFEw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821870; c=relaxed/simple; bh=h1ZVvgJ7SeyvdOYpc1dBLJ7EzMoOiIdQTGbYi9xfN0U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YiiGDCWp7x93aqGYeeFETZQoGJzluyv3zizjrhEc6dJtIfxZ/oybuPab9UmO95eZePyQXl3P5AnMwXhlV+SwHA6OJ6xcTUWUbb8mZ7cz1gUD8HiIyo8WuvVkg7xFTt4VTNqXq/VeWul6sSKfcJMKxbxA5+Xv0egEplwn+ToxPR8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lHjrvu9C; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="lHjrvu9C" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F388BC4CEFD; Fri, 9 May 2025 20:17:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821869; bh=h1ZVvgJ7SeyvdOYpc1dBLJ7EzMoOiIdQTGbYi9xfN0U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lHjrvu9CqCb2+/G/dK5E3Izb3dcBcxO+bDQp9bXFwuDELFSiu8Rmm7VD1lcFbHCLO 1R+onqiLS3uEXTB5Zmm/QK2ddbbFPZrYfZHVD8UqkLpOjTsOcPoIr4qV+7O9T2V0iF rhJMwONl28JJCF9NnKaF9T1s4kzWvhKfS4v8JjGtNxv/gbc4RZcUT/xL8QzzhggfK0 kut83eMXzzZnozuCqlHEUQQuHSQBD/eMzkUL2ygzdT4Mh20mfHlkIRNXPoiTTRiLHU N4UsVb/yClbh7x8zQULictv3pUOLpphtwdKpwdloTJsr0DsGcr63XAotkB+3n3wb1v CcXTUw9OHCWpg== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan , Masahiro Yamada Subject: [PATCH v2 08/62] kbuild: Remove 'kmod_' prefix from __KBUILD_MODNAME Date: Fri, 9 May 2025 13:16:32 -0700 Message-ID: <071a1b53fbed73dfd8ab321658af1f0c4d68b4ba.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for the objtool klp diff subcommand, remove the arbitrary 'kmod_' prefix from __KBUILD_MODNAME and instead add it explicitly in the __initcall_id() macro. This change supports the standardization of "unique" symbol naming by ensuring the non-unique portion of the name comes before the unique part. That will enable objtool to properly correlate symbols across builds. Cc: Masahiro Yamada Signed-off-by: Josh Poimboeuf --- include/linux/init.h | 3 ++- scripts/Makefile.lib | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/linux/init.h b/include/linux/init.h index ee1309473bc6..553a62f4cff5 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -206,12 +206,13 @@ extern struct module __this_module; =20 /* Format: ____ */ #define __initcall_id(fn) \ + __PASTE(kmod_, \ __PASTE(__KBUILD_MODNAME, \ __PASTE(__, \ __PASTE(__COUNTER__, \ __PASTE(_, \ __PASTE(__LINE__, \ - __PASTE(_, fn)))))) + __PASTE(_, fn))))))) =20 /* Format: ____ */ #define __initcall_name(prefix, __iid, id) \ diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 2fe73cda0bdd..fb94e1ed1092 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -104,7 +104,7 @@ name-fix-token =3D $(subst $(comma),_,$(subst -,_,$1)) name-fix =3D $(call stringify,$(call name-fix-token,$1)) basename_flags =3D -DKBUILD_BASENAME=3D$(call name-fix,$(basetarget)) modname_flags =3D -DKBUILD_MODNAME=3D$(call name-fix,$(modname)) \ - -D__KBUILD_MODNAME=3Dkmod_$(call name-fix-token,$(modname)) + -D__KBUILD_MODNAME=3D$(call name-fix-token,$(modname)) modfile_flags =3D -DKBUILD_MODFILE=3D$(call stringify,$(modfile)) =20 _c_flags =3D $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), \ --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 64CFE2620D5; Fri, 9 May 2025 20:17:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821870; cv=none; b=AYXzDRgAQNFtjOowQ0e8xAgFi7igVHfI6x95jpuTMmwnGGPThLbNXvv+Rus8Zl7abus5TNIUsIEBHAEAd1K5sNvonFPYOlUuxoza53xRScGUsga2kQiiqAuu0splv/+VJ8UOxboGDqaPtds5BtsMtItfHE4ggLvuTjYX6pDEc9I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821870; c=relaxed/simple; bh=QEuLubKoQXMBsEx5sHZzFlitGLkxHjeRmTHJo/8LE50=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hIqv3DczkBTp5bRkUn4WJEkbZXjitJydBBOotJb6WZwwSvV/3gjYRC6jVhEmpnhzl4uHoBgxjfkAERzemZcm72fge0IEBYgxH9gPHcImCOeMYaTh8aqzTN/BlU8HJHipLXwOu9uwu4ZizbUUXpclE+dQ6pzZjkQPWsubxRhm4f8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=AJkEtWvh; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="AJkEtWvh" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B232CC4CEF1; Fri, 9 May 2025 20:17:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821870; bh=QEuLubKoQXMBsEx5sHZzFlitGLkxHjeRmTHJo/8LE50=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AJkEtWvhwgUEm69O7cnYy26j+QGpFDMsD3psaSXAryU9kiorxwRZlT91twuv4xCj2 4nigkHAjOHSSn8HjVlezDtSolnIstTJEh9GqJCuD3t5Lc0O0XHyVekGmiDcUI5Ige8 HmxwEpq7Pa2w+Fg5dOmu5G7rTduN2XfOJrOmtanLuKj6c6VK0pzOb1i/Yg3AqGPn3O jZat6teAq69tIxJW0Ag5poplfkDJEhIiWdPXrzyT5RF/TZ4bvLDaAoxU0VLWnRwdTQ 9HUXC6Cf/VdPgR8524YrmqkF/u/LezJgrg9DaUlLtZ11wq9kLvePjI0C2pY4m/P74C pqT71uYMceRrg== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan , Masahiro Yamada Subject: [PATCH v2 09/62] modpost: Ignore unresolved section bounds symbols Date: Fri, 9 May 2025 13:16:33 -0700 Message-ID: <9629c36b9515e9574783d63ea6f937f51b3e7a56.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for klp-build livepatch module creation tooling, suppress warnings for unresolved references to linker-generated __start_* and __stop_* section bounds symbols. These symbols are expected to be undefined when modpost runs, as they're created later by the linker. Cc: Masahiro Yamada Signed-off-by: Josh Poimboeuf --- scripts/mod/modpost.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index be89921d60b6..84266a19b296 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -604,6 +604,11 @@ static int ignore_undef_symbol(struct elf_info *info, = const char *symname) strstarts(symname, "_savevr_") || strcmp(symname, ".TOC.") =3D=3D 0) return 1; + + /* ignore linker-created section bounds variables */ + if (strstarts(symname, "__start_") || strstarts(symname, "__stop_")) + return 1; + /* Do not ignore this symbol */ return 0; } --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 973A2262FF3; Fri, 9 May 2025 20:17:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821871; cv=none; b=bcrDsxKiM5OEz4GnD393OV1PwDZmXtJOsCJXb7mfhid/L2+PREh+GFcwgxGZG7BQFoSdGHekhfaH9P1WK3H5ErtKeRiu/mOuAluDwmkSgUG9MJEDWgCIhnHEP89Mnl9VA4qxgKyDAjZzfj08aJPSWHXmLLl/bBlp1fJraQ3nmD8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821871; c=relaxed/simple; bh=68/5Prs0aj5PVNoTeZpDaBIYAjvhkFM/hSAYUYosuTc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RjNc7AznBd7kkYmH85Vge3qCacr/+o/VbOJD/DJnj9Z3CFYMp21fDWOqfi2Ao3+ScflRL4fYjONKv/ysxVsOCLmXODawZKaG7FXOg6IuHP9aNcAV0ZjxX5JkbWj/1veCNoVOt9E2yTDM/x17eHY8oPFIk2yff9O3gaYt4Qt1t2U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=py1ZUo96; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="py1ZUo96" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6EA29C4CEF2; Fri, 9 May 2025 20:17:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821871; bh=68/5Prs0aj5PVNoTeZpDaBIYAjvhkFM/hSAYUYosuTc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=py1ZUo96UHrV4ZCWTxXXdoDulRJ9IZKrXIYFtAbTtYolygJ+UOTomw5WN1nSy0zVh sAyDkwIS3tTtcKmo5XtfCJcHXv8niPqh+uNeZxuj0keRZ4yJJ8+TRWvuXwckRN3eig T1H067BPMHX9IeKKzfdfNJr8UnXvRjh1yGHyHVRx1R4y21tgu18Zt0ruTy6QIHQob6 sU1C+jOnJCPADyCXEeAjbwC70uoN8zuwEhAaLQN3SnWHcpg6d91tro1styD7tMaWWx SPM61Vt9LEa1otwxZr0EDRPMiUVTXTlfGX421FOKJY47TwMb4VMJ5gbQdUXoTVDxQv AD46xbPLfPAGQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 10/62] x86/alternative: Refactor INT3 call emulation selftest Date: Fri, 9 May 2025 13:16:34 -0700 Message-ID: <517fdaa3f187c9a69d6aac8c8b7526776b99f96d.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The INT3 call emulation selftest is a bit fragile as it relies on the compiler not inserting any extra instructions before the int3_selftest_ip() definition. Also, the int3_selftest_ip() symbol overlaps with the int3_selftest symbol(), which can confuse objtool. Fix those issues by slightly reworking the functionality and moving int3_selftest_ip() to a separate asm function. While at it, improve the naming. Signed-off-by: Josh Poimboeuf --- arch/x86/kernel/alternative.c | 51 +++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index ddbc303e41e3..ec220e53cb52 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -1899,21 +1899,34 @@ int alternatives_text_reserved(void *start, void *e= nd) * See entry_{32,64}.S for more details. */ =20 -/* - * We define the int3_magic() function in assembly to control the calling - * convention such that we can 'call' it from assembly. - */ - -extern void int3_magic(unsigned int *ptr); /* defined in asm */ +extern void int3_selftest_asm(unsigned int *ptr); =20 asm ( " .pushsection .init.text, \"ax\", @progbits\n" -" .type int3_magic, @function\n" -"int3_magic:\n" +" .type int3_selftest_asm, @function\n" +"int3_selftest_asm:\n" ANNOTATE_NOENDBR -" movl $1, (%" _ASM_ARG1 ")\n" + /* + * INT3 padded with NOP to CALL_INSN_SIZE. The INT3 triggers an + * exception, then the int3_exception_nb notifier emulates a call to + * int3_selftest_callee(). + */ +" int3; nop; nop; nop; nop\n" ASM_RET -" .size int3_magic, .-int3_magic\n" +" .size int3_selftest_asm, . - int3_selftest_asm\n" +" .popsection\n" +); + +extern void int3_selftest_callee(unsigned int *ptr); + +asm ( +" .pushsection .init.text, \"ax\", @progbits\n" +" .type int3_selftest_callee, @function\n" +"int3_selftest_callee:\n" + ANNOTATE_NOENDBR +" movl $0x1234, (%" _ASM_ARG1 ")\n" + ASM_RET +" .size int3_selftest_callee, . - int3_selftest_callee\n" " .popsection\n" ); =20 @@ -1922,7 +1935,7 @@ extern void int3_selftest_ip(void); /* defined in asm= below */ static int __init int3_exception_notify(struct notifier_block *self, unsigned long val, void= *data) { - unsigned long selftest =3D (unsigned long)&int3_selftest_ip; + unsigned long selftest =3D (unsigned long)&int3_selftest_asm; struct die_args *args =3D data; struct pt_regs *regs =3D args->regs; =20 @@ -1937,7 +1950,7 @@ int3_exception_notify(struct notifier_block *self, un= signed long val, void *data if (regs->ip - INT3_INSN_SIZE !=3D selftest) return NOTIFY_DONE; =20 - int3_emulate_call(regs, (unsigned long)&int3_magic); + int3_emulate_call(regs, (unsigned long)&int3_selftest_callee); return NOTIFY_STOP; } =20 @@ -1953,19 +1966,11 @@ static noinline void __init int3_selftest(void) BUG_ON(register_die_notifier(&int3_exception_nb)); =20 /* - * Basically: int3_magic(&val); but really complicated :-) - * - * INT3 padded with NOP to CALL_INSN_SIZE. The int3_exception_nb - * notifier above will emulate CALL for us. + * Basically: int3_selftest_callee(&val); but really complicated :-) */ - asm volatile ("int3_selftest_ip:\n\t" - ANNOTATE_NOENDBR - " int3; nop; nop; nop; nop\n\t" - : ASM_CALL_CONSTRAINT - : __ASM_SEL_RAW(a, D) (&val) - : "memory"); + int3_selftest_asm(&val); =20 - BUG_ON(val !=3D 1); + BUG_ON(val !=3D 0x1234); =20 unregister_die_notifier(&int3_exception_nb); } --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 32ED2262FED; Fri, 9 May 2025 20:17:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821872; cv=none; b=oAvWILNSCniCCMd801Ia8NY845KDEIvFKGrZ5GrA+VgphnNoJtW/psdAyxB5YAIrwZxmkVmGzjGIRpLZfJNvE5imfdVyZU5MB918/aVnvftsqb4L5Qmgm++ZYYhERqTHyGjxZItGIkO7NYMooVPmaWXfeEEvq48L6bSFBR6lwv4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821872; c=relaxed/simple; bh=LDUKcJdT8kH8BjUeYhtSNqXt7nIhVlc4MqtNBfwYqyM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mnECaXH+Zc98hnrfLpmEsVI3iGd6CnS6H72zv3nwuYWR07WuQdJk4SDrEjZ+VyzXY99ui+T9PR/8n9ZiQgKFBKbS0WRtCelz3VXdSlEdLZb8OVm7/sbpAxoQTIDtaacw5sKteDdna7EcPyVVcZqMZ3zhneGAwpqOZiinCb43emk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rf1iBl+H; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rf1iBl+H" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 22B52C4CEF1; Fri, 9 May 2025 20:17:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821871; bh=LDUKcJdT8kH8BjUeYhtSNqXt7nIhVlc4MqtNBfwYqyM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rf1iBl+HpDRgdOTBIBu3Fml6XJxx7FFMFnr4l4LXlYiU9tVDUdFJBOT9qH05Z/hsY qYB7hkOKR5LmSKHSwrndV6t+SAdQdrzv+fNd+FEQ83kMGamgVxXvhU4yG0RGe4oAEd OYHrwCWZYsFzWDTYiFHwG10JKBDA/qsRtZ/rQJPByCMlg+xOGVyQgTFlz0u+hbfAOy VMEPF2AFedtH/jE+mTzK2NW776gu9KSeAqWCPe+Bdw4yWLh76l7JceorJiZNuOHZpW icLom8m+NQWZWlKio+otwzdVBEcfc6yfh1cxNHN3UY/AWX3z1c0ps2HaY8O4R3xX+e T841Xo1E54B9w== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 11/62] objtool: Make find_symbol_containing() less arbitrary Date: Fri, 9 May 2025 13:16:35 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In the rare case of overlapping symbols, find_symbol_containing() just returns the first one it finds. Make it slightly less arbitrary by returning the smallest symbol with size > 0. Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 8dffe68d705c..bc24d59360df 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -193,14 +193,29 @@ struct symbol *find_func_by_offset(struct section *se= c, unsigned long offset) struct symbol *find_symbol_containing(const struct section *sec, unsigned = long offset) { struct rb_root_cached *tree =3D (struct rb_root_cached *)&sec->symbol_tre= e; - struct symbol *iter; + struct symbol *sym =3D NULL, *tmp; =20 - __sym_for_each(iter, tree, offset, offset) { - if (iter->type !=3D STT_SECTION) - return iter; + __sym_for_each(tmp, tree, offset, offset) { + if (tmp->len) { + if (!sym) { + sym =3D tmp; + continue; + } + + if (sym->offset !=3D tmp->offset || sym->len !=3D tmp->len) { + /* + * In the rare case of overlapping symbols, + * pick the smaller one. + * + * TODO: outlaw overlapping symbols + */ + if (tmp->len < sym->len) + sym =3D tmp; + } + } } =20 - return NULL; + return sym; } =20 /* --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D5258263F4C; Fri, 9 May 2025 20:17:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821872; cv=none; b=a/sYZBD4Z00KOPZGKI6a3i108wx224ftds/cfY3vBcABcJ3hRODwR2CA/rZEZiOjJ6DvDsNywLYnM/Y0pwzKtW+Mge3KaUF24D8wQRU6GTbG4LfJljjF9ANhA+iDnUojjCtmgJktHSdj33/K8mA2ssXnLhbvSx+KSJDqj5Fcuf8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821872; c=relaxed/simple; bh=MkbdHRI47JadcIEFytvf/CtdZC615MAVjwn+3s/CxMI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VehHsRXwxvcb/kVmXalyivj8QOrTNYxLj8FfhNM55/jM+VWDBZ2kzLcMTc/SBAPL54uW0sBdRLivlXeLXYIiyGJxEnrrP9Cjc++XEXpJ/YO3Q2H0msHKvyYwQZePmHPCsOzpkiaVTnQHWhWZuJMPiih7KZOxvuQPVg+fzoyt5nk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rxEHaRkR; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rxEHaRkR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CAE5CC4CEEE; Fri, 9 May 2025 20:17:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821872; bh=MkbdHRI47JadcIEFytvf/CtdZC615MAVjwn+3s/CxMI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rxEHaRkRrPnlICxhFemKwPPpiU3Fvkwdf0J8FqgkIdICRFQWiDLLvNN+S+Qa1cs3c SyfkdmQi3UkLDMqr9oN5ix0PJAx4WulUwgY+tLGwyg4Zze508b2faKfMsNsv0kx61j SUoy352HqNBLLxCDEB0CmKbuRgV+muYHlBjz9WZVVaszCIqqET6Zg70Ql7qlVq2Rfe tDzvr/sKdZy8J02diXok2JYXKVLNFbJ47ASQJpQlCg5nj2Va5BWb/4wBJ6JwsuWAJs gW7uv1EovI3iroLsTitHsiqVuuuqaon0+LiC2HP7Jns8w4lMqjA2rym3FrcG02K/lt TaPN2Kj2a6FZA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 12/62] objtool: Speed up SHT_GROUP reindexing Date: Fri, 9 May 2025 13:16:36 -0700 Message-ID: <11535adbcbd2c1598dca5aff3cb9eb2a60a3eeda.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" After elf_update_group_sh_info() was introduced, a prototype version of "objtool klp diff" went from taking ~1s to several minutes, due to looping almost endlessly in elf_update_group_sh_info() while creating thousands of local symbols in a file with thousands of sections. Dramatically improve the performance by marking all symbols' correlated SHT_GROUP sections while reading the object. That way there's no need to search for it every time a symbol gets reindexed. Fixes: 2cb291596e2c ("objtool: Fix up st_info in COMDAT group section") Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 47 ++++++++++++++++++----------- tools/objtool/include/objtool/elf.h | 1 + 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index bc24d59360df..1c1bb2cb960d 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -587,28 +587,32 @@ static int read_symbols(struct elf *elf) return -1; } =20 -/* - * @sym's idx has changed. Update the sh_info in group sections. - */ -static void elf_update_group_sh_info(struct elf *elf, Elf32_Word symtab_id= x, - Elf32_Word new_idx, Elf32_Word old_idx) +static int mark_group_syms(struct elf *elf) { - struct section *sec; + struct section *symtab, *sec; + struct symbol *sym; + + symtab =3D find_section_by_name(elf, ".symtab"); + if (!symtab) { + ERROR("no .symtab"); + return -1; + } =20 list_for_each_entry(sec, &elf->sections, list) { - if (sec->sh.sh_type !=3D SHT_GROUP) - continue; - if (sec->sh.sh_link =3D=3D symtab_idx && - sec->sh.sh_info =3D=3D old_idx) { - sec->sh.sh_info =3D new_idx; - mark_sec_changed(elf, sec, true); - /* - * Each ELF group should have a unique symbol key. - * Return early on match. - */ - return; + if (sec->sh.sh_type =3D=3D SHT_GROUP && + sec->sh.sh_link =3D=3D symtab->idx) { + sym =3D find_symbol_by_index(elf, sec->sh.sh_info); + if (!sym) { + ERROR("%s: can't find SHT_GROUP signature symbol", + sec->name); + return -1; + } + + sym->group_sec =3D sec; } } + + return 0; } =20 /* @@ -802,7 +806,11 @@ __elf_create_symbol(struct elf *elf, struct symbol *sy= m) if (elf_update_sym_relocs(elf, old)) return NULL; =20 - elf_update_group_sh_info(elf, symtab->idx, new_idx, first_non_local); + if (old->group_sec) { + old->group_sec->sh.sh_info =3D new_idx; + mark_sec_changed(elf, old->group_sec, true); + } + new_idx =3D first_non_local; } =20 @@ -1075,6 +1083,9 @@ struct elf *elf_open_read(const char *name, int flags) if (read_symbols(elf)) goto err; =20 + if (mark_group_syms(elf)) + goto err; + if (read_relocs(elf)) goto err; =20 diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index c7c4e87ebe88..0a2fa3ac0079 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -72,6 +72,7 @@ struct symbol { u8 ignore : 1; struct list_head pv_target; struct reloc *relocs; + struct section *group_sec; }; =20 struct reloc { --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2C3D7264609; Fri, 9 May 2025 20:17:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821873; cv=none; b=RO2zU1ogITCghOf7iqYUYk7nsNcbUOrx6gDjmmRAuriimeCuI8Xxof+6w4gMmegNAp9b17k35fZxlnHQEgQ9BFjMsbky07z9IKR8/s6u48dHW4E5ED9eOFAluCGPwgfKNwgyUMPOuki2om/EY82m0RRQLo9oUtHUVwlJBZ4EYIE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821873; c=relaxed/simple; bh=QAQwoFDGTO2//ydxJPnSjPdvJrw2htDOdNuFU1aeSnY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BYBVdrcV+IgpfcxbEJq5iSTKKmy4qgy9ICSGwUBq1of1Q7B78D6tgu+9XmKkk65gp+HrifTuvvcg8LY8fOhQBZLInVs0rNQECXT5vwU9OOMZ7UFnKg29tyVpXNnVTDZR5sWQJIUOz1uMkSBOoQcaUfCzobeqrJ8HyiCpCdT7EVI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=sGiLurQG; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="sGiLurQG" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7EAE9C4CEEF; Fri, 9 May 2025 20:17:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821873; bh=QAQwoFDGTO2//ydxJPnSjPdvJrw2htDOdNuFU1aeSnY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sGiLurQGtAdJZAcD7S6o214GCLdiq9s/FPQIfqbt3AOA8GLYMck9Cxt8fy87rVyAP LiWAnys0Qz2h5EfOdE8niGh/cL3xNyVSNrGcd7AsgNzMtJ0mCKXJlGPZUiaP23ZOKx EpZcvJJkemhgc0kWCVASTeifE4K1eudeauTEafm0RwYO/gsHSYSsWLg/uMvPmFQJcR o5chIPDRX/IkSR9uj1NoQziZV3/+omRWWgHh5ss1l2dMiI9PPdNLquAGuj3JoMe+ic 0B6F/tqnsgTEdLjQOJMlVKzDBz1odNK6RrIY9IXJiWANWah7hWpKKh+uBT88iSGvxA 2g9HmYh5XqM6w== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 13/62] objtool: Fix broken error handling in read_symbols() Date: Fri, 9 May 2025 13:16:37 -0700 Message-ID: <16c0fcf02cdce0b93666e853070086d5e40be0e6.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The free(sym) call in the read_symbols() error path is fundamentally broken: 'sym' doesn't point to any allocated block. If triggered, things would go from bad to worse. Remove the free() and simplify the error paths. Freeing memory isn't necessary here anyway, these are fatal errors which lead to an immediate exit(). Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 1c1bb2cb960d..b009d9feed76 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -492,14 +492,14 @@ static int read_symbols(struct elf *elf) if (!gelf_getsymshndx(symtab->data, shndx_data, i, &sym->sym, &shndx)) { ERROR_ELF("gelf_getsymshndx"); - goto err; + return -1; } =20 sym->name =3D elf_strptr(elf->elf, symtab->sh.sh_link, sym->sym.st_name); if (!sym->name) { ERROR_ELF("elf_strptr"); - goto err; + return -1; } =20 if ((sym->sym.st_shndx > SHN_UNDEF && @@ -511,7 +511,7 @@ static int read_symbols(struct elf *elf) sym->sec =3D find_section_by_index(elf, shndx); if (!sym->sec) { ERROR("couldn't find section for symbol %s", sym->name); - goto err; + return -1; } if (GELF_ST_TYPE(sym->sym.st_info) =3D=3D STT_SECTION) { sym->name =3D sym->sec->name; @@ -581,10 +581,6 @@ static int read_symbols(struct elf *elf) } =20 return 0; - -err: - free(sym); - return -1; } =20 static int mark_group_syms(struct elf *elf) --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D19B9264F83; Fri, 9 May 2025 20:17:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821873; cv=none; b=H0f4kMfJ5by0vWbGBZCiHAHPBW9LJojd69bOvM2dHd0RFuA4Nd0eXDBoNPYzO7OZ3modit2bZg8AJTxQ4JPb1I0/JwCofeQOwdOdBzHinGXRsriwxY08Dx0G0x9SNyu/b42C6Tc7iA0XKqBztWW9EC7rUDQj1fGaY71iMzj8FgE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821873; c=relaxed/simple; bh=dH9lJ5pVgRGXRU3nCJAoakjNV0irDXPbwo3dgXZoSp4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hu+E2wtQNWWFUCu1J+z8t9brasmT0jI5KBodwDrlWxjmD8XHPNsRWcNnQ16XnWr8a2rtoKtlQvuQ5z7ULAD70SXmIGTGXXPuXdAaF9p4i3tHU/TjDCUHDgVCe5Bq0mzKvkvFNI7Nip6dni2KAWHrV3dl7SQ0TCKSiIbJtzXiOp0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gRt8ixP3; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="gRt8ixP3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 33610C4CEEE; Fri, 9 May 2025 20:17:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821873; bh=dH9lJ5pVgRGXRU3nCJAoakjNV0irDXPbwo3dgXZoSp4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gRt8ixP3RHSOf74iwWLF6T/NcmRiNqWTZo7Z1Xel1lqzZmxtSnevF2w4gn3216suL qKUpQTijZcNK5Wg1M+p4yzC9BNQCh1k/Z+um3upi0z+PT2+1FDn8jcqKeQ/DMk5U0t CvJYVad0CKIjYIlQB/Oq3cT5sIaYsVnPhV83WU1GkHyvv5U2AH3WufvigKtKXHiAtM KsyreAZOqGkA6dHCdVQPCwpkTAk5kNK4wt/k51wSkJdFX1aNEZ7/fJ3dptQMtMwFZy BTmQXV0/94ChlH3+Tf8QSlkQKppIDlCmLx1JJ8wLsvNJt+rlgHHDdrAKkARVILp+s7 m6Win7eQNmH/w== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 14/62] objtool: Propagate elf_truncate_section() error in elf_write() Date: Fri, 9 May 2025 13:16:38 -0700 Message-ID: <57aaef73e092a0d539c07aba00e2063ea7124552.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Properly check and propagate the return value of elf_truncate_section() to avoid silent failures. Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index b009d9feed76..19e249f4783c 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -1307,7 +1307,6 @@ static int elf_truncate_section(struct elf *elf, stru= ct section *sec) for (;;) { /* get next data descriptor for the relevant section */ data =3D elf_getdata(s, data); - if (!data) { if (size) { ERROR("end of section data but non-zero size left\n"); @@ -1343,8 +1342,8 @@ int elf_write(struct elf *elf) =20 /* Update changed relocation sections and section headers: */ list_for_each_entry(sec, &elf->sections, list) { - if (sec->truncate) - elf_truncate_section(elf, sec); + if (sec->truncate && elf_truncate_section(elf, sec)) + return -1; =20 if (sec_changed(sec)) { s =3D elf_getscn(elf->elf, sec->idx); --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F2C09265CB9; Fri, 9 May 2025 20:17:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821875; cv=none; b=c2OCL1XTVrHeNwMj4WXOLe7IuQWrlKKOcwJ5C08p5f7ud/jh39mvQHqgcxAG9lorpoFxFtmNWucdDAsIsUXIVdD+omhz0PnordcGWXgNqdaZ8xY/FratBkJX7dM4LWylz2+lGYC0S+XovYL6vYbr5wMCLs/4KpNnCjLhRRlLMQg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821875; c=relaxed/simple; bh=QfBHWmIVnkYafDr60dzPf4Vjy/KCp+oTkW0957LIfng=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kbN9vrA8G/0a+PE5PuVRXpHug2wA0PFggqyo7Cta8athfrN7qGvCKEbicBssb4bInpSinhBjeSoIIy4jBJfmBCkXCWXAKQfpx4UdessFXGWbYoc74eDfnVUi8uRV3i+Wea4eMa/Hn8hRAUpjMHMtetHsWhCMI48fyRRj1LH9tIs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=OJvMAO3z; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="OJvMAO3z" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DB9E0C4CEEF; Fri, 9 May 2025 20:17:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821874; bh=QfBHWmIVnkYafDr60dzPf4Vjy/KCp+oTkW0957LIfng=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OJvMAO3zcihhCwssP6aTeWAnDn0ezcG7bxjjWGUmjAOOyykXwctuDaghCK6QMnAJf EtDYpfEQOA7DPUdd5AZyBvTQpqPm8TMJYSfJkcUmTLf9hzDrleWcywvm7s+FJw64GS /rzTP9qZS3S6bqlUDRzIRBMRrWeCWjRYaM7MAwmqa10q1H1adCI1/3ieqbSPlbVEer ofIPMQ1Zb0ja6i9bg8p2bH5qlodgaeT4u7byBYFUmFukVUxEXcxhHOL7dZ4tIaRuhf QFvPWdPOjRRm2wCr034SNxqIsd4WReQ8GgosWvX9/JVD3oBdQfqw8eHXeExc32vJYa Q+RgS340OSHSA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 15/62] objtool: Add empty symbols to the symbol tree again Date: Fri, 9 May 2025 13:16:39 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The following commit 5da6aea375cd ("objtool: Fix find_{symbol,func}_containing()") fixed the issue where overlapping symbols weren't getting sorted properly in the symbol tree. Therefore the workaround to skip adding empty symbols from the following commit a2e38dffcd93 ("objtool: Don't add empty symbols to the rbtree") is no longer needed. Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 19e249f4783c..a8a78b55d3ec 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -96,7 +96,8 @@ static inline unsigned long __sym_last(struct symbol *s) } =20 INTERVAL_TREE_DEFINE(struct symbol, node, unsigned long, __subtree_last, - __sym_start, __sym_last, static, __sym) + __sym_start, __sym_last, static inline __maybe_unused, + __sym) =20 #define __sym_for_each(_iter, _tree, _start, _end) \ for (_iter =3D __sym_iter_first((_tree), (_start), (_end)); \ @@ -440,13 +441,6 @@ static void elf_add_symbol(struct elf *elf, struct sym= bol *sym) list_add(&sym->list, entry); elf_hash_add(symbol, &sym->hash, sym->idx); elf_hash_add(symbol_name, &sym->name_hash, str_hash(sym->name)); - - /* - * Don't store empty STT_NOTYPE symbols in the rbtree. They - * can exist within a function, confusing the sorting. - */ - if (!sym->len) - __sym_remove(sym, &sym->sec->symbol_tree); } =20 static int read_symbols(struct elf *elf) --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BC2D126656C; Fri, 9 May 2025 20:17:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821875; cv=none; b=dHEqCjgbI/o+Hss2dm7A0YYLno9v/Rt4FSRMdI9jPAsL2WHKitstwDb+CmXNpN6OQYD/ebsK2ubTeYz2F4YEMJmOnPEE4G/1nOHSV1pPUEI87W4sg/eBuURityKD8/xOJairPyuM4YrIKe+6AhQo3dIlXmI36iO97bbvZrs7whs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821875; c=relaxed/simple; bh=YyD6KDvlcm2ljvEKZEc8fYvgEk6IvDo2PvpCUwTOJmE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nmofumJXfjKWU2vB+h8Dg8QvOB+dU1llgz7COU95i/Rilv77zVzPwxHYyXDp0Z7oVhtb+NjiD4eeViPJH3wiPyNro4v8lgDhWbKFcHa7YYmtvwvtykzuXfT1uhaaf4F79BSCeJzRBNrV4VBlAg518Ps5uHfSRztx0JIFtw67ovQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hg92T/Vg; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hg92T/Vg" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 920E2C4CEE9; Fri, 9 May 2025 20:17:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821875; bh=YyD6KDvlcm2ljvEKZEc8fYvgEk6IvDo2PvpCUwTOJmE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hg92T/VgT4yZHXxpKdOKJJ6R1KDniwxD7sZFosIXAdxZzsGFs6QF32pddr70S/Gsf DluZlRmmMnw7IIXMNJaul7m6DRKRI6E4ucbru3hTccafT/KI2upT766WBr2RaxF1FA G9Lb/doKrZQgH8tXQmfSSYdZxbNxQQh/qjbEu8ssYAgnschaaXslyhFL/1dh96YMO9 gSjscF8eLY9eNa+R7sKHko5uxEdfOe4F+xQ6gGTOSbR7EzIjeyzxO68bD52zDR3Cb/ v+afeearTstY2r2M7GepBdhXp7WL/QWGSL7736hn+oUhG6KFArrVtRB1ALBOvHx89l vBwZ5qmc4Fxlg== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 16/62] objtool: Fix interval tree insertion for zero-length symbols Date: Fri, 9 May 2025 13:16:40 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Zero-length symbols get inserted in the wrong spot. Fix that. Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index a8a78b55d3ec..c024937eb12a 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -92,7 +92,7 @@ static inline unsigned long __sym_start(struct symbol *s) =20 static inline unsigned long __sym_last(struct symbol *s) { - return s->offset + s->len - 1; + return s->offset + (s->len ? s->len - 1 : 0); } =20 INTERVAL_TREE_DEFINE(struct symbol, node, unsigned long, __subtree_last, --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F3C5F266571; Fri, 9 May 2025 20:17:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821876; cv=none; b=lFIt4JxRFp0VoeGPkyCqvFwj/mbBFtPvZt/PBbks+xkyYuXC5DRCrn2SQo3MsnTwekSwg1CMJh6yVB6HewQBXzYb6vMZbz3uuy6L3nfzSPO0lvd4Z3Mmw29Zdv8eiQAFjfpa2ertxLzaDTC4bd2pvYaPkdiA+rFJJoDCFXJzKkg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821876; c=relaxed/simple; bh=eyn64xsGzqTLQ6AHxWV/CsAkWUQ+4wmQ1jaSVqhPaww=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rdk4kVMRAfRAdFW6v8/GIjAycMzH4ZjORMna3r3FF0lVoclmhZJ+g06WhfizcY0V4sUXQK8PTt9gwNMidcePm0FbtXn7WlqyXMWkkrq61SbqUv9NnqQTGLeRATJv2Jk1bCDIbE7+1yziHVdAWo44U+uIF1Bux+dm3daV7kdsPGs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=r3fsQtlm; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="r3fsQtlm" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4DFE6C4CEF1; Fri, 9 May 2025 20:17:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821875; bh=eyn64xsGzqTLQ6AHxWV/CsAkWUQ+4wmQ1jaSVqhPaww=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=r3fsQtlmH6G+qIm9AK2vYC35+WtESG6CJNtRcyxGAAwc0AK0PwQO1vp6SF1gJg9sj ZNREa/t6MsS5n6flp8uJuFT6MKUjwG48ZWaMJu5yCniuJ4eoTLM6a8HyybBwLzKGaV 1GReDUg3iUeD1HTRlEEX9VDyowJlM2jxYNGRRsQrMeEuM/fdIojASz7z/v58cznhXV 7rOdZ9XwzSGS37IoPAl3sWYKL3tFH4e1obmrLPYkLFBYLZkRs+alKchSEQMUuHX03Y Ujz3VshZsyLhHxywL+nrCF/7xKaJPuOYI8ly2YSE/ys3IYIrq9dpduvz7n6TXJ/3sz DBZHZ87wrMssQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 17/62] objtool: Fix weak symbol detection Date: Fri, 9 May 2025 13:16:41 -0700 Message-ID: <78dc6f9015f7aa8e37b7ce3cebd1a3b899f93e38.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" find_symbol_hole_containing() fails to find a symbol hole (aka stripped weak symbol) if its section has no symbols before the hole. This breaks weak symbol detection if -ffunction-sections is enabled. Fix that by allowing the interval tree to contain section symbols, which are always at offset zero for a given section. Fixes a bunch of (-ffunction-sections) warnings like: vmlinux.o: warning: objtool: .text.__x64_sys_io_setup+0x10: unreachable i= nstruction Fixes: 4adb23686795 ("objtool: Ignore extra-symbol code") Signed-off-by: Josh Poimboeuf --- tools/include/linux/interval_tree_generic.h | 2 +- tools/objtool/elf.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/include/linux/interval_tree_generic.h b/tools/include/li= nux/interval_tree_generic.h index aaa8a0767aa3..c0ec9dbdfbaf 100644 --- a/tools/include/linux/interval_tree_generic.h +++ b/tools/include/linux/interval_tree_generic.h @@ -77,7 +77,7 @@ ITSTATIC void ITPREFIX ## _remove(ITSTRUCT *node, = \ * Cond2: start <=3D ITLAST(node) \ */ \ \ -static ITSTRUCT * \ +ITSTATIC ITSTRUCT * \ ITPREFIX ## _subtree_search(ITSTRUCT *node, ITTYPE start, ITTYPE last) = \ { \ while (true) { \ diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index c024937eb12a..d7fb3d0b05cf 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -109,7 +109,7 @@ struct symbol_hole { }; =20 /* - * Find !section symbol where @offset is after it. + * Find the last symbol before @offset. */ static int symbol_hole_by_offset(const void *key, const struct rb_node *no= de) { @@ -120,8 +120,7 @@ static int symbol_hole_by_offset(const void *key, const= struct rb_node *node) return -1; =20 if (sh->key >=3D s->offset + s->len) { - if (s->type !=3D STT_SECTION) - sh->sym =3D s; + sh->sym =3D s; return 1; } =20 @@ -428,7 +427,8 @@ static void elf_add_symbol(struct elf *elf, struct symb= ol *sym) sym->len =3D sym->sym.st_size; =20 __sym_for_each(iter, &sym->sec->symbol_tree, sym->offset, sym->offset) { - if (iter->offset =3D=3D sym->offset && iter->type =3D=3D sym->type) + if (iter->offset =3D=3D sym->offset && iter->type =3D=3D sym->type && + iter->len =3D=3D sym->len) iter->alias =3D sym; } =20 --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9E1502676CD; Fri, 9 May 2025 20:17:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821876; cv=none; b=W+WuJAu0W/Wo2nUsbNyrJh1ejn+++cvVhO/hPoL39thBjZQZIxSW87pE2IlJGvj/o8KHzo9zx0MH+Fh/Um56bylsrqiEVjqrXA1cFVibb/Iu/Gl2yuisPCx1TXRi/UBaN37930SEG/u3TPstuKylwpXP0QOXaNX8Ux4Z9mV8+a8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821876; c=relaxed/simple; bh=VqG6g//chpaS3lqzskCigvBXnHLMqfE7+a/jSGlD9vg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ANvuxjYWdhtMXdZSjaknxVrLBJmcy+8g0t4Bq4/hDnF4ONHoFqKCCLUK+XrW1kVtIm8NY9ON8CSICZspMpWtO95mk363V6TlkRwa0vt5J20n0MPZjlgZg3AWfKau2AKRWb76uQXyRGzDJ+mBjG4ywGdvoRqqEsSm4fcswUCXWH4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rMb7fGMp; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rMb7fGMp" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 007B7C4CEEE; Fri, 9 May 2025 20:17:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821876; bh=VqG6g//chpaS3lqzskCigvBXnHLMqfE7+a/jSGlD9vg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rMb7fGMpYwhyePF081JqcTo/4y8jWmBr5IW0ozT1/Jn080uC6Nj6OXhvwjchbxF5A 1G/Z1H5d9dklMfp2pYNJZkAE15gOuqKSloRB1FgbY7lK/Ve18HbvZTwttbEGPD2DMr XRri7hQvCT0CGqpey/D+KS2iCoy2lm3EjWOdIVa15+TXr0sQpsa9h2X76rLgG3BVCP f/YJVBW9rPYZxqEO2QY5+OMJ7zqNI84GyBwuTl9Pjtze3iS+/fcc2EC014yGXf7yWb j4D3aBCGjwA78/PcciWAzlZTN+TMXnaAOKgGYVjqRjNx2J+cT8jM/Fnc1jI/HHUNa2 HhQiApwzac5Qw== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 18/62] objtool: Fix x86 addend calculation Date: Fri, 9 May 2025 13:16:42 -0700 Message-ID: <8064f40394e9f0438a36f53f54e3b56f8e5b5365.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" On x86, arch_dest_reloc_offset() hardcodes the addend adjustment to four, but the actual adjustment depends on the relocation type. Fix that. Signed-off-by: Josh Poimboeuf --- tools/objtool/arch/loongarch/decode.c | 4 ++-- tools/objtool/arch/powerpc/decode.c | 4 ++-- tools/objtool/arch/x86/decode.c | 15 +++++++++++++-- tools/objtool/check.c | 13 ++++--------- tools/objtool/include/objtool/arch.h | 2 +- 5 files changed, 22 insertions(+), 16 deletions(-) diff --git a/tools/objtool/arch/loongarch/decode.c b/tools/objtool/arch/loo= ngarch/decode.c index b6fdc68053cc..330671d88c59 100644 --- a/tools/objtool/arch/loongarch/decode.c +++ b/tools/objtool/arch/loongarch/decode.c @@ -17,9 +17,9 @@ unsigned long arch_jump_destination(struct instruction *i= nsn) return insn->offset + (insn->immediate << 2); } =20 -unsigned long arch_dest_reloc_offset(int addend) +s64 arch_insn_adjusted_addend(struct instruction *insn, struct reloc *relo= c) { - return addend; + return reloc_addend(reloc); } =20 bool arch_pc_relative_reloc(struct reloc *reloc) diff --git a/tools/objtool/arch/powerpc/decode.c b/tools/objtool/arch/power= pc/decode.c index c851c51d4bd3..9b17885e6cba 100644 --- a/tools/objtool/arch/powerpc/decode.c +++ b/tools/objtool/arch/powerpc/decode.c @@ -14,9 +14,9 @@ int arch_ftrace_match(char *name) return !strcmp(name, "_mcount"); } =20 -unsigned long arch_dest_reloc_offset(int addend) +s64 arch_insn_adjusted_addend(struct instruction *insn, struct reloc *relo= c) { - return addend; + return reloc_addend(reloc); } =20 bool arch_callee_saved_reg(unsigned char reg) diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decod= e.c index 331b9a744410..771ad24e49ee 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -68,9 +68,20 @@ bool arch_callee_saved_reg(unsigned char reg) } } =20 -unsigned long arch_dest_reloc_offset(int addend) +s64 arch_insn_adjusted_addend(struct instruction *insn, struct reloc *relo= c) { - return addend + 4; + s64 addend =3D reloc_addend(reloc); + + switch (reloc_type(reloc)) { + case R_X86_64_PC32: + case R_X86_64_PLT32: + addend +=3D insn->offset + insn->len - reloc_offset(reloc); + break; + default: + break; + } + + return addend; } =20 unsigned long arch_jump_destination(struct instruction *insn) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 3a411064fa34..ea4e0facd21b 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1502,7 +1502,7 @@ static int add_jump_destinations(struct objtool_file = *file) dest_off =3D arch_jump_destination(insn); } else if (reloc->sym->type =3D=3D STT_SECTION) { dest_sec =3D reloc->sym->sec; - dest_off =3D arch_dest_reloc_offset(reloc_addend(reloc)); + dest_off =3D arch_insn_adjusted_addend(insn, reloc); } else if (reloc->sym->retpoline_thunk) { ret =3D add_retpoline_call(file, insn); if (ret) @@ -1672,7 +1672,7 @@ static int add_call_destinations(struct objtool_file = *file) } =20 } else if (reloc->sym->type =3D=3D STT_SECTION) { - dest_off =3D arch_dest_reloc_offset(reloc_addend(reloc)); + dest_off =3D arch_insn_adjusted_addend(insn, reloc); dest =3D find_call_destination(reloc->sym->sec, dest_off); if (!dest) { ERROR_INSN(insn, "can't find call dest symbol at %s+0x%lx", @@ -3348,7 +3348,7 @@ static bool pv_call_dest(struct objtool_file *file, s= truct instruction *insn) if (!reloc || strcmp(reloc->sym->name, "pv_ops")) return false; =20 - idx =3D (arch_dest_reloc_offset(reloc_addend(reloc)) / sizeof(void *)); + idx =3D (arch_insn_adjusted_addend(insn, reloc) / sizeof(void *)); =20 if (file->pv_ops[idx].clean) return true; @@ -4396,12 +4396,7 @@ static int validate_ibt_insn(struct objtool_file *fi= le, struct instruction *insn reloc_offset(reloc) + 1, (insn->offset + insn->len) - (reloc_offset(reloc) + 1))) { =20 - off =3D reloc->sym->offset; - if (reloc_type(reloc) =3D=3D R_X86_64_PC32 || - reloc_type(reloc) =3D=3D R_X86_64_PLT32) - off +=3D arch_dest_reloc_offset(reloc_addend(reloc)); - else - off +=3D reloc_addend(reloc); + off =3D reloc->sym->offset + arch_insn_adjusted_addend(insn, reloc); =20 dest =3D find_insn(file, reloc->sym->sec, off); if (!dest) diff --git a/tools/objtool/include/objtool/arch.h b/tools/objtool/include/o= bjtool/arch.h index 01ef6f415adf..cd1776c35b13 100644 --- a/tools/objtool/include/objtool/arch.h +++ b/tools/objtool/include/objtool/arch.h @@ -83,7 +83,7 @@ bool arch_callee_saved_reg(unsigned char reg); =20 unsigned long arch_jump_destination(struct instruction *insn); =20 -unsigned long arch_dest_reloc_offset(int addend); +s64 arch_insn_adjusted_addend(struct instruction *insn, struct reloc *relo= c); =20 const char *arch_nop_insn(int len); const char *arch_ret_insn(int len); --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B8DCD25F79A; Fri, 9 May 2025 20:17:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821877; cv=none; b=uh6DJOrufkg93bEN5/PKFKnlhT+MN5yRiRSpg8WfOT7oVhwVHgi0RYkZDMQMVHHzAHaLEruoiPsTIbtBgMR3YvI2CHsqBln/juX1R0nCKiV5HlUiNVsrSztUFjczMDQZ9z8T2Gspd/hKKnwZfpmFor5eaoUO9DZ4KwnTtTYZjZ8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821877; c=relaxed/simple; bh=zsi/UkUHfX+HCgon4iWgQ8WWU+oyoaWZoqhN5WSCmrQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XRhPzikHWJQkHf97GhtN0tg7kGlbPlVJFRI2um5LKD9MhHK0GVy3X2eBia25SLfj9lYQexkaNbS0mIvEkftsZu2n6Mgmzo8Ol/Ir8WB3UF7IRxsB2bjx8ygR4IGsGpY4EvREuCOOvbiGLib56Yvssx8JTJPUvdwgsUQObtbTL7A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=onFRhoJ/; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="onFRhoJ/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A80A4C4CEF1; Fri, 9 May 2025 20:17:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821877; bh=zsi/UkUHfX+HCgon4iWgQ8WWU+oyoaWZoqhN5WSCmrQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=onFRhoJ/ckckXI82v9MLqVOEjPWlNq70aypBmjgCPSawbv26A8LQadR69+VsES1IM /g7S63r4lHVzChcTJVLet/YXDChALrch2F4MlyEJTQ/EOieLGhaBZ6587yVy9BTBjh aZCL16rDOF4kYI955fiuC7+ntGmR9z4QsyVCqiCwqFRHg9OWkdBLgIUyJuuzPH1NRr Z5i+xs/vFidB+oZzkmgxmBTNqwAzcD0MGXbtPiB4ldANpr74F+vuteV08ZZLEDjLkY 7HNiNEav7n5nKc4RwCseVIgXrwnfLUeh6d9IPo7L1afoi662Z3/OLISNxKz1zGZ44y EaPvhiZEbISNg== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 19/62] objtool: Fix __pa_symbol() relocation handling Date: Fri, 9 May 2025 13:16:43 -0700 Message-ID: <5d629e496710097c648126f3267d769ca3419baf.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" __pa_symbol() generates a relocation which refers to a physical address. Convert it to back its virtual form before calculating the addend. Signed-off-by: Josh Poimboeuf --- tools/objtool/arch/x86/decode.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decod= e.c index 771ad24e49ee..7bb8bad22b8a 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -68,6 +68,17 @@ bool arch_callee_saved_reg(unsigned char reg) } } =20 +/* Undo the effects of __pa_symbol() if necessary */ +static unsigned long phys_to_virt(unsigned long pa) +{ + s64 va =3D pa; + + if (va > 0) + va &=3D ~(0x80000000); + + return va; +} + s64 arch_insn_adjusted_addend(struct instruction *insn, struct reloc *relo= c) { s64 addend =3D reloc_addend(reloc); @@ -81,7 +92,7 @@ s64 arch_insn_adjusted_addend(struct instruction *insn, s= truct reloc *reloc) break; } =20 - return addend; + return phys_to_virt(addend); } =20 unsigned long arch_jump_destination(struct instruction *insn) --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7AE90267F73; Fri, 9 May 2025 20:17:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821878; cv=none; b=DinlQ6CchqgVaZJPW9i9qh9YK283xF7IpwrbZRE1XjBg8GjmjTPuQXtY+FYW7WrnmP3QpGRbO1Aja9xXXJ2lo/5eFqrddC7JF6SJjGZ36UpxcmG/SFAPNOh2uozDU12q+O8ledxUWufc2EOWaiqZPjVVRQOn4E/eKJzJE0FirkE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821878; c=relaxed/simple; bh=L1LqTskq/WOpKf8Dm/MOhrYquHsVHeNDKUmrpvXx9rA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tkoyvokrGfLM4KLxTPf9ph0EesCUR+j/5RD63XWwdJu+ZKF8tuzwenGGRV9DalRY+EMndN0N+r7MBHYluf0azXCJsqrAa49YbtmHcJMC31gbSlKcTVGi4gebHCEBhoKZcdYbUrkAQJa6UHbkA12EoYTkbOxbUWD4MWTrtyhbID8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=IjanlGXJ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="IjanlGXJ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5E06BC4CEE4; Fri, 9 May 2025 20:17:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821877; bh=L1LqTskq/WOpKf8Dm/MOhrYquHsVHeNDKUmrpvXx9rA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IjanlGXJ2723P2kYBrNdN6PQj57AwRvcoUta0VR3ZBDAKvFaSsR0AwCblrWWA1iyB kVMwhJG5Nefx9x3YRW9YKhKzdq2cX9Nx92ndCHpupY914UDUHUG76d+7k6byS8bjyS j7ymYgApHE0Q9HLoOnWnqJYLLcZCfkuLTBiYn6GXYeG0HA4AWNs3NrFkk4H+dgakqc XBgLIlLWjyRVGlkGtlzlmWiwbYZkU3GBuTJs90Viti4DIqrRYaaZ7+Ok+8oZQZ2IuE jX02vu0fatfabbubS948O+TCyo0a9BxbhLHDEVy0sOnI5lEvIoTgGZqZGkb1s2P/dV 2/o3ezUS73LHA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 20/62] objtool: Fix "unexpected end of section" warning for alternatives Date: Fri, 9 May 2025 13:16:44 -0700 Message-ID: <7d99e58d5a0bbd46ccfe4ece125c72815e99e205.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Due to the short circuiting logic in next_insn_to_validate(), control flow may silently transition from .altinstr_replacement to .text without a corresponding nested call to validate_branch(). As a result the validate_branch() 'sec' variable doesn't get reinitialized, which can trigger a confusing "unexpected end of section" warning which blames .altinstr_replacement rather than the offending fallthrough function. Fix that by not caching the section. There's no point in doing that anyway. Signed-off-by: Josh Poimboeuf --- tools/objtool/check.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index ea4e0facd21b..53793b9ea974 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -3545,15 +3545,12 @@ static int validate_branch(struct objtool_file *fil= e, struct symbol *func, { struct alternative *alt; struct instruction *next_insn, *prev_insn =3D NULL; - struct section *sec; u8 visited; int ret; =20 if (func && func->ignore) return 0; =20 - sec =3D insn->sec; - while (1) { next_insn =3D next_insn_to_validate(file, insn); =20 @@ -3791,7 +3788,7 @@ static int validate_branch(struct objtool_file *file,= struct symbol *func, =20 WARN("%s%sunexpected end of section %s", func ? func->name : "", func ? "(): " : "", - sec->name); + insn->sec->name); return 1; } =20 --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 17E4D268C49; Fri, 9 May 2025 20:17:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821879; cv=none; b=LWI0uWNs4nKN8UxhwD+v0TvYCZRiyNLOLUKuM+ebWd8EDJkOvcLinW3iQ72SFz/8h/u2LqwPKECCxX3ADJJ+hhYyuOzVZJbnchTVORN1fwxh8f8uGdqOczpV4jdAL0dWBAS8XC9lFrA3jpYN6C0eRNjLt4P95FTECcUMm4C1Jmg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821879; c=relaxed/simple; bh=iZPpW5B7vyUX5hbIoVsgCqQOfefHFHuE1LOhfhu9YJA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=X8++w96U9lR7tipf738bfWTFPDjB8PPXHBGujrG7qPAXUyMO2oJSLnB793RptkNgkK6rv69Yytcq18NXkmftsqJRoaqIzFxViUB5tDWz5WMB3REBhb3bBc84ijq7fYNZmG6JTgjnVm9iquk/4WsUhrql65O1FYMtpmb7WfXm5ig= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KEBTdoAC; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="KEBTdoAC" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1425AC4CEEE; Fri, 9 May 2025 20:17:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821878; bh=iZPpW5B7vyUX5hbIoVsgCqQOfefHFHuE1LOhfhu9YJA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KEBTdoACkOPyw6/6J7N1MGQEj5amg39fjHY3msAcm8rc613gunwTa+LTvCWN4g2Oz NARMK2sY+ijTaTM8LLGXiePQCpBv1FRR2sdxjwaoYxndVaTKtRyJUu57NZLo4XIG9K 3w4EFuNLWvt87o9nNeCaap5TSJ1wnjxmwPk1Yqcgzxlscn6FCiBRF7EJNnu0qv2wKK CTFMDnehrWHNiEulTaHLG0HgZYs9wu2AvelEnq88vRYExzc+Cl2OGBwKuhvJTNHZck Y+f3x8iFZz1mJluB9VRkw0UXbddYyBPfkDdBYnBIaBMMaA+R1fgkj+r3OrzTB7GYem RW2o+QRxi/rsA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 21/62] objtool: Check for missing annotation entries in read_annotate() Date: Fri, 9 May 2025 13:16:45 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a sanity check to make sure none of the relocations for the .discard.annotate_insn section have gone missing. Signed-off-by: Josh Poimboeuf --- tools/objtool/check.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 53793b9ea974..0cdc2fc85439 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -2314,6 +2314,11 @@ static int read_annotate(struct objtool_file *file, sec->sh.sh_entsize =3D 8; } =20 + if (sec_num_entries(sec) !=3D sec_num_entries(sec->rsec)) { + ERROR("bad .discard.annotate_insn section: missing relocs"); + return -1; + } + for_each_reloc(sec->rsec, reloc) { type =3D *(u32 *)(sec->data->d_buf + (reloc_idx(reloc) * sec->sh.sh_ents= ize) + 4); =20 --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EA25526980E; Fri, 9 May 2025 20:17:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821880; cv=none; b=OvtuwwUTyUq5gxkCvl0ciy/OwGJtALiA0BY9ALwSArmKGukDsb10dmn4TrsJMx1f6Rk/dqvcnhUY2VuRM0XrnAQJ9K5OsC5BbVJcRp/QLMssg1cCh7fCtukaGEQPNZUDCxzLzuU/0VA0UCv+hrvh0HlArZKogmFEiFrSmI8cTOk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821880; c=relaxed/simple; bh=6A4iq+crR8Jurs2zPxbRg8Rnbuntyd2oRV/t83dZ+Bo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=urxwa3LN5EFC/TrdTrUMkNZZMii1uZi6SBB7vtGycJ2DSBPq5ksKPWNQVB3O4NCAsnbVMAHtJWvIEbHWYgC2pWsvSfy+8gnMBhMWbFVpuQJ2Gx1RUT3PgcWyzFwCR0HeP9fn/yBxidbcZsXwdZtFsFs+syobh73FuVBNyJHuJ/g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lQ03SHtK; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="lQ03SHtK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C744DC4CEF1; Fri, 9 May 2025 20:17:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821879; bh=6A4iq+crR8Jurs2zPxbRg8Rnbuntyd2oRV/t83dZ+Bo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lQ03SHtKVVm46U+jyHySD6743IwOUXcFRYhE9cSw0E5wprG7zsw7zYtZGPUCYUaV2 oE+WN/yLBiJ+hwcxyJgNP39FU4N4lyExQw3Z/IpztANYWOmtoiKQvx2SYYG++e2amg ISNsvk9sPdW1Qo0WmHCIsoUWjz8vngYrdweEGkP+KZS+RYAMc0EXOPmut0J3wI6uiY q+R8dskfHheJajNmyTxhfGECwqv9poL4PBsfmtuXFZKW4fQUUgMAprEBgwnDaxDAAP pWT29n+nEOLf1ZLHtLxQlM3ulAPAzEtcwWyM3soKkjY6Kqlkn7MXX1hWt6JaNwP8vI ENiaJ0MWj0PZQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 22/62] objtool: Const string cleanup Date: Fri, 9 May 2025 13:16:46 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Use 'const char *' where applicable. Signed-off-by: Josh Poimboeuf --- tools/objtool/arch/loongarch/decode.c | 2 +- tools/objtool/arch/powerpc/decode.c | 2 +- tools/objtool/arch/x86/decode.c | 2 +- tools/objtool/elf.c | 6 +++--- tools/objtool/include/objtool/arch.h | 2 +- tools/objtool/include/objtool/elf.h | 6 +++--- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tools/objtool/arch/loongarch/decode.c b/tools/objtool/arch/loo= ngarch/decode.c index 330671d88c59..7b38718d782a 100644 --- a/tools/objtool/arch/loongarch/decode.c +++ b/tools/objtool/arch/loongarch/decode.c @@ -7,7 +7,7 @@ #include #include =20 -int arch_ftrace_match(char *name) +int arch_ftrace_match(const char *name) { return !strcmp(name, "_mcount"); } diff --git a/tools/objtool/arch/powerpc/decode.c b/tools/objtool/arch/power= pc/decode.c index 9b17885e6cba..d4cb02120a6b 100644 --- a/tools/objtool/arch/powerpc/decode.c +++ b/tools/objtool/arch/powerpc/decode.c @@ -9,7 +9,7 @@ #include #include =20 -int arch_ftrace_match(char *name) +int arch_ftrace_match(const char *name) { return !strcmp(name, "_mcount"); } diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decod= e.c index 7bb8bad22b8a..cdf385e54c69 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -23,7 +23,7 @@ #include #include =20 -int arch_ftrace_match(char *name) +int arch_ftrace_match(const char *name) { return !strcmp(name, "__fentry__"); } diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index d7fb3d0b05cf..2ea6d591c3c2 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -853,7 +853,7 @@ elf_create_section_symbol(struct elf *elf, struct secti= on *sec) return sym; } =20 -static int elf_add_string(struct elf *elf, struct section *strtab, char *s= tr); +static int elf_add_string(struct elf *elf, struct section *strtab, const c= har *str); =20 struct symbol * elf_create_prefix_symbol(struct elf *elf, struct symbol *orig, long size) @@ -1086,7 +1086,7 @@ struct elf *elf_open_read(const char *name, int flags) return NULL; } =20 -static int elf_add_string(struct elf *elf, struct section *strtab, char *s= tr) +static int elf_add_string(struct elf *elf, struct section *strtab, const c= har *str) { Elf_Data *data; Elf_Scn *s; @@ -1111,7 +1111,7 @@ static int elf_add_string(struct elf *elf, struct sec= tion *strtab, char *str) return -1; } =20 - data->d_buf =3D str; + data->d_buf =3D strdup(str); data->d_size =3D strlen(str) + 1; data->d_align =3D 1; =20 diff --git a/tools/objtool/include/objtool/arch.h b/tools/objtool/include/o= bjtool/arch.h index cd1776c35b13..07729a240159 100644 --- a/tools/objtool/include/objtool/arch.h +++ b/tools/objtool/include/objtool/arch.h @@ -71,7 +71,7 @@ struct stack_op { =20 struct instruction; =20 -int arch_ftrace_match(char *name); +int arch_ftrace_match(const char *name); =20 void arch_initial_func_cfi_state(struct cfi_init_state *state); =20 diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index 0a2fa3ac0079..0f9adfe8e852 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -40,7 +40,7 @@ struct section { struct section *base, *rsec; struct symbol *sym; Elf_Data *data; - char *name; + const char *name; int idx; bool _changed, text, rodata, noinstr, init, truncate; struct reloc *relocs; @@ -53,7 +53,7 @@ struct symbol { struct elf_hash_node name_hash; GElf_Sym sym; struct section *sec; - char *name; + const char *name; unsigned int idx, len; unsigned long offset; unsigned long __subtree_last; @@ -87,7 +87,7 @@ struct elf { GElf_Ehdr ehdr; int fd; bool changed; - char *name; + const char *name; unsigned int num_files; struct list_head sections; unsigned long num_relocs; --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DD77726A0CC; Fri, 9 May 2025 20:18:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821880; cv=none; b=NbTYR0Q0PlA6DGnmN4sJhzicRfdMzWYP28sDCitPUjFqCPUsdt14XLVJbHLJ+MzY+sMI7UXfw40CC0NjhUgohh/3y8p50YjxY/pWDzlVM18rJEqz+6YN7vQoDPpD0M3we8VdbgDsSOQVXoZpMq3FjXcAbdem3+k9vzozix/ME28= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821880; c=relaxed/simple; bh=ATnjVeDvFHZYfIgFa9Cjs6eAsIVU/U1FXzQfK6EwYZs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AhpkbAqSKIi0gXoprxTR3OjGkstAhcCiwTxNlmBxWJD6TwSo46bO/SnbFGfnF+JfgLK4ITNUoN4XQa7SpsQ7TYjCkgoHnw5i8wtZLrI6wym7Bh+FKDPSnM3gxBlrJNqKsDnn/x6QTQ+h1/i0XhkoY3JKJqI+4AVTP4rxT32o7Us= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Q4lfrQ4s; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Q4lfrQ4s" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7EC73C4CEF0; Fri, 9 May 2025 20:17:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821880; bh=ATnjVeDvFHZYfIgFa9Cjs6eAsIVU/U1FXzQfK6EwYZs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Q4lfrQ4sn+DkONUip8khR8lUOW1y9hSoHIu9c5VDGJJUVNgQvSKnMP2srG/rDOeDB X9dIVQezhuWHks6PBRF2Sq05D+QnL/Ga+ZsdOKnb4OkPu6PFa2W9YIq73CUB+wiIAo AY9EPb9WfNdw6XOOwPSEaAwkKFOrtdp+bUCiUYxHN9lohzQHssvTF+tnVyM6x2SlGP ENVwTrwbHvwGSkWKtSXmFjL3OLcm60mVPn6ERF0Z2F1IHJPAHyRY5nKGjII2SRLvbS WVasM5D+j30kiPLZ7gwqKYOf7usw7wEoqZcA685A+WQ3NoWpVGZvx0zVgalG5h+ALM AZBKRxFvpdUSQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 23/62] objtool: Clean up compiler flag usage Date: Fri, 9 May 2025 13:16:47 -0700 Message-ID: <23a069d2e00c6b0c9305f05282bad7ea6f8bed07.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" KBUILD_HOSTCFLAGS and KBUILD_HOSTLDFLAGS aren't defined when objtool is built standalone. Also, the EXTRA_WARNINGS flags are rather arbitrary. Make things simpler and more consistent by specifying compiler flags explicitly and tweaking the warnings. Also make a few code tweaks to make the new warnings happy. Signed-off-by: Josh Poimboeuf --- tools/objtool/Makefile | 15 ++++++++++----- tools/objtool/check.c | 4 ++-- tools/objtool/elf.c | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile index 8c20361dd100..fc82d47f2b9a 100644 --- a/tools/objtool/Makefile +++ b/tools/objtool/Makefile @@ -23,6 +23,11 @@ LIBELF_LIBS :=3D $(shell $(HOSTPKG_CONFIG) libelf --lib= s 2>/dev/null || echo -lel =20 all: $(OBJTOOL) =20 +WARNINGS :=3D -Werror -Wall -Wextra -Wmissing-prototypes \ + -Wmissing-declarations -Wwrite-strings \ + -Wno-implicit-fallthrough -Wno-sign-compare \ + -Wno-unused-parameter + INCLUDES :=3D -I$(srctree)/tools/include \ -I$(srctree)/tools/include/uapi \ -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi \ @@ -30,11 +35,11 @@ INCLUDES :=3D -I$(srctree)/tools/include \ -I$(srctree)/tools/objtool/include \ -I$(srctree)/tools/objtool/arch/$(SRCARCH)/include \ -I$(LIBSUBCMD_OUTPUT)/include -# Note, EXTRA_WARNINGS here was determined for CC and not HOSTCC, it -# is passed here to match a legacy behavior. -WARNINGS :=3D $(EXTRA_WARNINGS) -Wno-switch-default -Wno-switch-enum -Wno-= packed -Wno-nested-externs -OBJTOOL_CFLAGS :=3D -Werror $(WARNINGS) $(KBUILD_HOSTCFLAGS) -g $(INCLUDES= ) $(LIBELF_FLAGS) -OBJTOOL_LDFLAGS :=3D $(LIBELF_LIBS) $(LIBSUBCMD) $(KBUILD_HOSTLDFLAGS) + +OBJTOOL_CFLAGS :=3D -std=3Dgnu11 -fomit-frame-pointer -O2 -g \ + $(WARNINGS) $(INCLUDES) $(LIBELF_FLAGS) $(HOSTCFLAGS) + +OBJTOOL_LDFLAGS :=3D $(LIBSUBCMD) $(LIBELF_LIBS) $(HOSTLDFLAGS) =20 # Allow old libelf to be used: elfshdr :=3D $(shell echo '$(pound)include ' | $(HOSTCC) $(OBJTO= OL_CFLAGS) -x c -E - 2>/dev/null | grep elf_getshdr) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 0cdc2fc85439..5e62d3ce3cc6 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -459,7 +459,7 @@ static int decode_instructions(struct objtool_file *fil= e) =20 for (offset =3D 0; offset < sec->sh.sh_size; offset +=3D insn->len) { if (!insns || idx =3D=3D INSN_CHUNK_MAX) { - insns =3D calloc(sizeof(*insn), INSN_CHUNK_SIZE); + insns =3D calloc(INSN_CHUNK_SIZE, sizeof(*insn)); if (!insns) { ERROR_GLIBC("calloc"); return -1; @@ -608,7 +608,7 @@ static int init_pv_ops(struct objtool_file *file) return 0; =20 nr =3D sym->len / sizeof(unsigned long); - file->pv_ops =3D calloc(sizeof(struct pv_state), nr); + file->pv_ops =3D calloc(nr, sizeof(struct pv_state)); if (!file->pv_ops) { ERROR_GLIBC("calloc"); return -1; diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 2ea6d591c3c2..c27edeed2dd0 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -736,7 +736,7 @@ static int elf_update_symbol(struct elf *elf, struct se= ction *symtab, } =20 /* setup extended section index magic and write the symbol */ - if ((shndx >=3D SHN_UNDEF && shndx < SHN_LORESERVE) || is_special_shndx) { + if (shndx < SHN_LORESERVE || is_special_shndx) { sym->sym.st_shndx =3D shndx; if (!shndx_data) shndx =3D 0; --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7134E25F7A2; Fri, 9 May 2025 20:18:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821881; cv=none; b=cMlZ01sA6apE3oPH56XveKeR5hiz7wSSGmaaOBP2sA3MLsfS4UBy7QbaFOlSuUpEM75UjjUZwivXxljpdjfhIs2fWCXJftNFv9xQtoNbLvx3Q3YjxtyTlHAXf4C0yvbXo4MHTvKhSey1stjvj/rowQjI5SYLoBS75VS3GjfbnHk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821881; c=relaxed/simple; bh=zUNMQu1kVpk4KDqVdNxQAeQ0l+ZQ+8XZPtXWEdwjJGA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=eotE6G/KS53IMu3WbrM9+Cy8zql8ATd1z2+HLEfbYk8Bg5P9WogcRAJqee0pV8z15ZCkaLQAGRq/DGOy2Jlnp+aa0aBBtjwA5QOwFn5Ei6QZpFM1y78/mZuH7odhDLwH38bj226TPcmCgvXw/Fvh9GkVZTxMzfCP2mxqGFONKKs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=L1qAnbxk; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="L1qAnbxk" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6E1DAC4CEEE; Fri, 9 May 2025 20:18:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821881; bh=zUNMQu1kVpk4KDqVdNxQAeQ0l+ZQ+8XZPtXWEdwjJGA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=L1qAnbxkYpsWxUom8K6GZrD6a5lUqxLrVEKxamEfM54xuz/4ZfEkO2P8Ew/tTT0W3 ScZsgVHBegkJW4LgVwYPZCRlmqoFfT+sV/7dd7DXuDy7ch9PlpTZjNr8qi6iJweArJ FAT74062IIuFxYX6lAMh4UM6buLnpiMUeYFK9lgDTWlaeKjboxCNb3GRrjbHt6+tRD DwZXKOIfal+R8qutYevbtkZOls47f5J9bNMNIi/P8mp/3o5aC3b1S0rAm6vCE1RKRf pmr5xUrFOyEyU/QI3hmOuyU9lP6PB6ESnBxkB3PAkB2AH4OEW1mnMzwxPA+MxZxVhy k9lwgQXxcWDCQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 24/62] objtool: Remove .parainstructions reference Date: Fri, 9 May 2025 13:16:48 -0700 Message-ID: <07c7b78e8589731fd808897bb67c8252765b3fa4.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The .parainstructions section no longer exists since the following commit: 60bc276b129e ("x86/paravirt: Switch mixed paravirt/alternative calls to a= lternatives"). Remove the reference to it. Signed-off-by: Josh Poimboeuf --- tools/objtool/check.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 5e62d3ce3cc6..8a87c38516fc 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -4468,7 +4468,6 @@ static int validate_ibt(struct objtool_file *file) !strcmp(sec->name, ".altinstructions") || !strcmp(sec->name, ".ibt_endbr_seal") || !strcmp(sec->name, ".orc_unwind_ip") || - !strcmp(sec->name, ".parainstructions") || !strcmp(sec->name, ".retpoline_sites") || !strcmp(sec->name, ".smp_locks") || !strcmp(sec->name, ".static_call_sites") || --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8F30226FA42; Fri, 9 May 2025 20:18:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821882; cv=none; b=c3I0T9BlbgHP3DmRzj/kc17mhrraf4foZQ7ERvLa9c2MTlyG7X3ffrNAWXivqVw2oRRn2y6xxJ3bd9HKjVdHKIQjzDcWunjIH3r3LO+UmoxRinGM+BuKUXJOpoW4GnsL7tIuYqO79cEkhj9mZdB1hfmiU5P4A+S2O4tO6lehpDc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821882; c=relaxed/simple; bh=30eLE6xSDMB9ljZcmYDvILgYPcifP1so4H1h7z0aDvg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=axu6/9dHTQ/00/XjAKb5LsTyomjlt6g/9n+cEpgB8x1QtSRfqavTHaNGAuSe6AtyJJVdWoV5aUXaaQuhgKIuMnHu6uM8aSj6y/zZDpSzX+wATJTw4tWdcVTsiHfuLQTQQYUH8Ov0uDj9y+uKO2KFlKQSoGWA6JiwMhT4jjJIOqk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RCjDocGY; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="RCjDocGY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8C8DAC4CEEF; Fri, 9 May 2025 20:18:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821882; bh=30eLE6xSDMB9ljZcmYDvILgYPcifP1so4H1h7z0aDvg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RCjDocGY6wtU7QuY9SLLU+3LX6HKM455N3xV53/lxn2oBgMRRdjGR4uI4LEyf17+E bW/sjjry87Jwv+4zkfPKL0FIOdAzLOEueOABo8njXXQuiWJ2S/gTAJOyW58CvdSktm Ugmzn4xbX1KIbroGkfv9MMHfKVgnNOivMn7uzdWpP3f53jHfCafqKDwRpdlNiH4l/g bx4cjWNjGcn65Vwl/4sxWy4YyfT23J4ksxBc2c66LMuU2vNjvepZLP7otUpdpu1wqm D+tBM9cGVJjRpi8RzrswdPNSYLzOx4DPpP1o/Nr3wK4zY0oaHsuI/gJd0DOoc/bi7Y 1eki/ALcxwbRw== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 25/62] objtool: Convert elf iterator macros to use 'struct elf' Date: Fri, 9 May 2025 13:16:49 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 'struct objtool_file' is specific to the check code and doesn't belong in the elf code which is supposed to be objtool_file-agnostic. Convert the elf iterator macros to use 'struct elf' instead. Signed-off-by: Josh Poimboeuf --- tools/objtool/check.c | 22 +++++++++++----------- tools/objtool/include/objtool/elf.h | 8 ++++---- tools/objtool/orc_gen.c | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 8a87c38516fc..c6884620e49d 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -106,7 +106,7 @@ static struct instruction *prev_insn_same_sym(struct ob= jtool_file *file, #define for_each_insn(file, insn) \ for (struct section *__sec, *__fake =3D (struct section *)1; \ __fake; __fake =3D NULL) \ - for_each_sec(file, __sec) \ + for_each_sec(file->elf, __sec) \ sec_for_each_insn(file, __sec, insn) =20 #define func_for_each_insn(file, func, insn) \ @@ -429,7 +429,7 @@ static int decode_instructions(struct objtool_file *fil= e) struct instruction *insn; int ret; =20 - for_each_sec(file, sec) { + for_each_sec(file->elf, sec) { struct instruction *insns =3D NULL; u8 prev_len =3D 0; u8 idx =3D 0; @@ -859,7 +859,7 @@ static int create_cfi_sections(struct objtool_file *fil= e) } =20 idx =3D 0; - for_each_sym(file, sym) { + for_each_sym(file->elf, sym) { if (sym->type !=3D STT_FUNC) continue; =20 @@ -875,7 +875,7 @@ static int create_cfi_sections(struct objtool_file *fil= e) return -1; =20 idx =3D 0; - for_each_sym(file, sym) { + for_each_sym(file->elf, sym) { if (sym->type !=3D STT_FUNC) continue; =20 @@ -2165,7 +2165,7 @@ static int add_jump_table_alts(struct objtool_file *f= ile) if (!file->rodata) return 0; =20 - for_each_sym(file, func) { + for_each_sym(file->elf, func) { if (func->type !=3D STT_FUNC) continue; =20 @@ -2471,7 +2471,7 @@ static int classify_symbols(struct objtool_file *file) { struct symbol *func; =20 - for_each_sym(file, func) { + for_each_sym(file->elf, func) { if (func->type =3D=3D STT_NOTYPE && strstarts(func->name, ".L")) func->local_label =3D true; =20 @@ -2516,7 +2516,7 @@ static void mark_rodata(struct objtool_file *file) * * .rodata.str1.* sections are ignored; they don't contain jump tables. */ - for_each_sec(file, sec) { + for_each_sec(file->elf, sec) { if ((!strncmp(sec->name, ".rodata", 7) && !strstr(sec->name, ".str1.")) || !strncmp(sec->name, ".data.rel.ro", 12)) { @@ -4178,7 +4178,7 @@ static int add_prefix_symbols(struct objtool_file *fi= le) struct section *sec; struct symbol *func; =20 - for_each_sec(file, sec) { + for_each_sec(file->elf, sec) { if (!(sec->sh.sh_flags & SHF_EXECINSTR)) continue; =20 @@ -4270,7 +4270,7 @@ static int validate_functions(struct objtool_file *fi= le) struct section *sec; int warnings =3D 0; =20 - for_each_sec(file, sec) { + for_each_sec(file->elf, sec) { if (!(sec->sh.sh_flags & SHF_EXECINSTR)) continue; =20 @@ -4449,7 +4449,7 @@ static int validate_ibt(struct objtool_file *file) for_each_insn(file, insn) warnings +=3D validate_ibt_insn(file, insn); =20 - for_each_sec(file, sec) { + for_each_sec(file->elf, sec) { =20 /* Already done by validate_ibt_insn() */ if (sec->sh.sh_flags & SHF_EXECINSTR) @@ -4610,7 +4610,7 @@ static void disas_warned_funcs(struct objtool_file *f= ile) struct symbol *sym; char *funcs =3D NULL, *tmp; =20 - for_each_sym(file, sym) { + for_each_sym(file->elf, sym) { if (sym->warned) { if (!funcs) { funcs =3D malloc(strlen(sym->name) + 1); diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index 0f9adfe8e852..fcea9338c687 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -324,16 +324,16 @@ static inline void set_sym_next_reloc(struct reloc *r= eloc, struct reloc *next) reloc->_sym_next_reloc =3D (unsigned long)next | bit; } =20 -#define for_each_sec(file, sec) \ - list_for_each_entry(sec, &file->elf->sections, list) +#define for_each_sec(elf, sec) \ + list_for_each_entry(sec, &elf->sections, list) =20 #define sec_for_each_sym(sec, sym) \ list_for_each_entry(sym, &sec->symbol_list, list) =20 -#define for_each_sym(file, sym) \ +#define for_each_sym(elf, sym) \ for (struct section *__sec, *__fake =3D (struct section *)1; \ __fake; __fake =3D NULL) \ - for_each_sec(file, __sec) \ + for_each_sec(elf, __sec) \ sec_for_each_sym(__sec, sym) =20 #define for_each_reloc(rsec, reloc) \ diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c index 922e6aac7cea..6eff3d6a125c 100644 --- a/tools/objtool/orc_gen.c +++ b/tools/objtool/orc_gen.c @@ -57,7 +57,7 @@ int orc_create(struct objtool_file *file) =20 /* Build a deduplicated list of ORC entries: */ INIT_LIST_HEAD(&orc_list); - for_each_sec(file, sec) { + for_each_sec(file->elf, sec) { struct orc_entry orc, prev_orc =3D {0}; struct instruction *insn; bool empty =3D true; --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5227E270556; Fri, 9 May 2025 20:18:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821883; cv=none; b=Y/IAt4+oN/JaI4b6iNjO7U+IEyHpNU9QW5NOqf5T6/XsdbWwXuvwpz2SlUGYKYlkbTDioHieefM85hQN5PRWsmFRa/pGeW3EPSSJ154jU81Q4U8xwcIQAoYd6PIbE0bJv5/Fj4FiWAzrBfOw3voLXeHYr3A/0hX92JIDSwfAkQ0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821883; c=relaxed/simple; bh=EppRrtC+ZsRFBchm5X5je9mHitk+9jFxBuuOOS29glc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AtGjOH0hqPqhCVFX3yhqEuVyNUV4vdZgvyLEr2GYzHAhpp+O6nCmGqVuZk0CBiyKiq8PLaVQjkWGx4VaLIpp8UdKhJR7/zMZRf9fwb4g0/R9ZHpcW8u+QC/+wC+sCceVsUItpKg8W0nK5uONv+ctwspE0UQgkbfU0zE/vFW/GFs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oBjxN3Mc; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="oBjxN3Mc" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9BD30C4CEEE; Fri, 9 May 2025 20:18:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821883; bh=EppRrtC+ZsRFBchm5X5je9mHitk+9jFxBuuOOS29glc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oBjxN3Mc+RZEy162o3B7h6cBw9+98n80tk70xbvvzeQZQwCcL9OhdI2QET/bjgXKP UzGoOPXae7TsH7JpF22mrTSPWGrgE9fLuKxo7Uw74QBGASgnr0GMa4l6Q61Sc5fszh r1oyaT2QI+HCLv2pxZmDtSC03GlZUPkm1WVUBTgf3IZ99guWy4DqzpRPpxwk/PLi+H jY7Ew8qsudBlHRpGfy2o9x6429IIex8sMCngbGUQAuPxT7zugVgGDNxQ85/BL6NAVI 0F2oIIN0ASVs0TT7DpWgCQKJLVIPQBqbfRZgVv7f7u5A19n4ZSetCLaY5YvVW/P3gS MVi1lH8KiHdFQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 26/62] objtool: Add section/symbol type helpers Date: Fri, 9 May 2025 13:16:50 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add some helper macros to improve readability. Signed-off-by: Josh Poimboeuf --- tools/objtool/arch/x86/special.c | 2 +- tools/objtool/check.c | 58 ++++++++++++------------- tools/objtool/elf.c | 20 ++++----- tools/objtool/include/objtool/elf.h | 66 +++++++++++++++++++++++++++++ tools/objtool/special.c | 4 +- 5 files changed, 108 insertions(+), 42 deletions(-) diff --git a/tools/objtool/arch/x86/special.c b/tools/objtool/arch/x86/spec= ial.c index 06ca4a2659a4..09300761f108 100644 --- a/tools/objtool/arch/x86/special.c +++ b/tools/objtool/arch/x86/special.c @@ -89,7 +89,7 @@ struct reloc *arch_find_switch_table(struct objtool_file = *file, /* look for a relocation which references .rodata */ text_reloc =3D find_reloc_by_dest_range(file->elf, insn->sec, insn->offset, insn->len); - if (!text_reloc || text_reloc->sym->type !=3D STT_SECTION || + if (!text_reloc || !is_sec_sym(text_reloc->sym) || !text_reloc->sym->sec->rodata) return NULL; =20 diff --git a/tools/objtool/check.c b/tools/objtool/check.c index c6884620e49d..d53438865d68 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -258,7 +258,7 @@ static bool __dead_end_function(struct objtool_file *fi= le, struct symbol *func, if (!func) return false; =20 - if (func->bind =3D=3D STB_GLOBAL || func->bind =3D=3D STB_WEAK) { + if (!is_local_sym(func)) { if (is_rust_noreturn(func)) return true; =20 @@ -267,7 +267,7 @@ static bool __dead_end_function(struct objtool_file *fi= le, struct symbol *func, return true; } =20 - if (func->bind =3D=3D STB_WEAK) + if (is_weak_sym(func)) return false; =20 if (!func->len) @@ -434,7 +434,7 @@ static int decode_instructions(struct objtool_file *fil= e) u8 prev_len =3D 0; u8 idx =3D 0; =20 - if (!(sec->sh.sh_flags & SHF_EXECINSTR)) + if (!is_text_sec(sec)) continue; =20 if (strcmp(sec->name, ".altinstr_replacement") && @@ -457,7 +457,7 @@ static int decode_instructions(struct objtool_file *fil= e) if (!strcmp(sec->name, ".init.text") && !opts.module) sec->init =3D true; =20 - for (offset =3D 0; offset < sec->sh.sh_size; offset +=3D insn->len) { + for (offset =3D 0; offset < sec_size(sec); offset +=3D insn->len) { if (!insns || idx =3D=3D INSN_CHUNK_MAX) { insns =3D calloc(INSN_CHUNK_SIZE, sizeof(*insn)); if (!insns) { @@ -477,7 +477,7 @@ static int decode_instructions(struct objtool_file *fil= e) insn->prev_len =3D prev_len; =20 ret =3D arch_decode_instruction(file, sec, offset, - sec->sh.sh_size - offset, + sec_size(sec) - offset, insn); if (ret) return ret; @@ -497,12 +497,12 @@ static int decode_instructions(struct objtool_file *f= ile) } =20 sec_for_each_sym(sec, func) { - if (func->type !=3D STT_NOTYPE && func->type !=3D STT_FUNC) + if (!is_notype_sym(func) && !is_func_sym(func)) continue; =20 - if (func->offset =3D=3D sec->sh.sh_size) { + if (func->offset =3D=3D sec_size(sec)) { /* Heuristic: likely an "end" symbol */ - if (func->type =3D=3D STT_NOTYPE) + if (is_notype_sym(func)) continue; ERROR("%s(): STT_FUNC at end of section", func->name); return -1; @@ -518,7 +518,7 @@ static int decode_instructions(struct objtool_file *fil= e) =20 sym_for_each_insn(file, func, insn) { insn->sym =3D func; - if (func->type =3D=3D STT_FUNC && + if (is_func_sym(func) && insn->type =3D=3D INSN_ENDBR && list_empty(&insn->call_node)) { if (insn->offset =3D=3D func->offset) { @@ -562,7 +562,7 @@ static int add_pv_ops(struct objtool_file *file, const = char *symname) idx =3D (reloc_offset(reloc) - sym->offset) / sizeof(unsigned long); =20 func =3D reloc->sym; - if (func->type =3D=3D STT_SECTION) + if (is_sec_sym(func)) func =3D find_symbol_by_offset(reloc->sym->sec, reloc_addend(reloc)); if (!func) { @@ -825,7 +825,7 @@ static int create_ibt_endbr_seal_sections(struct objtoo= l_file *file) struct symbol *sym =3D insn->sym; *site =3D 0; =20 - if (opts.module && sym && sym->type =3D=3D STT_FUNC && + if (opts.module && sym && is_func_sym(sym) && insn->offset =3D=3D sym->offset && (!strcmp(sym->name, "init_module") || !strcmp(sym->name, "cleanup_module"))) { @@ -860,7 +860,7 @@ static int create_cfi_sections(struct objtool_file *fil= e) =20 idx =3D 0; for_each_sym(file->elf, sym) { - if (sym->type !=3D STT_FUNC) + if (!is_func_sym(sym)) continue; =20 if (strncmp(sym->name, "__cfi_", 6)) @@ -876,7 +876,7 @@ static int create_cfi_sections(struct objtool_file *fil= e) =20 idx =3D 0; for_each_sym(file->elf, sym) { - if (sym->type !=3D STT_FUNC) + if (!is_func_sym(sym)) continue; =20 if (strncmp(sym->name, "__cfi_", 6)) @@ -1465,7 +1465,7 @@ static bool jump_is_sibling_call(struct objtool_file = *file, return false; =20 /* Disallow sibling calls into STT_NOTYPE */ - if (ts->type =3D=3D STT_NOTYPE) + if (is_notype_sym(ts)) return false; =20 /* Must not be self to be a sibling */ @@ -1500,7 +1500,7 @@ static int add_jump_destinations(struct objtool_file = *file) if (!reloc) { dest_sec =3D insn->sec; dest_off =3D arch_jump_destination(insn); - } else if (reloc->sym->type =3D=3D STT_SECTION) { + } else if (is_sec_sym(reloc->sym)) { dest_sec =3D reloc->sym->sec; dest_off =3D arch_insn_adjusted_addend(insn, reloc); } else if (reloc->sym->retpoline_thunk) { @@ -1666,12 +1666,12 @@ static int add_call_destinations(struct objtool_fil= e *file) return -1; } =20 - if (func && insn_call_dest(insn)->type !=3D STT_FUNC) { + if (func && !is_func_sym(insn_call_dest(insn))) { ERROR_INSN(insn, "unsupported call to non-function"); return -1; } =20 - } else if (reloc->sym->type =3D=3D STT_SECTION) { + } else if (is_sec_sym(reloc->sym)) { dest_off =3D arch_insn_adjusted_addend(insn, reloc); dest =3D find_call_destination(reloc->sym->sec, dest_off); if (!dest) { @@ -2166,7 +2166,7 @@ static int add_jump_table_alts(struct objtool_file *f= ile) return 0; =20 for_each_sym(file->elf, func) { - if (func->type !=3D STT_FUNC) + if (!is_func_sym(func)) continue; =20 mark_func_jump_tables(file, func); @@ -2206,14 +2206,14 @@ static int read_unwind_hints(struct objtool_file *f= ile) return -1; } =20 - if (sec->sh.sh_size % sizeof(struct unwind_hint)) { + if (sec_size(sec) % sizeof(struct unwind_hint)) { ERROR("struct unwind_hint size mismatch"); return -1; } =20 file->hints =3D true; =20 - for (i =3D 0; i < sec->sh.sh_size / sizeof(struct unwind_hint); i++) { + for (i =3D 0; i < sec_size(sec) / sizeof(struct unwind_hint); i++) { hint =3D (struct unwind_hint *)sec->data->d_buf + i; =20 reloc =3D find_reloc_by_dest(file->elf, sec, i * sizeof(*hint)); @@ -2222,7 +2222,7 @@ static int read_unwind_hints(struct objtool_file *fil= e) return -1; } =20 - if (reloc->sym->type =3D=3D STT_SECTION) { + if (is_sec_sym(reloc->sym)) { offset =3D reloc_addend(reloc); } else if (reloc->sym->local_label) { offset =3D reloc->sym->offset; @@ -2258,7 +2258,7 @@ static int read_unwind_hints(struct objtool_file *fil= e) if (hint->type =3D=3D UNWIND_HINT_TYPE_REGS_PARTIAL) { struct symbol *sym =3D find_symbol_by_offset(insn->sec, insn->offset); =20 - if (sym && sym->bind =3D=3D STB_GLOBAL) { + if (sym && is_global_sym(sym)) { if (opts.ibt && insn->type !=3D INSN_ENDBR && !insn->noendbr) { ERROR_INSN(insn, "UNWIND_HINT_IRET_REGS without ENDBR"); return -1; @@ -2472,10 +2472,10 @@ static int classify_symbols(struct objtool_file *fi= le) struct symbol *func; =20 for_each_sym(file->elf, func) { - if (func->type =3D=3D STT_NOTYPE && strstarts(func->name, ".L")) + if (is_notype_sym(func) && strstarts(func->name, ".L")) func->local_label =3D true; =20 - if (func->bind !=3D STB_GLOBAL) + if (!is_global_sym(func)) continue; =20 if (!strncmp(func->name, STATIC_CALL_TRAMP_PREFIX_STR, @@ -4179,11 +4179,11 @@ static int add_prefix_symbols(struct objtool_file *= file) struct symbol *func; =20 for_each_sec(file->elf, sec) { - if (!(sec->sh.sh_flags & SHF_EXECINSTR)) + if (!is_text_sec(sec)) continue; =20 sec_for_each_sym(sec, func) { - if (func->type !=3D STT_FUNC) + if (!is_func_sym(func)) continue; =20 add_prefix_symbol(file, func); @@ -4227,7 +4227,7 @@ static int validate_section(struct objtool_file *file= , struct section *sec) int warnings =3D 0; =20 sec_for_each_sym(sec, func) { - if (func->type !=3D STT_FUNC) + if (!is_func_sym(func)) continue; =20 init_insn_state(file, &state, sec); @@ -4271,7 +4271,7 @@ static int validate_functions(struct objtool_file *fi= le) int warnings =3D 0; =20 for_each_sec(file->elf, sec) { - if (!(sec->sh.sh_flags & SHF_EXECINSTR)) + if (!is_text_sec(sec)) continue; =20 warnings +=3D validate_section(file, sec); @@ -4452,7 +4452,7 @@ static int validate_ibt(struct objtool_file *file) for_each_sec(file->elf, sec) { =20 /* Already done by validate_ibt_insn() */ - if (sec->sh.sh_flags & SHF_EXECINSTR) + if (is_text_sec(sec)) continue; =20 if (!sec->rsec) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index c27edeed2dd0..d36c0d42fd7b 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -170,7 +170,7 @@ struct symbol *find_symbol_by_offset(struct section *se= c, unsigned long offset) struct symbol *iter; =20 __sym_for_each(iter, tree, offset, offset) { - if (iter->offset =3D=3D offset && iter->type !=3D STT_SECTION) + if (iter->offset =3D=3D offset && !is_sec_sym(iter)) return iter; } =20 @@ -183,7 +183,7 @@ struct symbol *find_func_by_offset(struct section *sec,= unsigned long offset) struct symbol *iter; =20 __sym_for_each(iter, tree, offset, offset) { - if (iter->offset =3D=3D offset && iter->type =3D=3D STT_FUNC) + if (iter->offset =3D=3D offset && is_func_sym(iter)) return iter; } =20 @@ -264,7 +264,7 @@ struct symbol *find_func_containing(struct section *sec= , unsigned long offset) struct symbol *iter; =20 __sym_for_each(iter, tree, offset, offset) { - if (iter->type =3D=3D STT_FUNC) + if (is_func_sym(iter)) return iter; } =20 @@ -373,14 +373,14 @@ static int read_sections(struct elf *elf) return -1; } =20 - if (sec->sh.sh_size !=3D 0 && !is_dwarf_section(sec)) { + if (sec_size(sec) !=3D 0 && !is_dwarf_section(sec)) { sec->data =3D elf_getdata(s, NULL); if (!sec->data) { ERROR_ELF("elf_getdata"); return -1; } if (sec->data->d_off !=3D 0 || - sec->data->d_size !=3D sec->sh.sh_size) { + sec->data->d_size !=3D sec_size(sec)) { ERROR("unexpected data attributes for %s", sec->name); return -1; } @@ -420,7 +420,7 @@ static void elf_add_symbol(struct elf *elf, struct symb= ol *sym) sym->type =3D GELF_ST_TYPE(sym->sym.st_info); sym->bind =3D GELF_ST_BIND(sym->sym.st_info); =20 - if (sym->type =3D=3D STT_FILE) + if (is_file_sym(sym)) elf->num_files++; =20 sym->offset =3D sym->sym.st_value; @@ -527,7 +527,7 @@ static int read_symbols(struct elf *elf) sec_for_each_sym(sec, sym) { char *pname; size_t pnamelen; - if (sym->type !=3D STT_FUNC) + if (!is_func_sym(sym)) continue; =20 if (sym->pfunc =3D=3D NULL) @@ -929,7 +929,7 @@ struct reloc *elf_init_reloc_text_sym(struct elf *elf, = struct section *sec, struct symbol *sym =3D insn_sec->sym; int addend =3D insn_off; =20 - if (!(insn_sec->sh.sh_flags & SHF_EXECINSTR)) { + if (!is_text_sec(insn_sec)) { ERROR("bad call to %s() for data symbol %s", __func__, sym->name); return NULL; } @@ -958,7 +958,7 @@ struct reloc *elf_init_reloc_data_sym(struct elf *elf, = struct section *sec, struct symbol *sym, s64 addend) { - if (sym->sec && (sec->sh.sh_flags & SHF_EXECINSTR)) { + if (is_text_sec(sec)) { ERROR("bad call to %s() for text symbol %s", __func__, sym->name); return NULL; } @@ -1287,7 +1287,7 @@ int elf_write_insn(struct elf *elf, struct section *s= ec, */ static int elf_truncate_section(struct elf *elf, struct section *sec) { - u64 size =3D sec->sh.sh_size; + u64 size =3D sec_size(sec); bool truncated =3D false; Elf_Data *data =3D NULL; Elf_Scn *s; diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index fcea9338c687..0914dadece0b 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -8,6 +8,7 @@ =20 #include #include +#include #include #include #include @@ -177,11 +178,71 @@ static inline unsigned int elf_text_rela_type(struct = elf *elf) return elf_addr_size(elf) =3D=3D 4 ? R_TEXT32 : R_TEXT64; } =20 +static inline bool sym_has_sec(struct symbol *sym) +{ + return sym->sec->idx; +} + +static inline bool is_null_sym(struct symbol *sym) +{ + return !sym->idx; +} + +static inline bool is_sec_sym(struct symbol *sym) +{ + return sym->type =3D=3D STT_SECTION; +} + +static inline bool is_object_sym(struct symbol *sym) +{ + return sym->type =3D=3D STT_OBJECT; +} + +static inline bool is_func_sym(struct symbol *sym) +{ + return sym->type =3D=3D STT_FUNC; +} + +static inline bool is_file_sym(struct symbol *sym) +{ + return sym->type =3D=3D STT_FILE; +} + +static inline bool is_notype_sym(struct symbol *sym) +{ + return sym->type =3D=3D STT_NOTYPE; +} + +static inline bool is_global_sym(struct symbol *sym) +{ + return sym->bind =3D=3D STB_GLOBAL; +} + +static inline bool is_weak_sym(struct symbol *sym) +{ + return sym->bind =3D=3D STB_WEAK; +} + +static inline bool is_local_sym(struct symbol *sym) +{ + return sym->bind =3D=3D STB_LOCAL; +} + static inline bool is_reloc_sec(struct section *sec) { return sec->sh.sh_type =3D=3D SHT_RELA || sec->sh.sh_type =3D=3D SHT_REL; } =20 +static inline bool is_string_sec(struct section *sec) +{ + return sec->sh.sh_flags & SHF_STRINGS; +} + +static inline bool is_text_sec(struct section *sec) +{ + return sec->sh.sh_flags & SHF_EXECINSTR; +} + static inline bool sec_changed(struct section *sec) { return sec->_changed; @@ -222,6 +283,11 @@ static inline bool is_32bit_reloc(struct reloc *reloc) return reloc->sec->sh.sh_entsize < 16; } =20 +static inline unsigned long sec_size(struct section *sec) +{ + return sec->sh.sh_size; +} + #define __get_reloc_field(reloc, field) \ ({ \ is_32bit_reloc(reloc) ? \ diff --git a/tools/objtool/special.c b/tools/objtool/special.c index c80fed8a840e..9cfdd424e173 100644 --- a/tools/objtool/special.c +++ b/tools/objtool/special.c @@ -142,12 +142,12 @@ int special_get_alts(struct elf *elf, struct list_hea= d *alts) if (!sec) continue; =20 - if (sec->sh.sh_size % entry->size !=3D 0) { + if (sec_size(sec) % entry->size !=3D 0) { ERROR("%s size not a multiple of %d", sec->name, entry->size); return -1; } =20 - nr_entries =3D sec->sh.sh_size / entry->size; + nr_entries =3D sec_size(sec) / entry->size; =20 for (idx =3D 0; idx < nr_entries; idx++) { alt =3D malloc(sizeof(*alt)); --=20 2.49.0 From nobody Tue Dec 16 10:00:03 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 09F3A276024; Fri, 9 May 2025 20:18:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821884; cv=none; b=u32Dfk4jGUyoDb/x5f3Sl0mdN6eFD6AbSIBnmLNib6VOnxYeOGIx1+RXFhkMiYy4AUat86H0p1YfxXQAHEDJqWNC9oRpBsuG3g9N7BVQsotDHqLkw0itflgssjofp9VQj6ftSkE7SsVpHMjBPftcTcJs3Lx6S+TCWKQXHeA8ZxQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821884; c=relaxed/simple; bh=nG0D1Th2MfRsPa/QSsPxSzVCpK+SaAFbpW1WnLuhvFw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ulCEgOsTyAkazBkPheD+UpgvFL300lw0F7KD2vnTj4qYZ2SGyDlkHK/adPR86S6We28o+fe3+8iqmjgtA5zfHzpCJWkWCWnU4+PWrhrg79DR8WuC8POLi5Z037P3V4vS8VD/492Dtd4eiOu/geeuSl52H6qsJ9rXCFXTzAlWRWU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=an0/2ltE; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="an0/2ltE" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5CAF6C4CEE9; Fri, 9 May 2025 20:18:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821883; bh=nG0D1Th2MfRsPa/QSsPxSzVCpK+SaAFbpW1WnLuhvFw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=an0/2ltEMaxftommRLf1wOOrhLwoqcPyXA1fOgV7HMYo6xQU1YbrR24U9/6+g46xT ewWdvQwOo4DsURWQdhv/N3g6T8uaf3s1G19yAJG/ODSlT4DAwz5e0kvWm2rdWhF4Yu ctjyz4dzMo4PQFdKQBkCSi/G8jrxT8thNUoWDZcEhAs+cyl0gh3nTb+UmUSRXvrUea gSo7wgMAIpsB0No8KqRAIw5QNU3LQKGLY3guWOijVk3dJqwfMOwVKklzKc0PKM/zdI ZPlPO3oS2Qf3kmKLUUBRlgeEkJszVgQsBCWhoZJyknIGVh/xkRJDluzVQN5l6aZH7e JKnbFJXNDqnHg== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 27/62] objtool: Mark .cold subfunctions Date: Fri, 9 May 2025 13:16:51 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Introduce a flag to identify .cold subfunctions so they can be detected easier and faster. Signed-off-by: Josh Poimboeuf --- tools/objtool/check.c | 14 ++++++-------- tools/objtool/elf.c | 19 ++++++++++--------- tools/objtool/include/objtool/elf.h | 1 + 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index d53438865d68..043c36b70f26 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1581,7 +1581,9 @@ static int add_jump_destinations(struct objtool_file = *file) /* * Cross-function jump. */ - if (func && insn_func(jump_dest) && func !=3D insn_func(jump_dest)) { + + if (func && insn_func(jump_dest) && !func->cold && + insn_func(jump_dest)->cold) { =20 /* * For GCC 8+, create parent/child links for any cold @@ -1598,11 +1600,8 @@ static int add_jump_destinations(struct objtool_file= *file) * case where the parent function's only reference to a * subfunction is through a jump table. */ - if (!strstr(func->name, ".cold") && - strstr(insn_func(jump_dest)->name, ".cold")) { - func->cfunc =3D insn_func(jump_dest); - insn_func(jump_dest)->pfunc =3D func; - } + func->cfunc =3D insn_func(jump_dest); + insn_func(jump_dest)->pfunc =3D func; } =20 if (jump_is_sibling_call(file, insn, jump_dest)) { @@ -4066,9 +4065,8 @@ static bool ignore_unreachable_insn(struct objtool_fi= le *file, struct instructio * If this hole jumps to a .cold function, mark it ignore too. */ if (insn->jump_dest && insn_func(insn->jump_dest) && - strstr(insn_func(insn->jump_dest)->name, ".cold")) { + insn_func(insn->jump_dest)->cold) insn_func(insn->jump_dest)->ignore =3D true; - } } =20 return false; diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index d36c0d42fd7b..59568381486c 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -441,6 +441,10 @@ static void elf_add_symbol(struct elf *elf, struct sym= bol *sym) list_add(&sym->list, entry); elf_hash_add(symbol, &sym->hash, sym->idx); elf_hash_add(symbol_name, &sym->name_hash, str_hash(sym->name)); + + if (is_func_sym(sym) && strstr(sym->name, ".cold")) + sym->cold =3D 1; + sym->pfunc =3D sym->cfunc =3D sym; } =20 static int read_symbols(struct elf *elf) @@ -527,18 +531,15 @@ static int read_symbols(struct elf *elf) sec_for_each_sym(sec, sym) { char *pname; size_t pnamelen; - if (!is_func_sym(sym)) + + if (!sym->cold) continue; =20 - if (sym->pfunc =3D=3D NULL) - sym->pfunc =3D sym; - - if (sym->cfunc =3D=3D NULL) - sym->cfunc =3D sym; - coldstr =3D strstr(sym->name, ".cold"); - if (!coldstr) - continue; + if (!coldstr) { + ERROR("%s(): cold subfunction without \".cold\"?", sym->name); + return -1; + } =20 pnamelen =3D coldstr - sym->name; pname =3D strndup(sym->name, pnamelen); diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index 0914dadece0b..f41496b0ad8f 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -71,6 +71,7 @@ struct symbol { u8 local_label : 1; u8 frame_pointer : 1; u8 ignore : 1; + u8 cold : 1; struct list_head pv_target; struct reloc *relocs; struct section *group_sec; --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3095D27A925; Fri, 9 May 2025 20:18:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821886; cv=none; b=KvfUcexMYAvQZwPUJDPlnE7ndfGWNLllFT45T9XmLl3sbxsdiKh70UhvHb09JGRbWEy7noaX7rq1YwUSkENg5uy8BJ2whmEddFaamM4GWcHPuoKKRDoRPtyIHqCH4XJsK9K99SiKLxIuTiF6imZz7PkYfnZ688qy/hgAitu61NI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821886; c=relaxed/simple; bh=Boy9wHA23OKqJtEN3bVTI2eRSSWNKeq4o2FdXbHxnqE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=I84SzgU/baYUPsuoclDLZ3qS6xI1EY2Nvb/Stojn/ELXBmjmXSpjqIAY9W6JGreKU0+pgKy6ekujWle+7hu5l1OaFn6QjSLOkA9oDwsOieRKHEdd5IvvZnE90Y9zOJIHznAqJaebG5gbAq7ITsfAxb/jtrH32lsh+dzmioDBvM4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bNpa9S0N; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="bNpa9S0N" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 12CFBC4CEEF; Fri, 9 May 2025 20:18:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821884; bh=Boy9wHA23OKqJtEN3bVTI2eRSSWNKeq4o2FdXbHxnqE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bNpa9S0NxvncHPr23Hfpe++saLBwT1acULEXarkyfD1eG7DHmkVBWC1x8n0SkmHfo b8PEuNe2vHeu9I0zy4hpIk1pvjU4aQOJIBmkEEI6rODk6HROy+gnEplGcMxUViP63p tYc6p2EV7joaAcjppe+Zx4UYo7gL9o9rvPHfHJvkwdFxEBtzmqLwNTLrmDZtHE8ETL jjS8vNKThHUz8GVvHa4qadYrDKCi/hl8RYwkNOhed05HnHMt27Bzud8lcG501HzMGP 43aq5SFz/wuwHKqUYHXAr5wSnEl98Iko+6PVWwHMYCJ2nSd2HEJ784PrQb2PvmTN9g YUdZiCYU6sg+A== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 28/62] objtool: Fix weak symbol hole detection for .cold functions Date: Fri, 9 May 2025 13:16:52 -0700 Message-ID: <8ae052ab65412c0fc0359e780dc382f9feb53ace.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When ignore_unreachable_insn() looks for weak function holes which jump to their .cold functions, it assumes the parent function comes before the corresponding .cold function in the symbol table. That's not necessarily the case with -ffunction-sections. Mark all the holes beforehand (including .cold functions) so the ordering of the discovery doesn't matter. Signed-off-by: Josh Poimboeuf --- tools/objtool/check.c | 84 ++++++++++++++------------- tools/objtool/include/objtool/check.h | 3 +- 2 files changed, 45 insertions(+), 42 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 043c36b70f26..a2a025ec57e8 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -2527,6 +2527,44 @@ static void mark_rodata(struct objtool_file *file) file->rodata =3D found; } =20 +static void mark_holes(struct objtool_file *file) +{ + struct instruction *insn; + bool in_hole =3D false; + + if (!opts.link) + return; + + /* + * Whole archive runs might encounter dead code from weak symbols. + * This is where the linker will have dropped the weak symbol in + * favour of a regular symbol, but leaves the code in place. + */ + for_each_insn(file, insn) { + if (insn->sym || !find_symbol_hole_containing(insn->sec, insn->offset)) { + in_hole =3D false; + continue; + } + + /* Skip function padding and pfx code */ + if (!in_hole && insn->type =3D=3D INSN_NOP) + continue; + + in_hole =3D true; + insn->hole =3D 1; + + /* + * If this hole jumps to a .cold function, mark it ignore. + */ + if (insn->jump_dest) { + struct symbol *dest_func =3D insn_func(insn->jump_dest); + + if (dest_func && dest_func->cold) + dest_func->ignore =3D true; + } + } +} + static int decode_sections(struct objtool_file *file) { int ret; @@ -2592,6 +2630,9 @@ static int decode_sections(struct objtool_file *file) if (ret) return ret; =20 + /* Must be after add_jump_destinations() */ + mark_holes(file); + /* * Must be after add_call_destinations() such that it can override * dead_end_function() marks. @@ -4021,7 +4062,8 @@ static bool ignore_unreachable_insn(struct objtool_fi= le *file, struct instructio struct instruction *prev_insn; int i; =20 - if (insn->type =3D=3D INSN_NOP || insn->type =3D=3D INSN_TRAP || (func &&= func->ignore)) + if (insn->type =3D=3D INSN_NOP || insn->type =3D=3D INSN_TRAP || + insn->hole || (func && func->ignore)) return true; =20 /* @@ -4032,46 +4074,6 @@ static bool ignore_unreachable_insn(struct objtool_f= ile *file, struct instructio !strcmp(insn->sec->name, ".altinstr_aux")) return true; =20 - /* - * Whole archive runs might encounter dead code from weak symbols. - * This is where the linker will have dropped the weak symbol in - * favour of a regular symbol, but leaves the code in place. - * - * In this case we'll find a piece of code (whole function) that is not - * covered by a !section symbol. Ignore them. - */ - if (opts.link && !func) { - int size =3D find_symbol_hole_containing(insn->sec, insn->offset); - unsigned long end =3D insn->offset + size; - - if (!size) /* not a hole */ - return false; - - if (size < 0) /* hole until the end */ - return true; - - sec_for_each_insn_continue(file, insn) { - /* - * If we reach a visited instruction at or before the - * end of the hole, ignore the unreachable. - */ - if (insn->visited) - return true; - - if (insn->offset >=3D end) - break; - - /* - * If this hole jumps to a .cold function, mark it ignore too. - */ - if (insn->jump_dest && insn_func(insn->jump_dest) && - insn_func(insn->jump_dest)->cold) - insn_func(insn->jump_dest)->ignore =3D true; - } - - return false; - } - if (!func) return false; =20 diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/= objtool/check.h index 00fb745e7233..0f4e7ac929ef 100644 --- a/tools/objtool/include/objtool/check.h +++ b/tools/objtool/include/objtool/check.h @@ -64,7 +64,8 @@ struct instruction { noendbr : 1, unret : 1, visited : 4, - no_reloc : 1; + no_reloc : 1, + hole : 1; /* 10 bit hole */ =20 struct alt_group *alt_group; --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6A0EF28E59B; Fri, 9 May 2025 20:18:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821885; cv=none; b=EzQEm+AMPbwDLrblywMoD3bmaJ+K5d8NjSS5eevQ8FrzfwAoASBtb/g84Jgf9vRCZKDUSUWJivqtXKAbsWZkCjyGRMXDKgooRHd5TQQ45B2zzX582MzMBETCx6BLxwb23xHG0wQD89xy2I1M5PFjbR1PkMaQWF+ivpUrQBIR5IE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821885; c=relaxed/simple; bh=1NbDwtOv3dS3yl1dXnXeu8RsvtrlV1MtT1kj2eujlVo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=iIY8AK3s7J2ZeMpuNNi2ymasiS/4xXmE2XZa6RkNYnhkruMT4fZdZBTJvl/KsFo3MtDBYjo845X/VlBdIUYZKbcY7t2c7H5YsAl0Seouv1ZUgD3nohBETaE2g+0JYyd2NEKBwrO369BpDVNJz9ce253gptaL/nuJQ2aVEIBG2MU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HKJV+B3B; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="HKJV+B3B" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BD06BC4CEF0; Fri, 9 May 2025 20:18:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821885; bh=1NbDwtOv3dS3yl1dXnXeu8RsvtrlV1MtT1kj2eujlVo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HKJV+B3Buuf73rnysN7EBXD06v+LEqWPJQKH3PayyjPdZWCWS8Y9byr0yvA2h33mZ DCQuLYq9+yyX9AU8EYT/PsDYB289JmqhGoM+s/6PKgsISiOMVf1mR2KXoFVOrWXLEf Zww/r04mS76V42T4iMRfb8SFXmmWmIHQS8JU+yMIQD2QMcouCm40TUKzhlIAwYordI c5gxrzxBQNy53buyYQm+VfAxPkqiase6LEufgx1r28IP9jaj6DJzzvuL7OmFCRPRjK jJhTwB32bE/vRJKFh3s6V7bZ6GCwb9yigS/YdvSibuZ78BrcvOYqdH9xHSN7MLLXoh 7SfF+wH0amUUw== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 29/62] objtool: Mark prefix functions Date: Fri, 9 May 2025 13:16:53 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for the objtool klp diff subcommand, introduce a flag to identify __pfx_*() and __cfi_*() functions in advance so they don't need to be manually identified every time a check is needed. Signed-off-by: Josh Poimboeuf --- tools/objtool/check.c | 3 +-- tools/objtool/elf.c | 5 +++++ tools/objtool/include/objtool/elf.h | 6 ++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index a2a025ec57e8..6b2e57d9aaf8 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -3601,8 +3601,7 @@ static int validate_branch(struct objtool_file *file,= struct symbol *func, =20 if (func && insn_func(insn) && func !=3D insn_func(insn)->pfunc) { /* Ignore KCFI type preambles, which always fall through */ - if (!strncmp(func->name, "__cfi_", 6) || - !strncmp(func->name, "__pfx_", 6)) + if (is_prefix_func(func)) return 0; =20 if (file->ignore_unreachables) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 59568381486c..9a1fc0392b7f 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -442,6 +442,11 @@ static void elf_add_symbol(struct elf *elf, struct sym= bol *sym) elf_hash_add(symbol, &sym->hash, sym->idx); elf_hash_add(symbol_name, &sym->name_hash, str_hash(sym->name)); =20 + if (is_func_sym(sym) && sym->len =3D=3D 16 && + (strstarts(sym->name, "__pfx") || strstarts(sym->name, "__cfi_"))) + sym->prefix =3D 1; + + if (is_func_sym(sym) && strstr(sym->name, ".cold")) sym->cold =3D 1; sym->pfunc =3D sym->cfunc =3D sym; diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index f41496b0ad8f..842faec1b9a9 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -72,6 +72,7 @@ struct symbol { u8 frame_pointer : 1; u8 ignore : 1; u8 cold : 1; + u8 prefix : 1; struct list_head pv_target; struct reloc *relocs; struct section *group_sec; @@ -229,6 +230,11 @@ static inline bool is_local_sym(struct symbol *sym) return sym->bind =3D=3D STB_LOCAL; } =20 +static inline bool is_prefix_func(struct symbol *sym) +{ + return is_func_sym(sym) && sym->prefix; +} + static inline bool is_reloc_sec(struct section *sec) { return sec->sh.sh_type =3D=3D SHT_RELA || sec->sh.sh_type =3D=3D SHT_REL; --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7F265290BC2; Fri, 9 May 2025 20:18:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821886; cv=none; b=ToOBkqNUDtfuIKqzJnpRigmQwUULoG4C9QQk0pJ/rfEjNZE1r/87y9YN3Q8h5wwx8m78m5zdqw/QtgfKV0bORoi3g4SKUHAJUNWQtTt/0VmmPHuQgUD9to/vaR7iZmCKP54jiYbVCs39vYJias1p+ZD6cKTeMpIFAZJEHRz/Pp8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821886; c=relaxed/simple; bh=TCh7mN1dtaUkmUbKcMUgKaRQzRkSpr6K6e506gWbFxc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=R1bpPl067Nt/uhHRb7rt6cGwNp7aqBBmU/kIwJClcVyN3SxYWSDgUNepR9s91h/rzwnkmot2PI5IzoTW735+cQ7U+IV0Ngc9igtZfpTdeabz5NyrBkcoItZ70Df21WE7okgXE8Q3BND8I2mgUJEfDCZatMjqlJmlreL2u9/g+Wc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dVomlVuq; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dVomlVuq" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 749A4C4CEEE; Fri, 9 May 2025 20:18:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821886; bh=TCh7mN1dtaUkmUbKcMUgKaRQzRkSpr6K6e506gWbFxc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dVomlVuqWJQIWdDDc3MebpfihTCirAtSplPO1VKcVQZ9HelUbAD/dWpRcj8bVwWlJ CGPvPg7ol7/13NYE0VrYxQMVT6s1TfUqli2qBPVkc2pUDX45Y4IMOFrXuZk5icVafh ZJkTfKCROla4+mY0tbJdfzIV9K/F4UWJwDtvM8fGQb5BqkvxrxqOPdFfTzU1+9I8Tu wycRo7cK0Q7Xzy1HCqbn4Ka3Xa3cJdYVPASHBRQI+YaAScOrGS1OT2gKjvkBvBNLC9 UXZlSWNrhNRVpxoBSNWesBFWtf46TdLuIG80F7NbzEsiowpatNKLcqkkcS615dwZH2 qr/J1bzZ2LRwA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 30/62] objtool: Simplify reloc offset calculation in unwind_read_hints() Date: Fri, 9 May 2025 13:16:54 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Simplify the relocation offset calculation in unwind_read_hints(), similar to other conversions which have already been done. Signed-off-by: Josh Poimboeuf --- tools/objtool/check.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 6b2e57d9aaf8..c9f041168bce 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -2221,14 +2221,7 @@ static int read_unwind_hints(struct objtool_file *fi= le) return -1; } =20 - if (is_sec_sym(reloc->sym)) { - offset =3D reloc_addend(reloc); - } else if (reloc->sym->local_label) { - offset =3D reloc->sym->offset; - } else { - ERROR("unexpected relocation symbol type in %s", sec->rsec->name); - return -1; - } + offset =3D reloc->sym->offset + reloc_addend(reloc); =20 insn =3D find_insn(file, reloc->sym->sec, offset); if (!insn) { --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C6F8229188E; Fri, 9 May 2025 20:18:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821886; cv=none; b=rCAk7iNqf4u4uEbow85/P3xAusuNt71J8LrWVnbKYLewUf5EHcCJKGmXykxW9ycgx8P1iZarlOAvp835I2z3OrPm99bMuYQDvIumFuiDa4r7n6XQz90bFVPDgOsR12H90jNVv/FGkMitTbjDCiztnoi5rdiBtVvKa9PQ08RtpN4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821886; c=relaxed/simple; bh=4dEdBQqKg96SIuMQ4R/7bsyOczgXLNxTXCnaDOxtU+0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WPx32AODDMj/MJtPklHxdfPeOYKppBjuw1HV2k7mSix01tROZEDoLNIMkWv6S5tr34UyugcIdvUgWbMyHZAgtP/32/L9CBwglXUTWI85quj1FfUboRPc6PzP/HUb2y/KUmxJ+S6BHX2BpBQZ3uZzPUXDKq6Wmh0lLxvEWAVdHls= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bd3Ltiqm; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="bd3Ltiqm" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2913AC4CEF0; Fri, 9 May 2025 20:18:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821886; bh=4dEdBQqKg96SIuMQ4R/7bsyOczgXLNxTXCnaDOxtU+0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bd3LtiqmHR4yfQXPnlG2a6IGZEk75/F9WQ/qb+UDdnHs7UZc6ijKJ57otVRy5PVW5 QIvKQSQ5adnIczmNUSGUVWqM7J3ZwcIyh+24lee3CB/U54FUEkoSkVtFQptKu5F658 uINeS5l7P/5fTDw1hikrUA7iR311QrjBEhhjXEeaHF6YNq0hrN75RDhxCe/wsCbx1i +MmssoHYEharGhRx10q4Du6w6gQ7/f9H7le8ov+w+1qOdRe2tKPSuqkWG0I/VEQV6d KQ1goQk8tdhnxGJNPnKJtq9+AGKdtlDLA+u59szdMT/GbpI6IPqD0dVXVPKI4fk0Ro ITM3ntU45fjGA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 31/62] objtool: Avoid emptying lists for duplicate sections Date: Fri, 9 May 2025 13:16:55 -0700 Message-ID: <506d79489b610bde50f877fa0f67cf527b05cf06.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When a to-be-created section already exists, there's no point in emptying the various lists if their respective sections already exist. In fact it's better to leave them intact as they might get used later. Signed-off-by: Josh Poimboeuf --- tools/objtool/check.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index c9f041168bce..3b9443b98fd5 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -637,7 +637,6 @@ static int create_static_call_sections(struct objtool_f= ile *file) =20 sec =3D find_section_by_name(file->elf, ".static_call_sites"); if (sec) { - INIT_LIST_HEAD(&file->static_call_list); WARN("file already has .static_call_sites section, skipping"); return 0; } @@ -853,7 +852,6 @@ static int create_cfi_sections(struct objtool_file *fil= e) =20 sec =3D find_section_by_name(file->elf, ".cfi_sites"); if (sec) { - INIT_LIST_HEAD(&file->call_list); WARN("file already has .cfi_sites section, skipping"); return 0; } @@ -902,7 +900,6 @@ static int create_mcount_loc_sections(struct objtool_fi= le *file) =20 sec =3D find_section_by_name(file->elf, "__mcount_loc"); if (sec) { - INIT_LIST_HEAD(&file->mcount_loc_list); WARN("file already has __mcount_loc section, skipping"); return 0; } @@ -947,7 +944,6 @@ static int create_direct_call_sections(struct objtool_f= ile *file) =20 sec =3D find_section_by_name(file->elf, ".call_sites"); if (sec) { - INIT_LIST_HEAD(&file->call_list); WARN("file already has .call_sites section, skipping"); return 0; } --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7BCE0296FBC; Fri, 9 May 2025 20:18:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821887; cv=none; b=tiKKirYgdiZBBvzUn6/Ol1gO4qM1aoYc4uv+7LvueGA5YWlp4hLmu5O8dhgombJgR80/EUAYXodmEQhE7XgrDELXv4uxTaxST83Iqc1KkHXiOzAJTB8Iv0CYHsYabKUoFP29o3aNe7ZSiXnZdSBBH3zII+5TPDHHTqbiYv0pRcM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821887; c=relaxed/simple; bh=31ROD4LxAHEXgMf4J97V0RMD8+gDvAKgCY+5TpvyP/4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ftAden8pymQ1G0FA/1sFMBQNqrfcQItSOvsXmwGKC9zV6X2RKJ1GQEh/pcbnMkq5WmthbvIMgk8OolmVLvHPKiIkyDAEh6QBBUru9pBiYVfJX4is1zJOL3/QnShdL6FZnJIRRlw2RdjIl4VyYHz6Wy7zdWNWZSiXFAcNs527+Qc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UP0j4VTY; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="UP0j4VTY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D0BE5C4CEEE; Fri, 9 May 2025 20:18:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821887; bh=31ROD4LxAHEXgMf4J97V0RMD8+gDvAKgCY+5TpvyP/4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UP0j4VTYeX5hKxuNbS9jtkocy1sM0ptGI4ufTcutN3XEHnrSyB11xqAp7Zv/tTswp HMcUEA1Im1sZyE2m0ccrfH12imhXu9jXjsVfv4E1dwTPSXgKFuyZh3C74y5DZOUSCe wwREeNalMiIlUbuWqyK4f+k5vHv/acQNi6bO5GEj6YY1TSM7mjUCcOZZWhIlVwOUaf LnvOevtLPMUXWxHKkCGKwLmordOd4J/PAAY5SAqumHv+xnUsgDpkaK0Kn4hVZZHp25 5ROZpPGPt5WnNa8SeCM/ZRhMoEq9GqeO0mzv1R4kDnAmOUUtfYHKLF41+fUIgqX2lQ zRk+mOg0lbMdQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 32/62] objtool: Suppress section skipping warnings with --dryrun Date: Fri, 9 May 2025 13:16:56 -0700 Message-ID: <7eccdb0b09eff581377e5efab8377b6a37596992.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" It's common to use --dryrun on binaries that have already been processed. Don't print the section skipping warnings in that case. Signed-off-by: Josh Poimboeuf --- tools/objtool/check.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 3b9443b98fd5..66cbeebd16ea 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -637,7 +637,9 @@ static int create_static_call_sections(struct objtool_f= ile *file) =20 sec =3D find_section_by_name(file->elf, ".static_call_sites"); if (sec) { - WARN("file already has .static_call_sites section, skipping"); + if (!opts.dryrun) + WARN("file already has .static_call_sites section, skipping"); + return 0; } =20 @@ -719,7 +721,9 @@ static int create_retpoline_sites_sections(struct objto= ol_file *file) =20 sec =3D find_section_by_name(file->elf, ".retpoline_sites"); if (sec) { - WARN("file already has .retpoline_sites, skipping"); + if (!opts.dryrun) + WARN("file already has .retpoline_sites, skipping"); + return 0; } =20 @@ -757,7 +761,9 @@ static int create_return_sites_sections(struct objtool_= file *file) =20 sec =3D find_section_by_name(file->elf, ".return_sites"); if (sec) { - WARN("file already has .return_sites, skipping"); + if (!opts.dryrun) + WARN("file already has .return_sites, skipping"); + return 0; } =20 @@ -795,7 +801,9 @@ static int create_ibt_endbr_seal_sections(struct objtoo= l_file *file) =20 sec =3D find_section_by_name(file->elf, ".ibt_endbr_seal"); if (sec) { - WARN("file already has .ibt_endbr_seal, skipping"); + if (!opts.dryrun) + WARN("file already has .ibt_endbr_seal, skipping"); + return 0; } =20 @@ -852,7 +860,9 @@ static int create_cfi_sections(struct objtool_file *fil= e) =20 sec =3D find_section_by_name(file->elf, ".cfi_sites"); if (sec) { - WARN("file already has .cfi_sites section, skipping"); + if (!opts.dryrun) + WARN("file already has .cfi_sites section, skipping"); + return 0; } =20 @@ -900,7 +910,9 @@ static int create_mcount_loc_sections(struct objtool_fi= le *file) =20 sec =3D find_section_by_name(file->elf, "__mcount_loc"); if (sec) { - WARN("file already has __mcount_loc section, skipping"); + if (!opts.dryrun) + WARN("file already has __mcount_loc section, skipping"); + return 0; } =20 @@ -944,7 +956,9 @@ static int create_direct_call_sections(struct objtool_f= ile *file) =20 sec =3D find_section_by_name(file->elf, ".call_sites"); if (sec) { - WARN("file already has .call_sites section, skipping"); + if (!opts.dryrun) + WARN("file already has .call_sites section, skipping"); + return 0; } =20 --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 977A4297B9F; Fri, 9 May 2025 20:18:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821888; cv=none; b=B3BRVJnLCf1QUAFg0mxMT2tFDYSaolxxLdSxRPp1fuDF6aF1csYBdHLnJ3SlFeIFTV/zXPc4iv/xd7L58+O/NzKBEjl83ku5vzqTzLbIGYmCaGpc+KkjLiFp2Js+7xoL3LQh4G1/duz1T3wvCaXTRvZRPhr6dqPTBz7Q96uqSNs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821888; c=relaxed/simple; bh=Kja++anVa4TZR4hAtZTrGisJVRyVD27NbML9IybK2mA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EazStoARMU+C4O7xW5U2vSULHFASxn57h3dcNOn3UWXY8hjE9b1s0icbY+PCNYWt577mKCS8m3txMUhcmI4eco+QN08WX4uk1aKTOcYT+U+B1X0H2QJdRYU038ZFcRJejcyyAotaR42YTEVIFzYSgjr3ElmJokbY8bYURy85waw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=sqnNoE35; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="sqnNoE35" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 852C0C4CEF0; Fri, 9 May 2025 20:18:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821888; bh=Kja++anVa4TZR4hAtZTrGisJVRyVD27NbML9IybK2mA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sqnNoE3598sTsOxjNaC/uRmaDYK/WE8uBSPx6HUE1EKp4eP2xBiqFl/aXpkRlnBUo sIt0Wq/iE6zaxlbIPTOKubZcvoPoyGzGJwGSj7WLci2JapAkS+KFvhzgJXx4dB4zkO /qNcG9TSbPkJMADfX8OFK8reVFR+QL1rz+GyyVG2OhJeV+v8XvkdP/zwdC8Qrqyl0Q VJlcaPbQJI9BqaLyPkXg9Zh4X2hwRY88vqak0R+TwZjG5kdlPTy8fPSNcbhDzlm7wE fo2vQiz2859Blu3MFXXqKJDf6mR5AN05jx/YVKazaz7DsWY6wogSmdez9P2xoQU+yH sVRtAuCLXN7QQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 33/62] objtool: Rename --Werror to --werror Date: Fri, 9 May 2025 13:16:57 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The objtool --Werror option name is stylistically inconsistent: halfway between GCC's single-dash capitalized -Werror and objtool's double-dash --lowercase convention, making it unnecessarily hard to remember. Make the 'W' lower case (--werror) for consistency with objtool's other options. Signed-off-by: Josh Poimboeuf --- scripts/Makefile.lib | 2 +- scripts/Makefile.vmlinux_o | 2 +- tools/objtool/builtin-check.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index fb94e1ed1092..bfd55a6ad8f1 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -272,7 +272,7 @@ objtool-args-$(CONFIG_HAVE_STATIC_CALL_INLINE) +=3D --= static-call objtool-args-$(CONFIG_HAVE_UACCESS_VALIDATION) +=3D --uaccess objtool-args-$(or $(CONFIG_GCOV_KERNEL),$(CONFIG_KCOV)) +=3D --no-unreacha= ble objtool-args-$(CONFIG_PREFIX_SYMBOLS) +=3D --prefix=3D$(CONFIG_FUNCTION_= PADDING_BYTES) -objtool-args-$(CONFIG_OBJTOOL_WERROR) +=3D --Werror +objtool-args-$(CONFIG_OBJTOOL_WERROR) +=3D --werror =20 objtool-args =3D $(objtool-args-y) \ $(if $(delay-objtool), --link) \ diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o index 938c7457717e..7562cdc73dc7 100644 --- a/scripts/Makefile.vmlinux_o +++ b/scripts/Makefile.vmlinux_o @@ -41,7 +41,7 @@ objtool-enabled :=3D $(or $(delay-objtool),$(CONFIG_NOINS= TR_VALIDATION)) ifeq ($(delay-objtool),y) vmlinux-objtool-args-y +=3D $(objtool-args-y) else -vmlinux-objtool-args-$(CONFIG_OBJTOOL_WERROR) +=3D --Werror +vmlinux-objtool-args-$(CONFIG_OBJTOOL_WERROR) +=3D --werror endif =20 vmlinux-objtool-args-$(CONFIG_NOINSTR_VALIDATION) +=3D --noinstr \ diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index 80239843e9f0..43139143edf8 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -100,7 +100,7 @@ static const struct option check_options[] =3D { OPT_BOOLEAN(0, "sec-address", &opts.sec_address, "print section address= es in warnings"), OPT_BOOLEAN(0, "stats", &opts.stats, "print statistics"), OPT_BOOLEAN('v', "verbose", &opts.verbose, "verbose warnings"), - OPT_BOOLEAN(0, "Werror", &opts.werror, "return error on warnings"), + OPT_BOOLEAN(0, "werror", &opts.werror, "return error on warnings"), =20 OPT_END(), }; --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 457432980BD; Fri, 9 May 2025 20:18:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821889; cv=none; b=EnjM2eMnhbHniKztaidN6na7nygGljeL2f7LM97/GWnYYnN8F8hEPO97/ENOcY1RHm9Ga8t+uG3NzbhIRaze+KJf3KAHOqEFMfqFURXmKpxObJJqRKaCECrkmw3UcbmrwvVgrJgJHO5vBSH7w/7lO2YJv17P7AwOh1zIVFp9DlM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821889; c=relaxed/simple; bh=yhDQuxZsGgEz3jd505z5DoGpxMcvXqzEzc+Mv/9M55M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qpcHke22DWcMYCqooSwwBuvfJ/o0iPsagbrc4Xvqm56JlSq/b/aC1KtxBJY/CzjEUoP2E2ypyw/nDdUXy0ifvTK3pefWfAJ++hlmcJZY5UebdZcX30WjpQzmZKTD6lD5nyAoMV9AOkjNGDpdojIKNt5UAIEbNZJ2Z025KNmdswE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=V49WQpCB; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="V49WQpCB" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3A55BC4CEE9; Fri, 9 May 2025 20:18:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821888; bh=yhDQuxZsGgEz3jd505z5DoGpxMcvXqzEzc+Mv/9M55M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=V49WQpCBUroaTOex1hnPzBrvXd9OkT3sltzE8d4/7Fg4c5/UTspYm0BRkDYNr1rAe dyQKNh3YgPaDSmRqK+yloh1YQh7l1DujhDVjOhqChamG/EWyNx9kfMVmkJOmKd5f0b Z3pF0EISM/Pm+u8tjQZVpB+/GsbX9F7VQyEgmqxf/0EXSmhGuH8eidMAB2DvPq38GX mSV1q1/ikihRrGO5ug4apEz8m26ydqCZrMVfAzh1CF7BxePZ9wMli8TkyvAen/Qr57 uVk4sAV5FBfRN87C15F2GrGdY5vP3NQXGt8sHvWQbb4TfPrfOMx7aI6OhFrNmv5VG6 uACCvaEbsXYJQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 34/62] objtool: Reindent check_options[] Date: Fri, 9 May 2025 13:16:58 -0700 Message-ID: <0f8de2dcf0379ff2dacb927df15e84b8784e9e8e.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Bring the cmdline check_options[] array back into vertical alignment for better readability. Signed-off-by: Josh Poimboeuf --- tools/objtool/builtin-check.c | 50 +++++++++++++++++------------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index 43139143edf8..56388bb98785 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -73,34 +73,34 @@ static int parse_hacks(const struct option *opt, const = char *str, int unset) =20 static const struct option check_options[] =3D { OPT_GROUP("Actions:"), + OPT_BOOLEAN(0 , "cfi", &opts.cfi, "annotate kernel control flow integri= ty (kCFI) function preambles"), OPT_CALLBACK_OPTARG('h', "hacks", NULL, NULL, "jump_label,noinstr,skylake= ", "patch toolchain bugs/limitations", parse_hacks), - OPT_BOOLEAN('i', "ibt", &opts.ibt, "validate and annotate IBT"), - OPT_BOOLEAN('m', "mcount", &opts.mcount, "annotate mcount/fentry calls fo= r ftrace"), - OPT_BOOLEAN('n', "noinstr", &opts.noinstr, "validate noinstr rules"), - OPT_BOOLEAN(0, "orc", &opts.orc, "generate ORC metadata"), - OPT_BOOLEAN('r', "retpoline", &opts.retpoline, "validate and annotate ret= poline usage"), - OPT_BOOLEAN(0, "rethunk", &opts.rethunk, "validate and annotate rethunk= usage"), - OPT_BOOLEAN(0, "unret", &opts.unret, "validate entry unret placement"), - OPT_INTEGER(0, "prefix", &opts.prefix, "generate prefix symbols"), - OPT_BOOLEAN('l', "sls", &opts.sls, "validate straight-line-speculation mi= tigations"), - OPT_BOOLEAN('s', "stackval", &opts.stackval, "validate frame pointer rule= s"), - OPT_BOOLEAN('t', "static-call", &opts.static_call, "annotate static calls= "), - OPT_BOOLEAN('u', "uaccess", &opts.uaccess, "validate uaccess rules for SM= AP"), - OPT_BOOLEAN(0 , "cfi", &opts.cfi, "annotate kernel control flow integrit= y (kCFI) function preambles"), - OPT_CALLBACK_OPTARG(0, "dump", NULL, NULL, "orc", "dump metadata", parse_= dump), + OPT_BOOLEAN('i', "ibt", &opts.ibt, "validate and annotate IBT"), + OPT_BOOLEAN('m', "mcount", &opts.mcount, "annotate mcount/fentry calls f= or ftrace"), + OPT_BOOLEAN('n', "noinstr", &opts.noinstr, "validate noinstr rules"), + OPT_BOOLEAN(0, "orc", &opts.orc, "generate ORC metadata"), + OPT_BOOLEAN('r', "retpoline", &opts.retpoline, "validate and annotate re= tpoline usage"), + OPT_BOOLEAN(0, "rethunk", &opts.rethunk, "validate and annotate rethunk= usage"), + OPT_BOOLEAN(0, "unret", &opts.unret, "validate entry unret placement"), + OPT_INTEGER(0, "prefix", &opts.prefix, "generate prefix symbols"), + OPT_BOOLEAN('l', "sls", &opts.sls, "validate straight-line-speculation m= itigations"), + OPT_BOOLEAN('s', "stackval", &opts.stackval, "validate frame pointer rul= es"), + OPT_BOOLEAN('t', "static-call", &opts.static_call, "annotate static call= s"), + OPT_BOOLEAN('u', "uaccess", &opts.uaccess, "validate uaccess rules for S= MAP"), + OPT_CALLBACK_OPTARG(0, "dump", NULL, NULL, "orc", "dump metadata", parse= _dump), =20 OPT_GROUP("Options:"), - OPT_BOOLEAN(0, "backtrace", &opts.backtrace, "unwind on error"), - OPT_BOOLEAN(0, "dry-run", &opts.dryrun, "don't write modifications"), - OPT_BOOLEAN(0, "link", &opts.link, "object is a linked object"), - OPT_BOOLEAN(0, "module", &opts.module, "object is part of a kernel modu= le"), - OPT_BOOLEAN(0, "mnop", &opts.mnop, "nop out mcount call sites"), - OPT_BOOLEAN(0, "no-unreachable", &opts.no_unreachable, "skip 'unreachab= le instruction' warnings"), - OPT_STRING('o', "output", &opts.output, "file", "output file name"), - OPT_BOOLEAN(0, "sec-address", &opts.sec_address, "print section address= es in warnings"), - OPT_BOOLEAN(0, "stats", &opts.stats, "print statistics"), - OPT_BOOLEAN('v', "verbose", &opts.verbose, "verbose warnings"), - OPT_BOOLEAN(0, "werror", &opts.werror, "return error on warnings"), + OPT_BOOLEAN(0, "backtrace", &opts.backtrace, "unwind on error"), + OPT_BOOLEAN(0, "dry-run", &opts.dryrun, "don't write modifications"), + OPT_BOOLEAN(0, "link", &opts.link, "object is a linked object"), + OPT_BOOLEAN(0, "module", &opts.module, "object is part of a kernel modu= le"), + OPT_BOOLEAN(0, "mnop", &opts.mnop, "nop out mcount call sites"), + OPT_BOOLEAN(0, "no-unreachable", &opts.no_unreachable, "skip 'unreachab= le instruction' warnings"), + OPT_STRING('o', "output", &opts.output, "file", "output file name"), + OPT_BOOLEAN(0, "sec-address", &opts.sec_address, "print section address= es in warnings"), + OPT_BOOLEAN(0, "stats", &opts.stats, "print statistics"), + OPT_BOOLEAN('v', "verbose", &opts.verbose, "verbose warnings"), + OPT_BOOLEAN(0, "werror", &opts.werror, "return error on warnings"), =20 OPT_END(), }; --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F1FF12980D2; Fri, 9 May 2025 20:18:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821890; cv=none; b=iecswA9xnx7XwL5v3bFAW37jbU6ob0ckJYbGggvBPeMlS4/+aOAgN+aBvcSzcYv/J2oSfusdmRQkmLmCPzAvvmow4urMNM/cdwfCIOY18QN7IlLxgYVCWKs5N/jBQDHWjLGc+DfcSdJIrOCXq02KsmOUB6q8GwY9+NT5E1/n64E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821890; c=relaxed/simple; bh=E1XeSlz6tc3UGYZyk27xZHj95Gq3nCNWZZlCdtYtLZM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hQiVco20HDYH0cpbRCh1xdeYYXpmik/tQQa7G5RXnK6enlHtCT9qqh3Op6cfkWhVpAQxseGlpgxt/t6BzGaiAZKEhIoNJUdG3rQBKWjieBEVW1MeBhpW5XWS89drBBFwSU0mdLxzl2667z00C0rw2EmkHHOrvaHE5zevX8sNHDE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WzmGTsuN; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="WzmGTsuN" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E49DAC4CEF0; Fri, 9 May 2025 20:18:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821889; bh=E1XeSlz6tc3UGYZyk27xZHj95Gq3nCNWZZlCdtYtLZM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WzmGTsuNZJiVtxxlbm2fn6dhE3vK15ii8Wn0LIDc5wK6puRqoghJNhFt0MTj8yhlw DJOwpU012BnISTH8rcwYo3yV1EuEOVBw1NAXrAcGhGdkp7fmUuu7ZkP63pCCI412At UG6h+zCG+RRoty2inglJ0JFiZL2Z/zZ1zUBaTi27iWT/TXKn+tD2W4HfvSvJAP+Uyy rEKbG5xa8LAO7POJQb4XJL5uMr4QBcw0eVwXbc6Hn+fN9upvkDAnovvCDuao3KS9/j f3erN2MFWiDmIyvSid/M1ErOsyBZXPK0vVyP0gfVTVqvs2uYdnGogrzFmbf6UK3N3q JwK+NmuIOLBbA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 35/62] objtool: Refactor add_jump_destinations() Date: Fri, 9 May 2025 13:16:59 -0700 Message-ID: <70bf4b499941a6b19c5f750f5c36afcd6ffd216f.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The add_jump_destinations() logic is a bit weird and convoluted after being incrementally tweaked over the years. Refactor it to hopefully be more logical and straightforward. Signed-off-by: Josh Poimboeuf --- tools/objtool/check.c | 227 +++++++++++++--------------- tools/objtool/include/objtool/elf.h | 4 +- 2 files changed, 104 insertions(+), 127 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 66cbeebd16ea..e4ca5edf73ad 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1439,9 +1439,14 @@ static void add_return_call(struct objtool_file *fil= e, struct instruction *insn, } =20 static bool is_first_func_insn(struct objtool_file *file, - struct instruction *insn, struct symbol *sym) + struct instruction *insn) { - if (insn->offset =3D=3D sym->offset) + struct symbol *func =3D insn_func(insn); + + if (!func) + return false; + + if (insn->offset =3D=3D func->offset) return true; =20 /* Allow direct CALL/JMP past ENDBR */ @@ -1449,52 +1454,32 @@ static bool is_first_func_insn(struct objtool_file = *file, struct instruction *prev =3D prev_insn_same_sym(file, insn); =20 if (prev && prev->type =3D=3D INSN_ENDBR && - insn->offset =3D=3D sym->offset + prev->len) + insn->offset =3D=3D func->offset + prev->len) return true; } =20 return false; } =20 -/* - * A sibling call is a tail-call to another symbol -- to differentiate fro= m a - * recursive tail-call which is to the same symbol. - */ -static bool jump_is_sibling_call(struct objtool_file *file, - struct instruction *from, struct instruction *to) -{ - struct symbol *fs =3D from->sym; - struct symbol *ts =3D to->sym; - - /* Not a sibling call if from/to a symbol hole */ - if (!fs || !ts) - return false; - - /* Not a sibling call if not targeting the start of a symbol. */ - if (!is_first_func_insn(file, to, ts)) - return false; - - /* Disallow sibling calls into STT_NOTYPE */ - if (is_notype_sym(ts)) - return false; - - /* Must not be self to be a sibling */ - return fs->pfunc !=3D ts->pfunc; -} - /* * Find the destination instructions for all jumps. */ static int add_jump_destinations(struct objtool_file *file) { - struct instruction *insn, *jump_dest; + struct instruction *insn; struct reloc *reloc; - struct section *dest_sec; - unsigned long dest_off; int ret; =20 for_each_insn(file, insn) { struct symbol *func =3D insn_func(insn); + struct instruction *dest_insn; + struct section *dest_sec; + struct symbol *dest_sym; + unsigned long dest_off; + bool dest_undef =3D false; + + if (!is_static_jump(insn)) + continue; =20 if (insn->jump_dest) { /* @@ -1503,129 +1488,121 @@ static int add_jump_destinations(struct objtool_f= ile *file) */ continue; } - if (!is_static_jump(insn)) - continue; =20 reloc =3D insn_reloc(file, insn); if (!reloc) { dest_sec =3D insn->sec; dest_off =3D arch_jump_destination(insn); - } else if (is_sec_sym(reloc->sym)) { + } else if (is_undef_sym(reloc->sym)) { + dest_sym =3D reloc->sym; + dest_undef =3D true; + } else { dest_sec =3D reloc->sym->sec; - dest_off =3D arch_insn_adjusted_addend(insn, reloc); - } else if (reloc->sym->retpoline_thunk) { + dest_off =3D reloc->sym->sym.st_value + + arch_insn_adjusted_addend(insn, reloc); + } + + if (!dest_undef) { + dest_insn =3D find_insn(file, dest_sec, dest_off); + if (!dest_insn) { + struct symbol *sym =3D find_symbol_by_offset(dest_sec, dest_off); + + /* + * retbleed_untrain_ret() jumps to + * __x86_return_thunk(), but objtool can't find + * the thunk's starting RET instruction, + * because the RET is also in the middle of + * another instruction. Objtool only knows + * about the outer instruction. + */ + if (sym && sym->embedded_insn) { + add_return_call(file, insn, false); + continue; + } + + /* + * GCOV/KCOV dead code can jump to the end of + * the function/section. + */ + if (file->ignore_unreachables && func && + dest_sec =3D=3D insn->sec && + dest_off =3D=3D func->offset + func->len) + continue; + + ERROR_INSN(insn, "can't find jump dest instruction at %s+0x%lx", + dest_sec->name, dest_off); + return -1; + } + + dest_sym =3D dest_insn->sym; + if (!dest_sym) + goto set_jump_dest; + } + + if (dest_sym->retpoline_thunk) { ret =3D add_retpoline_call(file, insn); if (ret) return ret; continue; - } else if (reloc->sym->return_thunk) { + } + + if (dest_sym->return_thunk) { add_return_call(file, insn, true); continue; - } else if (func) { - /* - * External sibling call or internal sibling call with - * STT_FUNC reloc. - */ - ret =3D add_call_dest(file, insn, reloc->sym, true); - if (ret) - return ret; - continue; - } else if (reloc->sym->sec->idx) { - dest_sec =3D reloc->sym->sec; - dest_off =3D reloc->sym->sym.st_value + - arch_dest_reloc_offset(reloc_addend(reloc)); - } else { - /* non-func asm code jumping to another file */ - continue; } =20 - jump_dest =3D find_insn(file, dest_sec, dest_off); - if (!jump_dest) { - struct symbol *sym =3D find_symbol_by_offset(dest_sec, dest_off); - - /* - * This is a special case for retbleed_untrain_ret(). - * It jumps to __x86_return_thunk(), but objtool - * can't find the thunk's starting RET - * instruction, because the RET is also in the - * middle of another instruction. Objtool only - * knows about the outer instruction. - */ - if (sym && sym->embedded_insn) { - add_return_call(file, insn, false); - continue; - } - - /* - * GCOV/KCOV dead code can jump to the end of the - * function/section. - */ - if (file->ignore_unreachables && func && - dest_sec =3D=3D insn->sec && - dest_off =3D=3D func->offset + func->len) - continue; - - ERROR_INSN(insn, "can't find jump dest instruction at %s+0x%lx", - dest_sec->name, dest_off); - return -1; - } - - /* - * An intra-TU jump in retpoline.o might not have a relocation - * for its jump dest, in which case the above - * add_{retpoline,return}_call() didn't happen. - */ - if (jump_dest->sym && jump_dest->offset =3D=3D jump_dest->sym->offset) { - if (jump_dest->sym->retpoline_thunk) { - ret =3D add_retpoline_call(file, insn); + if (dest_undef) { + /* External symbol */ + if (func) { + /* External sibling call */ + ret =3D add_call_dest(file, insn, dest_sym, true); if (ret) return ret; continue; } - if (jump_dest->sym->return_thunk) { - add_return_call(file, insn, true); - continue; - } + + /* Non-func asm code jumping to external symbol */ + continue; } =20 + if (!insn->sym || insn->sym =3D=3D dest_insn->sym) + goto set_jump_dest; + /* - * Cross-function jump. + * Internal cross-function jump. */ =20 - if (func && insn_func(jump_dest) && !func->cold && - insn_func(jump_dest)->cold) { - - /* - * For GCC 8+, create parent/child links for any cold - * subfunctions. This is _mostly_ redundant with a - * similar initialization in read_symbols(). - * - * If a function has aliases, we want the *first* such - * function in the symbol table to be the subfunction's - * parent. In that case we overwrite the - * initialization done in read_symbols(). - * - * However this code can't completely replace the - * read_symbols() code because this doesn't detect the - * case where the parent function's only reference to a - * subfunction is through a jump table. - */ - func->cfunc =3D insn_func(jump_dest); - insn_func(jump_dest)->pfunc =3D func; + /* + * For GCC 8+, create parent/child links for any cold + * subfunctions. This is _mostly_ redundant with a + * similar initialization in read_symbols(). + * + * If a function has aliases, we want the *first* such + * function in the symbol table to be the subfunction's + * parent. In that case we overwrite the + * initialization done in read_symbols(). + * + * However this code can't completely replace the + * read_symbols() code because this doesn't detect the + * case where the parent function's only reference to a + * subfunction is through a jump table. + */ + if (func && dest_sym->cold) { + func->cfunc =3D dest_sym; + dest_sym->pfunc =3D func; + goto set_jump_dest; } =20 - if (jump_is_sibling_call(file, insn, jump_dest)) { - /* - * Internal sibling call without reloc or with - * STT_SECTION reloc. - */ - ret =3D add_call_dest(file, insn, insn_func(jump_dest), true); + if (is_first_func_insn(file, dest_insn)) { + /* Internal sibling call */ + ret =3D add_call_dest(file, insn, dest_sym, true); if (ret) return ret; continue; } =20 - insn->jump_dest =3D jump_dest; +set_jump_dest: + insn->jump_dest =3D dest_insn; } =20 return 0; diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index 842faec1b9a9..74c7b84b5310 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -180,9 +180,9 @@ static inline unsigned int elf_text_rela_type(struct el= f *elf) return elf_addr_size(elf) =3D=3D 4 ? R_TEXT32 : R_TEXT64; } =20 -static inline bool sym_has_sec(struct symbol *sym) +static inline bool is_undef_sym(struct symbol *sym) { - return sym->sec->idx; + return !sym->sec->idx; } =20 static inline bool is_null_sym(struct symbol *sym) --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B6457298253; Fri, 9 May 2025 20:18:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821890; cv=none; b=UN30cq3gWsev2NWDB/+xx1nQG7nNhBnaStwsfZoBT93ObG2gJL1XaYeWf/1Q58FKqXgbVfOEVcmWPpmdtgMh3s1xR0KpGkPf0QdXan2ojIhYPG8L7Vfc37QX/x7KMK7vbHDWuhb9LhorGFv4kkFPALWj36mK2YWcHzPxki1C4hM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821890; c=relaxed/simple; bh=z4MYmIyWMxc7ZB5anV6CPYR4FLSO8k77Eu2uXj6imDU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kV8QX+7uz5smAmtuUN+92x2b5hdePGvHzSqEn8RuWCidLea/8tihxb+t1bblM2AX4FVtolLZOxXbTivcW0kDAmL4qM0DC4n+O7EB9D1VKxECLgHRWtS/gF57oVeZFxmTW8JIv67mx1acKvaOqTXOMON2eblIfoW5h78oEQD8ZTc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rrY2HN0C; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rrY2HN0C" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9B3E2C4CEEE; Fri, 9 May 2025 20:18:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821890; bh=z4MYmIyWMxc7ZB5anV6CPYR4FLSO8k77Eu2uXj6imDU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rrY2HN0CxT8sA/PhcO4YeRnnl/EAZjGwNJ61iNF4bWOD49MIfdYboyxLj6pLMjtXC ha/c5qeglSI9DDBkuoL/n9sAcL0RvHiJPDoT47ffUBQ+lYJLszpqrq54zFW1QMq4DO 00OcsLQb2BSuHIpkrLFB5K+ZWaFXD0jdvCRO9eojdsTGdXbXDOj6NYEciMsQZ2oW9m P7CBoXfJzg6N+W/6/xyd9XT7GR7d9wFouWgz2qM5suZ/efoD5m4andPsyNipJLgJa6 LDfx8GCrEXFNYS9nPMsBoy0bFk3qXDOf5hebpAwi+QrjNJ2M7MRCH+3RcCNPtIGxxb UxiEgBYJln7EA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 36/62] objtool: Simplify special symbol handling in elf_update_symbol() Date: Fri, 9 May 2025 13:17:00 -0700 Message-ID: <8026f424659bc6a9b1b90ed88b1d377d80a8e0b0.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" !sym->sec isn't actually a thing: even STT_UNDEF and other special symbol types belong to NULL section 0. Simplify the initialization of 'shndx' accordingly. Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 9a1fc0392b7f..859d677e172c 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -635,7 +635,7 @@ static int elf_update_sym_relocs(struct elf *elf, struc= t symbol *sym) static int elf_update_symbol(struct elf *elf, struct section *symtab, struct section *symtab_shndx, struct symbol *sym) { - Elf32_Word shndx =3D sym->sec ? sym->sec->idx : SHN_UNDEF; + Elf32_Word shndx; Elf_Data *symtab_data =3D NULL, *shndx_data =3D NULL; Elf64_Xword entsize =3D symtab->sh.sh_entsize; int max_idx, idx =3D sym->idx; @@ -643,8 +643,7 @@ static int elf_update_symbol(struct elf *elf, struct se= ction *symtab, bool is_special_shndx =3D sym->sym.st_shndx >=3D SHN_LORESERVE && sym->sym.st_shndx !=3D SHN_XINDEX; =20 - if (is_special_shndx) - shndx =3D sym->sym.st_shndx; + shndx =3D is_special_shndx ? sym->sym.st_shndx : sym->sec->idx; =20 s =3D elf_getscn(elf->elf, symtab->idx); if (!s) { --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EEDAD29825C; Fri, 9 May 2025 20:18:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821891; cv=none; b=sXxkBCazxZyiwukVWo52ms1xBNjS7XF8VmXZ6AtNmMCtrlW2bMJ4UMnZV3+Sy2wv4NxOgnVczFYUfYy42gJ4byY8TwzATUfXxrIGmyuM2Puk5oRsqljUILCuQXt2ZJzaV0IYZ1aG3cvsl4nmYyCtBkvQ07qh2zOfAoBTHnhQNnw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821891; c=relaxed/simple; bh=7swKUK/3k6EQBq1Fv6U9z1jYwUKygY8A2CCrfaG+2Ic=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TntNwG+EXjD+soIML9bfEbJoUZIwi+CqU/trKEWGBsum6fE/mYC/8AQsh4Sif2QslWfg23MwVKJwrB5FcOefKyH4GK5ZTRggq8+P9A2JQMbb8pJTabgUfkg0L6V5ziS4gYPhTtNpDEsni/b32TlBhDhVGJ8apVwiP1BCZRkc4o4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GKQnQ267; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="GKQnQ267" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 51CE8C4CEEF; Fri, 9 May 2025 20:18:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821890; bh=7swKUK/3k6EQBq1Fv6U9z1jYwUKygY8A2CCrfaG+2Ic=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GKQnQ267ruruAesKwORHho6uxAxcSXM8yFFdLWo9zsckgONLLkH5J7J7bXrrxPpX3 t+3iVQpG81jB7F+sfxAa5NJGUansJsxi4nG0Zmxo7dIFn8g9yh68Y21n+4YBj/SYSm dy9wtn22Ng5Hj4JeOcppvotCQ36YpLRLmQsJrSGsWuJ/6Drt9QuXe9Mlcl4aMu5LOu RxlGgtC63h31ndJyo0snoows7C4VfBWnai/DmLxDgR/fmTjYcp+WpxgGHYZXOwGn5v DrgrLe1KEBpNCpWPoHxrqbdpNvZiDQr+XVuE4eDPZtGIB38K9WatHAgHF9Vg4AZqgX Un+Snc+SFW7AA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 37/62] objtool: Generalize elf_create_symbol() Date: Fri, 9 May 2025 13:17:01 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for the objtool klp diff subcommand, broaden the elf_create_symbol() interface to give callers more control and reduce duplication of some subtle setup logic. While at it, make elf_create_symbol() and elf_create_section_symbol() public so sections can be created by the upcoming klp diff code. Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 111 +++++++++++++++------------- tools/objtool/include/objtool/elf.h | 11 ++- 2 files changed, 69 insertions(+), 53 deletions(-) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 859d677e172c..38bf9ae86c89 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -761,24 +761,60 @@ static int elf_update_symbol(struct elf *elf, struct = section *symtab, return 0; } =20 -static struct symbol * -__elf_create_symbol(struct elf *elf, struct symbol *sym) +static int elf_add_string(struct elf *elf, struct section *strtab, const c= har *str); + +struct symbol *elf_create_symbol(struct elf *elf, const char *name, + struct section *sec, unsigned int bind, + unsigned int type, unsigned long offset, + size_t size) { struct section *symtab, *symtab_shndx; Elf32_Word first_non_local, new_idx; - struct symbol *old; + struct symbol *old, *sym; + + sym =3D calloc(1, sizeof(*sym)); + if (!sym) { + ERROR_GLIBC("calloc"); + return NULL; + } + + sym->name =3D strdup(name); + if (!sym->name) { + ERROR_GLIBC("strdup"); + return NULL; + } + + if (type !=3D STT_SECTION) { + sym->sym.st_name =3D elf_add_string(elf, NULL, sym->name); + if (sym->sym.st_name =3D=3D -1) + return NULL; + } + + if (sec) { + sym->sec =3D sec; + } else { + sym->sec =3D find_section_by_index(elf, 0); + if (!sym->sec) { + ERROR("no NULL section"); + return NULL; + } + } + + sym->sym.st_info =3D GELF_ST_INFO(bind, type); + sym->sym.st_value =3D offset; + sym->sym.st_size =3D size; =20 symtab =3D find_section_by_name(elf, ".symtab"); - if (symtab) { - symtab_shndx =3D find_section_by_name(elf, ".symtab_shndx"); - } else { + if (!symtab) { ERROR("no .symtab"); return NULL; } =20 + symtab_shndx =3D find_section_by_name(elf, ".symtab_shndx"); + new_idx =3D sec_num_entries(symtab); =20 - if (GELF_ST_BIND(sym->sym.st_info) !=3D STB_LOCAL) + if (bind !=3D STB_LOCAL) goto non_local; =20 /* @@ -816,10 +852,8 @@ __elf_create_symbol(struct elf *elf, struct symbol *sy= m) =20 non_local: sym->idx =3D new_idx; - if (elf_update_symbol(elf, symtab, symtab_shndx, sym)) { - ERROR("elf_update_symbol"); + if (sym->idx && elf_update_symbol(elf, symtab, symtab_shndx, sym)) return NULL; - } =20 symtab->sh.sh_size +=3D symtab->sh.sh_entsize; mark_sec_changed(elf, symtab, true); @@ -829,64 +863,39 @@ __elf_create_symbol(struct elf *elf, struct symbol *s= ym) mark_sec_changed(elf, symtab_shndx, true); } =20 + elf_add_symbol(elf, sym); + return sym; } =20 -static struct symbol * -elf_create_section_symbol(struct elf *elf, struct section *sec) +struct symbol *elf_create_section_symbol(struct elf *elf, struct section *= sec) { struct symbol *sym =3D calloc(1, sizeof(*sym)); =20 - if (!sym) { - ERROR_GLIBC("malloc"); + sym =3D elf_create_symbol(elf, sec->name, sec, STB_LOCAL, STT_SECTION, 0,= 0); + if (!sym) return NULL; - } =20 - sym->name =3D sec->name; - sym->sec =3D sec; - - // st_name 0 - sym->sym.st_info =3D GELF_ST_INFO(STB_LOCAL, STT_SECTION); - // st_other 0 - // st_value 0 - // st_size 0 - - sym =3D __elf_create_symbol(elf, sym); - if (sym) - elf_add_symbol(elf, sym); + sec->sym =3D sym; =20 return sym; } =20 -static int elf_add_string(struct elf *elf, struct section *strtab, const c= har *str); - struct symbol * -elf_create_prefix_symbol(struct elf *elf, struct symbol *orig, long size) +elf_create_prefix_symbol(struct elf *elf, struct symbol *orig, size_t size) { - struct symbol *sym =3D calloc(1, sizeof(*sym)); size_t namelen =3D strlen(orig->name) + sizeof("__pfx_"); - char *name =3D malloc(namelen); - - if (!sym || !name) { - ERROR_GLIBC("malloc"); - return NULL; - } + char name[SYM_NAME_LEN]; + unsigned long offset; =20 snprintf(name, namelen, "__pfx_%s", orig->name); =20 - sym->name =3D name; - sym->sec =3D orig->sec; + offset =3D orig->sym.st_value - size; =20 - sym->sym.st_name =3D elf_add_string(elf, NULL, name); - sym->sym.st_info =3D orig->sym.st_info; - sym->sym.st_value =3D orig->sym.st_value - size; - sym->sym.st_size =3D size; - - sym =3D __elf_create_symbol(elf, sym); - if (sym) - elf_add_symbol(elf, sym); - - return sym; + return elf_create_symbol(elf, name, orig->sec, + GELF_ST_BIND(orig->sym.st_info), + GELF_ST_TYPE(orig->sym.st_info), + offset, size); } =20 static struct reloc *elf_init_reloc(struct elf *elf, struct section *rsec, @@ -932,7 +941,7 @@ struct reloc *elf_init_reloc_text_sym(struct elf *elf, = struct section *sec, unsigned long insn_off) { struct symbol *sym =3D insn_sec->sym; - int addend =3D insn_off; + s64 addend =3D insn_off; =20 if (!is_text_sec(insn_sec)) { ERROR("bad call to %s() for data symbol %s", __func__, sym->name); @@ -949,8 +958,6 @@ struct reloc *elf_init_reloc_text_sym(struct elf *elf, = struct section *sec, sym =3D elf_create_section_symbol(elf, insn_sec); if (!sym) return NULL; - - insn_sec->sym =3D sym; } =20 return elf_init_reloc(elf, sec->rsec, reloc_idx, offset, sym, addend, diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index 74c7b84b5310..ffdf9ec3882e 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -15,6 +15,8 @@ #include #include =20 +#define SYM_NAME_LEN 512 + #ifdef LIBELF_USE_DEPRECATED # define elf_getshdrnum elf_getshnum # define elf_getshdrstrndx elf_getshstrndx @@ -119,7 +121,14 @@ struct section *elf_create_section_pair(struct elf *el= f, const char *name, size_t entsize, unsigned int nr, unsigned int reloc_nr); =20 -struct symbol *elf_create_prefix_symbol(struct elf *elf, struct symbol *or= ig, long size); +struct symbol *elf_create_symbol(struct elf *elf, const char *name, + struct section *sec, unsigned int bind, + unsigned int type, unsigned long offset, + size_t size); +struct symbol *elf_create_section_symbol(struct elf *elf, struct section *= sec); +struct symbol *elf_create_prefix_symbol(struct elf *elf, struct symbol *or= ig, + size_t size); + =20 struct reloc *elf_init_reloc_text_sym(struct elf *elf, struct section *sec, unsigned long offset, --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 194BF298981; Fri, 9 May 2025 20:18:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821892; cv=none; b=nosixSk8NNax1HQfFPyDZ/MR/gOYecBXql0nqwiKQNjslZbQM+EiTgrW5fatH3lykK3vR+K/m/oamhu+mEH2KVFf42Yd0keBMaspphxxWrDdQsXC0rcKx12RjvgX0TzDHbVwBdY8RzzXuaOCW9pQZzrzzK6VeThfdhAGZYgNqNc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821892; c=relaxed/simple; bh=tqRr0VDNiKRXcBnyKkuPzzvRT0RMapGcWS2ATHR6mVQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=q9MQvpqDN52bvx6eaqR2QX+n0zHqWc4UQSh3HlsUujQlmT47/kdo1+rTNthFx8v5+GojGBJHyyaG6E7SZG3VGuJBw4YfCFMs6ymVmL1HC1GM6qtZxPZJF6qiLxuMllW5CIj5tv+1/MJf/jpPA7rVaEGF/aGOBN9Z0kpC976ir9I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jV0nzlTL; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="jV0nzlTL" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 05DD1C4CEEE; Fri, 9 May 2025 20:18:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821891; bh=tqRr0VDNiKRXcBnyKkuPzzvRT0RMapGcWS2ATHR6mVQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jV0nzlTL85lwWcz/twJ5AX44M86vTFUpqkQHeC2hKg/CWriR60xBok/4zEceqEYCw Biqbv0GnzErMvwADeTzCM1UacTtXxI0SZ2r910ehXOYBBUikl+eQvNmXstX1h8Iudj iqWYnqQFG5vr4ld0LbuOQ+noUxhNXORnlrN8Y04IHwfpChgvusLovRfyIBR9o/nxue KoLHbSNjsnUVixfvmUG7fSLs8MHLUO9LGDQMSgObCiBEFetWvs43xrt0krN09Hr5vc Yq/EcAY2k3qmf5LpQePc+jtoF04Lnl2Z2m5aRQbC6a+NrGz4yeDdGBdLkloGDu3wq0 TdrptcV7QY5Hw== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 38/62] objtool: Generalize elf_create_section() Date: Fri, 9 May 2025 13:17:02 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for the objtool klp diff subcommand, broaden the elf_create_section() interface to give callers more control and reduce duplication of some subtle setup logic. While at it, make elf_create_rela_section() public so sections can be created by the upcoming klp diff code. Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 118 ++++++++++++++++------------ tools/objtool/include/objtool/elf.h | 7 +- tools/objtool/orc_gen.c | 6 +- 3 files changed, 77 insertions(+), 54 deletions(-) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 38bf9ae86c89..c38b109f441f 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -1136,51 +1136,53 @@ static int elf_add_string(struct elf *elf, struct s= ection *strtab, const char *s } =20 struct section *elf_create_section(struct elf *elf, const char *name, - size_t entsize, unsigned int nr) + size_t size, size_t entsize, + unsigned int type, unsigned int align, + unsigned int flags) { struct section *sec, *shstrtab; - size_t size =3D entsize * nr; Elf_Scn *s; =20 - sec =3D malloc(sizeof(*sec)); - if (!sec) { - ERROR_GLIBC("malloc"); + if (name && find_section_by_name(elf, name)) { + ERROR("section '%s' already exists", name); + return NULL; + } + + sec =3D calloc(1, sizeof(*sec)); + if (!sec) { + ERROR_GLIBC("calloc"); return NULL; } - memset(sec, 0, sizeof(*sec)); =20 INIT_LIST_HEAD(&sec->symbol_list); =20 + /* don't actually create the section, just the data structures */ + if (type =3D=3D SHT_NULL) + goto add; + s =3D elf_newscn(elf->elf); if (!s) { ERROR_ELF("elf_newscn"); return NULL; } =20 - sec->name =3D strdup(name); - if (!sec->name) { - ERROR_GLIBC("strdup"); - return NULL; - } - sec->idx =3D elf_ndxscn(s); =20 - sec->data =3D elf_newdata(s); - if (!sec->data) { - ERROR_ELF("elf_newdata"); - return NULL; - } - - sec->data->d_size =3D size; - sec->data->d_align =3D 1; - if (size) { - sec->data->d_buf =3D malloc(size); - if (!sec->data->d_buf) { - ERROR_GLIBC("malloc"); + sec->data =3D elf_newdata(s); + if (!sec->data) { + ERROR_ELF("elf_newdata"); + return NULL; + } + + sec->data->d_size =3D size; + sec->data->d_align =3D 1; + + sec->data->d_buf =3D calloc(1, size); + if (!sec->data->d_buf) { + ERROR_GLIBC("calloc"); return NULL; } - memset(sec->data->d_buf, 0, size); } =20 if (!gelf_getshdr(s, &sec->sh)) { @@ -1190,34 +1192,44 @@ struct section *elf_create_section(struct elf *elf,= const char *name, =20 sec->sh.sh_size =3D size; sec->sh.sh_entsize =3D entsize; - sec->sh.sh_type =3D SHT_PROGBITS; - sec->sh.sh_addralign =3D 1; - sec->sh.sh_flags =3D SHF_ALLOC; + sec->sh.sh_type =3D type; + sec->sh.sh_addralign =3D align; + sec->sh.sh_flags =3D flags; =20 - /* Add section name to .shstrtab (or .strtab for Clang) */ - shstrtab =3D find_section_by_name(elf, ".shstrtab"); - if (!shstrtab) - shstrtab =3D find_section_by_name(elf, ".strtab"); - if (!shstrtab) { - ERROR("can't find .shstrtab or .strtab section"); - return NULL; + if (name) { + sec->name =3D strdup(name); + if (!sec->name) { + ERROR("strdup"); + return NULL; + } + + /* Add section name to .shstrtab (or .strtab for Clang) */ + shstrtab =3D find_section_by_name(elf, ".shstrtab"); + if (!shstrtab) { + shstrtab =3D find_section_by_name(elf, ".strtab"); + if (!shstrtab) { + ERROR("can't find .shstrtab or .strtab"); + return NULL; + } + } + sec->sh.sh_name =3D elf_add_string(elf, shstrtab, sec->name); + if (sec->sh.sh_name =3D=3D -1) + return NULL; + + elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name)); } - sec->sh.sh_name =3D elf_add_string(elf, shstrtab, sec->name); - if (sec->sh.sh_name =3D=3D -1) - return NULL; =20 +add: list_add_tail(&sec->list, &elf->sections); elf_hash_add(section, &sec->hash, sec->idx); - elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name)); =20 mark_sec_changed(elf, sec, true); =20 return sec; } =20 -static struct section *elf_create_rela_section(struct elf *elf, - struct section *sec, - unsigned int reloc_nr) +struct section *elf_create_rela_section(struct elf *elf, struct section *s= ec, + unsigned int reloc_nr) { struct section *rsec; char *rsec_name; @@ -1230,22 +1242,23 @@ static struct section *elf_create_rela_section(stru= ct elf *elf, strcpy(rsec_name, ".rela"); strcat(rsec_name, sec->name); =20 - rsec =3D elf_create_section(elf, rsec_name, elf_rela_size(elf), reloc_nr); + rsec =3D elf_create_section(elf, rsec_name, reloc_nr * elf_rela_size(elf), + elf_rela_size(elf), SHT_RELA, elf_addr_size(elf), + SHF_INFO_LINK); free(rsec_name); if (!rsec) return NULL; =20 - rsec->data->d_type =3D ELF_T_RELA; - rsec->sh.sh_type =3D SHT_RELA; - rsec->sh.sh_addralign =3D elf_addr_size(elf); rsec->sh.sh_link =3D find_section_by_name(elf, ".symtab")->idx; rsec->sh.sh_info =3D sec->idx; - rsec->sh.sh_flags =3D SHF_INFO_LINK; =20 - rsec->relocs =3D calloc(sec_num_entries(rsec), sizeof(struct reloc)); - if (!rsec->relocs) { - ERROR_GLIBC("calloc"); - return NULL; + if (reloc_nr) { + rsec->data->d_type =3D ELF_T_RELA; + rsec->relocs =3D calloc(sec_num_entries(rsec), sizeof(struct reloc)); + if (!rsec->relocs) { + ERROR_GLIBC("calloc"); + return NULL; + } } =20 sec->rsec =3D rsec; @@ -1260,7 +1273,8 @@ struct section *elf_create_section_pair(struct elf *e= lf, const char *name, { struct section *sec; =20 - sec =3D elf_create_section(elf, name, entsize, nr); + sec =3D elf_create_section(elf, name, nr * entsize, entsize, + SHT_PROGBITS, 1, SHF_ALLOC); if (!sec) return NULL; =20 diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index ffdf9ec3882e..b366516b119d 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -116,11 +116,16 @@ struct elf { struct elf *elf_open_read(const char *name, int flags); =20 struct section *elf_create_section(struct elf *elf, const char *name, - size_t entsize, unsigned int nr); + size_t size, size_t entsize, + unsigned int type, unsigned int align, + unsigned int flags); struct section *elf_create_section_pair(struct elf *elf, const char *name, size_t entsize, unsigned int nr, unsigned int reloc_nr); =20 +struct section *elf_create_rela_section(struct elf *elf, struct section *s= ec, + unsigned int reloc_nr); + struct symbol *elf_create_symbol(struct elf *elf, const char *name, struct section *sec, unsigned int bind, unsigned int type, unsigned long offset, diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c index 6eff3d6a125c..9d380abc2ed3 100644 --- a/tools/objtool/orc_gen.c +++ b/tools/objtool/orc_gen.c @@ -127,7 +127,11 @@ int orc_create(struct objtool_file *file) return -1; } orc_sec =3D elf_create_section(file->elf, ".orc_unwind", - sizeof(struct orc_entry), nr); + nr * sizeof(struct orc_entry), + sizeof(struct orc_entry), + SHT_PROGBITS, + 1, + SHF_ALLOC); if (!orc_sec) return -1; =20 --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8FA03298998; Fri, 9 May 2025 20:18:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821892; cv=none; b=kva6unK4skBPQuva4MSR751CMiNlE6cr/HBrT1OgSkbZZvcYIJO33r3Ylf7WdUGyyxHOOvwz2n9Th7c2RvBOna1FDReWjgLbFjNmVJTdLv1KmGE9izgCxu7Md9RR7LYHtAx53W0gfTJ9uGkKaHsZ8S1v4mauLBJEwmpkbizTGiw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821892; c=relaxed/simple; bh=zsZfauCU6GgJ9tzyyCAWCfFGv5Mky/g31a415oAov7Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UlLh/dK8l5URWKEl9+ZSG3abL+6/+f+vcIo3TK4H2RNlQN4VOrvtVRYRJU2q1F1ihAm98XQee0BJ5Gw69ExKZHWnZRQIlfoEAW+OvBydZRxk9z0JFCO+swkbHz5bNF89GQCqfJBbjAllYezp0Eraz2p6qWbKLDs/P/pyxMbCqdU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pzdCprVN; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pzdCprVN" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E4544C4CEE9; Fri, 9 May 2025 20:18:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821892; bh=zsZfauCU6GgJ9tzyyCAWCfFGv5Mky/g31a415oAov7Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pzdCprVNi4eZPUsvPKMacTyN6dpgv1uyU01kh4ag1+4qiqiVIjqmuiOQtsvTZlLBa fvDEpoG5hlUt52OuBL6dwfHRpEBuaAksphi2TG+wEbYG/LjQ+BgarhcgJ2WA9nHrmL JVsEkEqvSU8zFNucIhTgVeSxXdhfRNgPszHxet4YXqRVucCKTZGHB5mtFUHVX+26Q0 dUGS4BHGgCg7AjR9DkaYbv4E4zrngpC3KDgU1EUiDJbWNt67G1JmEYSI1Gfn219kMw uC2HLt5XJNFeWWal2rUQqNeDJYhLVQcwN+Q4n8DINwpvIfElY6ZdjKEhTFBm0f8yMZ dIcg1Ea10Vjlg== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 39/62] objtool: Add elf_create_data() Date: Fri, 9 May 2025 13:17:03 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for the objtool klp diff subcommand, refactor elf_add_string() by adding a new elf_add_data() helper which allows the adding of arbitrary data to a section. Make both interfaces public so they can be used by the upcoming klp diff code. Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 66 ++++++++++++++++++++--------- tools/objtool/include/objtool/elf.h | 10 +++-- 2 files changed, 54 insertions(+), 22 deletions(-) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index c38b109f441f..1b5528065df7 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -18,10 +18,11 @@ #include #include #include - #include #include =20 +#define ALIGN_UP(x, align_to) (((x) + ((align_to)-1)) & ~((align_to)-1)) + static inline u32 str_hash(const char *str) { return jhash(str, strlen(str), 0); @@ -761,8 +762,6 @@ static int elf_update_symbol(struct elf *elf, struct se= ction *symtab, return 0; } =20 -static int elf_add_string(struct elf *elf, struct section *strtab, const c= har *str); - struct symbol *elf_create_symbol(struct elf *elf, const char *name, struct section *sec, unsigned int bind, unsigned int type, unsigned long offset, @@ -1098,11 +1097,9 @@ struct elf *elf_open_read(const char *name, int flag= s) return NULL; } =20 -static int elf_add_string(struct elf *elf, struct section *strtab, const c= har *str) +unsigned int elf_add_string(struct elf *elf, struct section *strtab, const= char *str) { - Elf_Data *data; - Elf_Scn *s; - int len; + unsigned int offset; =20 if (!strtab) strtab =3D find_section_by_name(elf, ".strtab"); @@ -1111,28 +1108,59 @@ static int elf_add_string(struct elf *elf, struct s= ection *strtab, const char *s return -1; } =20 - s =3D elf_getscn(elf->elf, strtab->idx); + if (!strtab->sh.sh_addralign) { + ERROR("'%s': invalid sh_addralign", strtab->name); + return -1; + } + + offset =3D ALIGN_UP(strtab->sh.sh_size, strtab->sh.sh_addralign); + + if (!elf_add_data(elf, strtab, str, strlen(str) + 1)) + return -1; + + return offset; +} + +void *elf_add_data(struct elf *elf, struct section *sec, const void *data,= size_t size) +{ + unsigned long offset; + Elf_Scn *s; + + if (!sec->sh.sh_addralign) { + ERROR("'%s': invalid sh_addralign", sec->name); + return NULL; + } + + s =3D elf_getscn(elf->elf, sec->idx); if (!s) { ERROR_ELF("elf_getscn"); - return -1; + return NULL; } =20 - data =3D elf_newdata(s); - if (!data) { + sec->data =3D elf_newdata(s); + if (!sec->data) { ERROR_ELF("elf_newdata"); - return -1; + return NULL; } =20 - data->d_buf =3D strdup(str); - data->d_size =3D strlen(str) + 1; - data->d_align =3D 1; + sec->data->d_buf =3D calloc(1, size); + if (!sec->data->d_buf) { + ERROR_GLIBC("calloc"); + return NULL; + } =20 - len =3D strtab->sh.sh_size; - strtab->sh.sh_size +=3D data->d_size; + if (data) + memcpy(sec->data->d_buf, data, size); =20 - mark_sec_changed(elf, strtab, true); + sec->data->d_size =3D size; + sec->data->d_align =3D 1; =20 - return len; + offset =3D ALIGN_UP(sec->sh.sh_size, sec->sh.sh_addralign); + sec->sh.sh_size =3D offset + size; + + mark_sec_changed(elf, sec, true); + + return sec->data->d_buf; } =20 struct section *elf_create_section(struct elf *elf, const char *name, diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index b366516b119d..fc00f86bedba 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -134,6 +134,10 @@ struct symbol *elf_create_section_symbol(struct elf *e= lf, struct section *sec); struct symbol *elf_create_prefix_symbol(struct elf *elf, struct symbol *or= ig, size_t size); =20 +void *elf_add_data(struct elf *elf, struct section *sec, const void *data, + size_t size); + +unsigned int elf_add_string(struct elf *elf, struct section *strtab, const= char *str); =20 struct reloc *elf_init_reloc_text_sym(struct elf *elf, struct section *sec, unsigned long offset, @@ -147,9 +151,9 @@ struct reloc *elf_init_reloc_data_sym(struct elf *elf, = struct section *sec, struct symbol *sym, s64 addend); =20 -int elf_write_insn(struct elf *elf, struct section *sec, - unsigned long offset, unsigned int len, - const char *insn); +int elf_write_insn(struct elf *elf, struct section *sec, unsigned long off= set, + unsigned int len, const char *insn); + int elf_write(struct elf *elf); void elf_close(struct elf *elf); =20 --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 48E6F2989AF; Fri, 9 May 2025 20:18:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821893; cv=none; b=MZofZYmTuF92THmJKNaPWOMZSlEF3iI6BmF2Wsj/OYetre1W6dqKsBOOkKP78b1K5q+v7sQ2B6ibXvgjWh3LzMcfVc2YBLB7Ao98qW/Wm3rXzwmcADmR7Ohht2zYZLJBStmo93AzmLttyO28Uod54R9yL1c2eAy1FKi8mF7tsiU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821893; c=relaxed/simple; bh=g3favnQ2TasT07axjoxQsRRs95xIcj3hy0hj5Qm7MVQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FCd2fJKNOH4suGTPVTYP7CZBjZof/lNzYC0DsxnDGNV1pd2pGOCGC2d6Dd+5w8VcxTcq+B00wgGYw0qBcfRKPNvxkXUk4/gYg4irKgyL3VtR8yFlA/VNT3bq2SK3xN0os4jQRsKoto78wxpSY1IZtZ5bwWXNDPJRvgnHGMW0XP4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eDMKCPXc; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="eDMKCPXc" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9B6A3C4CEE4; Fri, 9 May 2025 20:18:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821893; bh=g3favnQ2TasT07axjoxQsRRs95xIcj3hy0hj5Qm7MVQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eDMKCPXcHmKQq6TFumRtM7si9IejQD31KydsxGJqnYYJ7dR6zkcBAJE5GSP5owKAZ jB2IULLblNQyheueODNyO6Psux44q1+bYDQnH2k6VD8vk/pps5Phx4DdnD/+J8isr6 DutD3ozAjD2KTtr0312Axzu5MXUwgJhc0OP1Ltr/3oTQfMarC6rFUnvFi+Cgykn2H2 frtBQCnoNFwZX3INp+bTtL2TBLRchO4xcMz4CLZXFqs0AiZxSCT3Ln44VmkOL5goNy 1kPdhYd+JO4soKtpMkLOReZYgJ7+8bFQpm1HLNnMAW4MJ57zEWEESIYOe2fnjdfiyH cFUby31vXkvKw== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 40/62] objtool: Introduce elf_create_reloc() and elf_init_reloc() Date: Fri, 9 May 2025 13:17:04 -0700 Message-ID: <8c045c6e3048507898e9229ddd1aa7eb9ecbd0f6.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" elf_create_rela_section() is quite limited in that it requires the caller to know how many relocations need to be allocated up front. In preparation for the objtool klp diff subcommand, allow an arbitrary number of relocations to be created and initialized on demand after section creation. Signed-off-by: Josh Poimboeuf --- tools/objtool/elf.c | 151 +++++++++++++++++++++++++--- tools/objtool/include/objtool/elf.h | 9 ++ 2 files changed, 145 insertions(+), 15 deletions(-) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 1b5528065df7..8fc6e6c75b88 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -22,6 +22,8 @@ #include =20 #define ALIGN_UP(x, align_to) (((x) + ((align_to)-1)) & ~((align_to)-1)) +#define ALIGN_UP_POW2(x) (1U << ((8 * sizeof(x)) - __builtin_clz((x) - 1U)= )) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) =20 static inline u32 str_hash(const char *str) { @@ -897,10 +899,9 @@ elf_create_prefix_symbol(struct elf *elf, struct symbo= l *orig, size_t size) offset, size); } =20 -static struct reloc *elf_init_reloc(struct elf *elf, struct section *rsec, - unsigned int reloc_idx, - unsigned long offset, struct symbol *sym, - s64 addend, unsigned int type) +struct reloc *elf_init_reloc(struct elf *elf, struct section *rsec, + unsigned int reloc_idx, unsigned long offset, + struct symbol *sym, s64 addend, unsigned int type) { struct reloc *reloc, empty =3D { 0 }; =20 @@ -1002,12 +1003,14 @@ static int read_relocs(struct elf *elf) =20 rsec->base->rsec =3D rsec; =20 - nr_reloc =3D 0; - rsec->relocs =3D calloc(sec_num_entries(rsec), sizeof(*reloc)); + rsec->nr_alloc_relocs =3D sec_num_entries(rsec); + rsec->relocs =3D calloc(rsec->nr_alloc_relocs, sizeof(*reloc)); if (!rsec->relocs) { ERROR_GLIBC("calloc"); return -1; } + + nr_reloc =3D 0; for (i =3D 0; i < sec_num_entries(rsec); i++) { reloc =3D &rsec->relocs[i]; =20 @@ -1256,8 +1259,99 @@ struct section *elf_create_section(struct elf *elf, = const char *name, return sec; } =20 +static int elf_alloc_reloc(struct elf *elf, struct section *rsec) +{ + struct reloc *old_relocs, *old_relocs_end, *new_relocs; + unsigned int nr_relocs_old =3D sec_num_entries(rsec); + unsigned int nr_relocs_new =3D nr_relocs_old + 1; + unsigned long nr_alloc; + struct symbol *sym; + + if (!rsec->data) { + rsec->data =3D elf_newdata(elf_getscn(elf->elf, rsec->idx)); + if (!rsec->data) { + ERROR_ELF("elf_newdata"); + return -1; + } + + rsec->data->d_align =3D 1; + rsec->data->d_type =3D ELF_T_RELA; + rsec->data->d_buf =3D NULL; + } + + rsec->data->d_size =3D nr_relocs_new * elf_rela_size(elf); + rsec->sh.sh_size =3D rsec->data->d_size; + + nr_alloc =3D MAX(64, ALIGN_UP_POW2(nr_relocs_new)); + if (nr_alloc <=3D rsec->nr_alloc_relocs) + return 0; + rsec->nr_alloc_relocs =3D nr_alloc; + + rsec->data->d_buf =3D realloc(rsec->data->d_buf, + nr_alloc * elf_rela_size(elf)); + if (!rsec->data->d_buf) { + ERROR_GLIBC("realloc"); + return -1; + } + + old_relocs =3D rsec->relocs; + new_relocs =3D calloc(nr_alloc, sizeof(struct reloc)); + if (!new_relocs) { + ERROR_GLIBC("calloc"); + return -1; + } + + if (!old_relocs) + goto done; + + /* + * The struct reloc's address has changed. Update all the symbols and + * relocs which reference it. + */ + + old_relocs_end =3D &old_relocs[nr_relocs_old]; + for_each_sym(elf, sym) { + struct reloc *reloc; + + reloc =3D sym->relocs; + if (!reloc) + continue; + + if (reloc >=3D old_relocs && reloc < old_relocs_end) + sym->relocs =3D &new_relocs[reloc - old_relocs]; + + while (1) { + struct reloc *next_reloc =3D sym_next_reloc(reloc); + + if (!next_reloc) + break; + + if (next_reloc >=3D old_relocs && next_reloc < old_relocs_end) + set_sym_next_reloc(reloc, &new_relocs[next_reloc - old_relocs]); + + reloc =3D next_reloc; + } + } + + memcpy(new_relocs, old_relocs, nr_relocs_old * sizeof(struct reloc)); + + for (int i =3D 0; i < nr_relocs_old; i++) { + struct reloc *old =3D &old_relocs[i]; + struct reloc *new =3D &new_relocs[i]; + u32 key =3D reloc_hash(old); + + elf_hash_del(reloc, &old->hash, key); + elf_hash_add(reloc, &new->hash, key); + } + + free(old_relocs); +done: + rsec->relocs =3D new_relocs; + return 0; +} + struct section *elf_create_rela_section(struct elf *elf, struct section *s= ec, - unsigned int reloc_nr) + unsigned int nr_relocs) { struct section *rsec; char *rsec_name; @@ -1270,34 +1364,61 @@ struct section *elf_create_rela_section(struct elf = *elf, struct section *sec, strcpy(rsec_name, ".rela"); strcat(rsec_name, sec->name); =20 - rsec =3D elf_create_section(elf, rsec_name, reloc_nr * elf_rela_size(elf), + rsec =3D elf_create_section(elf, rsec_name, nr_relocs * elf_rela_size(elf= ), elf_rela_size(elf), SHT_RELA, elf_addr_size(elf), SHF_INFO_LINK); free(rsec_name); if (!rsec) return NULL; =20 - rsec->sh.sh_link =3D find_section_by_name(elf, ".symtab")->idx; - rsec->sh.sh_info =3D sec->idx; - - if (reloc_nr) { + if (nr_relocs) { rsec->data->d_type =3D ELF_T_RELA; - rsec->relocs =3D calloc(sec_num_entries(rsec), sizeof(struct reloc)); + + rsec->nr_alloc_relocs =3D nr_relocs; + rsec->relocs =3D calloc(nr_relocs, sizeof(struct reloc)); if (!rsec->relocs) { ERROR_GLIBC("calloc"); return NULL; } } =20 + rsec->sh.sh_link =3D find_section_by_name(elf, ".symtab")->idx; + rsec->sh.sh_info =3D sec->idx; + sec->rsec =3D rsec; rsec->base =3D sec; =20 return rsec; } =20 +struct reloc *elf_create_reloc(struct elf *elf, struct section *sec, + unsigned long offset, + struct symbol *sym, s64 addend, + unsigned int type) +{ + struct section *rsec =3D sec->rsec; + + if (!rsec) { + rsec =3D elf_create_rela_section(elf, sec, 0); + if (!rsec) + return NULL; + } + + if (find_reloc_by_dest(elf, sec, offset)) { + ERROR_FUNC(sec, offset, "duplicate reloc"); + return NULL; + } + + if (elf_alloc_reloc(elf, rsec)) + return NULL; + + return elf_init_reloc(elf, rsec, sec_num_entries(rsec) - 1, offset, sym, + addend, type); +} + struct section *elf_create_section_pair(struct elf *elf, const char *name, size_t entsize, unsigned int nr, - unsigned int reloc_nr) + unsigned int nr_relocs) { struct section *sec; =20 @@ -1306,7 +1427,7 @@ struct section *elf_create_section_pair(struct elf *e= lf, const char *name, if (!sec) return NULL; =20 - if (!elf_create_rela_section(elf, sec, reloc_nr)) + if (!elf_create_rela_section(elf, sec, nr_relocs)) return NULL; =20 return sec; diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index fc00f86bedba..5c663e475890 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -47,6 +47,7 @@ struct section { int idx; bool _changed, text, rodata, noinstr, init, truncate; struct reloc *relocs; + unsigned long nr_alloc_relocs; }; =20 struct symbol { @@ -139,6 +140,14 @@ void *elf_add_data(struct elf *elf, struct section *se= c, const void *data, =20 unsigned int elf_add_string(struct elf *elf, struct section *strtab, const= char *str); =20 +struct reloc *elf_create_reloc(struct elf *elf, struct section *sec, + unsigned long offset, struct symbol *sym, + s64 addend, unsigned int type); + +struct reloc *elf_init_reloc(struct elf *elf, struct section *rsec, + unsigned int reloc_idx, unsigned long offset, + struct symbol *sym, s64 addend, unsigned int type); + struct reloc *elf_init_reloc_text_sym(struct elf *elf, struct section *sec, unsigned long offset, unsigned int reloc_idx, --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 08D85298C10; Fri, 9 May 2025 20:18:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821894; cv=none; b=Ui8Bftu4g0SOhy+2Mtm4OMtSSM0SZePg6szid7myRGW0dC7H3oyEG9jnlWPDSqUm7golzpRvgYVjoPcwbHQ607qPsS9wv7PyM/KE/TaBeWVC5+1GuPqtaLSeY/otTNymgIkZqAOk1nKrIClsBjx5WYTQt1GOUATzbqUV4mRPOGo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821894; c=relaxed/simple; bh=+noZmweQm+RBqECCFwqV789efebiB0bLMqaVRLOtst4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dSRD684/1ntwVX3rQdncqWKtEVfyEEVCNpHlujKQddY7WpSx/2o0Swggr8b5VclGvaZ4efPw64NykQR0StgQW6r00RyR75gAKyWGpAfWOxep0uNDb3WRy7pv8Vg3xXp7H2AYfliYP5VvO2NF/UiMhAAs4QgMlZlcHgIvgWb/PeQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=sEKJXG8P; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="sEKJXG8P" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 50FCBC4CEEF; Fri, 9 May 2025 20:18:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821893; bh=+noZmweQm+RBqECCFwqV789efebiB0bLMqaVRLOtst4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sEKJXG8PyBv3iBH0rjIuwIWYtWKqU3VA+I0gXPwMB5h7AfqmZvFEA9IXncHe4VmJa OYjETr7+PBRUQhTvfKaoTOJUqbkfDvQW0WT6A0LTY01+d1DOi5DNmPGoxp9L2Kifx1 J6hweJxuRuRAXpzXSPsv8FQVaS5neasZ85rIFTe/8h+RgMTB9bQxwBfBfd981T6hJa qMD+KuwevaFY9+DDrkU+nZmPqUgJxCYRfhfvdMZ2Nn4bsQ3HOZCqgiRQmgPQ2iMdMh FXa9BGxq82TggAHy5LThgQLZZYQPG2nkKq8M6UyO9GxlOo1Du7NllP0XNAZ5mhaQJV BXljUcS0+OgNw== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 41/62] objtool: Add elf_create_file() Date: Fri, 9 May 2025 13:17:05 -0700 Message-ID: <11abeda8e7cbb18f8c32acd4492f93c63049a646.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add interface to enable the creation of a new ELF file. Signed-off-by: Josh Poimboeuf --- tools/objtool/builtin-check.c | 2 +- tools/objtool/elf.c | 144 +++++++++++++++++++++++++++- tools/objtool/include/objtool/elf.h | 5 +- 3 files changed, 147 insertions(+), 4 deletions(-) diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index 56388bb98785..c7bab6a39ca1 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -330,5 +330,5 @@ int objtool_run(int argc, const char **argv) if (!opts.dryrun && file->elf->changed && elf_write(file->elf)) return 1; =20 - return 0; + return elf_close(file->elf); } diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 8fc6e6c75b88..5e7620824136 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -1063,6 +1064,12 @@ struct elf *elf_open_read(const char *name, int flag= s) goto err; } =20 + elf->name =3D strdup(name); + if (!elf->name) { + ERROR_GLIBC("strdup"); + return NULL; + } + if ((flags & O_ACCMODE) =3D=3D O_RDONLY) cmd =3D ELF_C_READ_MMAP; else if ((flags & O_ACCMODE) =3D=3D O_RDWR) @@ -1100,6 +1107,137 @@ struct elf *elf_open_read(const char *name, int fla= gs) return NULL; } =20 +struct elf *elf_create_file(GElf_Ehdr *ehdr, const char *name) +{ + struct section *null, *symtab, *strtab, *shstrtab; + char *dir, *base, *tmp_name; + struct symbol *sym; + struct elf *elf; + + elf_version(EV_CURRENT); + + elf =3D calloc(1, sizeof(*elf)); + if (!elf) { + ERROR_GLIBC("calloc"); + return NULL; + } + + INIT_LIST_HEAD(&elf->sections); + + dir =3D strdup(name); + if (!dir) { + ERROR_GLIBC("strdup"); + return NULL; + } + + dir =3D dirname(dir); + + base =3D strdup(name); + if (!base) { + ERROR_GLIBC("strdup"); + return NULL; + } + + base =3D basename(base); + + tmp_name =3D malloc(256); + if (!tmp_name) { + ERROR_GLIBC("malloc"); + return NULL; + } + + snprintf(tmp_name, 256, "%s/%s.XXXXXX", dir, base); + + elf->fd =3D mkstemp(tmp_name); + if (elf->fd =3D=3D -1) { + ERROR_GLIBC("can't create tmp file"); + exit(1); + } + + elf->tmp_name =3D tmp_name; + + elf->name =3D strdup(name); + if (!elf->name) { + ERROR_GLIBC("strdup"); + return NULL; + } + + elf->elf =3D elf_begin(elf->fd, ELF_C_WRITE, NULL); + if (!elf->elf) { + ERROR_ELF("elf_begin"); + return NULL; + } + + if (!gelf_newehdr(elf->elf, ELFCLASS64)) { + ERROR_ELF("gelf_newehdr"); + return NULL; + } + + memcpy(&elf->ehdr, ehdr, sizeof(elf->ehdr)); + + if (!gelf_update_ehdr(elf->elf, &elf->ehdr)) { + ERROR_ELF("gelf_update_ehdr"); + return NULL; + } + + if (!elf_alloc_hash(section, 1000) || + !elf_alloc_hash(section_name, 1000) || + !elf_alloc_hash(symbol, 10000) || + !elf_alloc_hash(symbol_name, 10000) || + !elf_alloc_hash(reloc, 100000)) + return NULL; + + null =3D elf_create_section(elf, NULL, 0, 0, SHT_NULL, 0, 0); + shstrtab =3D elf_create_section(elf, NULL, 0, 0, SHT_STRTAB, 1, 0); + strtab =3D elf_create_section(elf, NULL, 0, 0, SHT_STRTAB, 1, 0); + + if (!null || !shstrtab || !strtab) + return NULL; + + null->name =3D ""; + shstrtab->name =3D ".shstrtab"; + strtab->name =3D ".strtab"; + + null->sh.sh_name =3D elf_add_string(elf, shstrtab, null->name); + shstrtab->sh.sh_name =3D elf_add_string(elf, shstrtab, shstrtab->name); + strtab->sh.sh_name =3D elf_add_string(elf, shstrtab, strtab->name); + + if (null->sh.sh_name =3D=3D -1 || shstrtab->sh.sh_name =3D=3D -1 || strta= b->sh.sh_name =3D=3D -1) + return NULL; + + elf_hash_add(section_name, &null->name_hash, str_hash(null->name)); + elf_hash_add(section_name, &strtab->name_hash, str_hash(strtab->name)); + elf_hash_add(section_name, &shstrtab->name_hash, str_hash(shstrtab->name)= ); + + if (elf_add_string(elf, strtab, "") =3D=3D -1) + return NULL; + + symtab =3D elf_create_section(elf, ".symtab", 0x18, 0x18, SHT_SYMTAB, 0x8= , 0); + if (!symtab) + return NULL; + + symtab->sh.sh_link =3D strtab->idx; + symtab->sh.sh_info =3D 1; + + elf->ehdr.e_shstrndx =3D shstrtab->idx; + if (!gelf_update_ehdr(elf->elf, &elf->ehdr)) { + ERROR_ELF("gelf_update_ehdr"); + return NULL; + } + + sym =3D calloc(1, sizeof(*sym)); + if (!sym) { + ERROR_GLIBC("calloc"); + return NULL; + } + + sym->name =3D ""; + sym->sec =3D null; + elf_add_symbol(elf, sym); + + return elf; +} + unsigned int elf_add_string(struct elf *elf, struct section *strtab, const= char *str) { unsigned int offset; @@ -1545,7 +1683,7 @@ int elf_write(struct elf *elf) return 0; } =20 -void elf_close(struct elf *elf) +int elf_close(struct elf *elf) { if (elf->elf) elf_end(elf->elf); @@ -1553,8 +1691,12 @@ void elf_close(struct elf *elf) if (elf->fd > 0) close(elf->fd); =20 + if (elf->tmp_name && rename(elf->tmp_name, elf->name)) + return -1; + /* * NOTE: All remaining allocations are leaked on purpose. Objtool is * about to exit anyway. */ + return 0; } diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index 5c663e475890..a0fc252e1993 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -93,7 +93,7 @@ struct elf { GElf_Ehdr ehdr; int fd; bool changed; - const char *name; + const char *name, *tmp_name; unsigned int num_files; struct list_head sections; unsigned long num_relocs; @@ -115,6 +115,7 @@ struct elf { }; =20 struct elf *elf_open_read(const char *name, int flags); +struct elf *elf_create_file(GElf_Ehdr *ehdr, const char *name); =20 struct section *elf_create_section(struct elf *elf, const char *name, size_t size, size_t entsize, @@ -164,7 +165,7 @@ int elf_write_insn(struct elf *elf, struct section *sec= , unsigned long offset, unsigned int len, const char *insn); =20 int elf_write(struct elf *elf); -void elf_close(struct elf *elf); +int elf_close(struct elf *elf); =20 struct section *find_section_by_name(const struct elf *elf, const char *na= me); struct symbol *find_func_by_offset(struct section *sec, unsigned long offs= et); --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AE621298C1E; Fri, 9 May 2025 20:18:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821894; cv=none; b=Fp+C3oFW8pimjDOgtJ8+We3l4IzMOfYuwSHkpxjf9df5SQoxWQGoiY0VGg6putdi6jpkABOqqDiDv2V1cac7rH5eAUvjbDiiM09p7tVqDxbGMpyoeOUrjxAgqIn3g/F10QUcSCqcIgDiRCxhdy1KHMMpNyPYePPGQnNn2Wo7K+o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821894; c=relaxed/simple; bh=IhnT+r49yQN4Y1vAs0J9seA0eXIHcLBZGuntccFA4aA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FUvKaYeq2ca2RaUXdT4T2t1Dpyt97rCyMyyjd/GWrwSUvRIHX2j9Dtl3oH6QkpuHC6L/bIYiK2a3tOyZb5apVymr4HA/bSrK/oGvamzngu8UBYvMvzy7qOuW9I57TzYAe2yJWep4Rp6/VBloy8/hL3mP3o83amRZUog8oRoQMmM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tuWE7pU7; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="tuWE7pU7" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 06959C4CEF0; Fri, 9 May 2025 20:18:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821894; bh=IhnT+r49yQN4Y1vAs0J9seA0eXIHcLBZGuntccFA4aA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tuWE7pU7RSzZNmBvmhn00fdV48l53J+oBWohl4y6kQByZkjRlt49L1x502gQOmmBO h7dIaPfoECyINvXUuqViJSEJ7+ym3JCgO2dm/AZ4bc0uYXPoixpWBh/yGizKZ5nTPD 9F6FDn9WGmIj9hD1cEDkxG8Qa5DBjCtn4OxiR2Kgx8g0lSQVdIp+H+mVd7S5Xx7WC7 VmUWQSkZ1iadFN0EXXY/rc+mnZ/C2CItu5/lONm+PTO0WnTa22SQc6oyV86p2OgSKX xgv7BJQcMrg1hVqVLlU/IzgY9GaGfTEdlPKQQSTAHNwPtEHf4rmVLHjhusogyLZS6K +sU2yi5oXde+g== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan , Masahiro Yamada Subject: [PATCH v2 42/62] kbuild,x86: Fix module permissions for __jump_table and __bug_table Date: Fri, 9 May 2025 13:17:06 -0700 Message-ID: <9da1e9f592aadc8fbf48b7429e3fbcea4606a76a.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" An upcoming patch will add the SHF_MERGE flag to x86 __jump_table and __bug_table so their entry sizes can be defined in inline asm. However, those sections have SHF_WRITE, which the Clang linker (lld) explicitly forbids combining with SHF_MERGE. Those sections are modified at runtime and must remain writable. While SHF_WRITE is ignored by vmlinux, it's still needed for modules. To work around the linker interference, remove SHF_WRITE during compilation and restore it after linking the module. Cc: Masahiro Yamada Signed-off-by: Josh Poimboeuf --- arch/Kconfig | 3 +++ arch/x86/Kconfig | 1 + arch/x86/include/asm/bug.h | 4 ++-- arch/x86/include/asm/jump_label.h | 2 +- scripts/Makefile.modfinal | 18 +++++++++++++----- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index b0adb665041f..a413cd86f87c 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -1314,6 +1314,9 @@ config HAVE_NOINSTR_HACK config HAVE_NOINSTR_VALIDATION bool =20 +config NEED_MODULE_PERMISSIONS_FIX + bool + config HAVE_UACCESS_VALIDATION bool select OBJTOOL diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 4c33c644b92d..996d59e59e5d 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -309,6 +309,7 @@ config X86 select HOTPLUG_SPLIT_STARTUP if SMP && X86_32 select IRQ_FORCED_THREADING select LOCK_MM_AND_FIND_VMA + select NEED_MODULE_PERMISSIONS_FIX select NEED_PER_CPU_EMBED_FIRST_CHUNK select NEED_PER_CPU_PAGE_FIRST_CHUNK select NEED_SG_DMA_LENGTH diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h index f0e9acf72547..fb3534ddbea2 100644 --- a/arch/x86/include/asm/bug.h +++ b/arch/x86/include/asm/bug.h @@ -42,7 +42,7 @@ #define _BUG_FLAGS(ins, flags, extra) \ do { \ asm_inline volatile("1:\t" ins "\n" \ - ".pushsection __bug_table,\"aw\"\n" \ + ".pushsection __bug_table,\"a\"\n" \ "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n" \ "\t" __BUG_REL(%c0) "\t# bug_entry::file\n" \ "\t.word %c1" "\t# bug_entry::line\n" \ @@ -60,7 +60,7 @@ do { \ #define _BUG_FLAGS(ins, flags, extra) \ do { \ asm_inline volatile("1:\t" ins "\n" \ - ".pushsection __bug_table,\"aw\"\n" \ + ".pushsection __bug_table,\"a\"\n" \ "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n" \ "\t.word %c0" "\t# bug_entry::flags\n" \ "\t.org 2b+%c1\n" \ diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_= label.h index 61dd1dee7812..cd21554b3675 100644 --- a/arch/x86/include/asm/jump_label.h +++ b/arch/x86/include/asm/jump_label.h @@ -13,7 +13,7 @@ #include =20 #define JUMP_TABLE_ENTRY(key, label) \ - ".pushsection __jump_table, \"aw\" \n\t" \ + ".pushsection __jump_table, \"a\"\n\t" \ _ASM_ALIGN "\n\t" \ ".long 1b - . \n\t" \ ".long " label " - . \n\t" \ diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 542ba462ed3e..878d0d25a461 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -28,12 +28,23 @@ ccflags-remove-y :=3D $(CC_FLAGS_CFI) .module-common.o: $(srctree)/scripts/module-common.c FORCE $(call if_changed_rule,cc_o_c) =20 +ifdef CONFIG_NEED_MODULE_PERMISSIONS_FIX +cmd_fix_mod_permissions =3D \ + $(OBJCOPY) --set-section-flags __jump_table=3Dalloc,data \ + --set-section-flags __bug_table=3Dalloc,data $@ +endif + quiet_cmd_ld_ko_o =3D LD [M] $@ cmd_ld_ko_o =3D \ $(LD) -r $(KBUILD_LDFLAGS) \ $(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \ -T $(objtree)/scripts/module.lds -o $@ $(filter %.o, $^) =20 +define rule_ld_ko_o + $(call cmd_and_savecmd,ld_ko_o) + $(call cmd,fix_mod_permissions) +endef + quiet_cmd_btf_ko =3D BTF [M] $@ cmd_btf_ko =3D \ if [ ! -f $(objtree)/vmlinux ]; then \ @@ -46,14 +57,11 @@ quiet_cmd_btf_ko =3D BTF [M] $@ # Same as newer-prereqs, but allows to exclude specified extra dependencies newer_prereqs_except =3D $(filter-out $(PHONY) $(1),$?) =20 -# Same as if_changed, but allows to exclude specified extra dependencies -if_changed_except =3D $(if $(call newer_prereqs_except,$(2))$(cmd-check), = \ - $(cmd); \ - printf '%s\n' 'savedcmd_$@ :=3D $(make-cmd)' > $(dot-target).cmd, @:) +if_changed_rule_except =3D $(if $(call newer_prereqs_except,$(2))$(cmd-che= ck),$(rule_$(1)),@:) =20 # Re-generate module BTFs if either module's .ko or vmlinux changed %.ko: %.o %.mod.o .module-common.o $(objtree)/scripts/module.lds $(and $(C= ONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),$(objtree)/vmlinux) FORCE - +$(call if_changed_except,ld_ko_o,$(objtree)/vmlinux) + +$(call if_changed_rule_except,ld_ko_o,$(objtree)/vmlinux) ifdef CONFIG_DEBUG_INFO_BTF_MODULES +$(if $(newer-prereqs),$(call cmd,btf_ko)) endif --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5EAA82989BE; Fri, 9 May 2025 20:18:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821895; cv=none; b=isWyuXUnrMEFbV+MW+D/yHD2SxGYDPApdpHTNsL+yExHIlutgtprdGlkSszm/t+19rmzw8bPKekAJIcINjE8/UeqTSSarU8XXMEMSB8Rl8Pm6bCoWDjeyW3RsOKma/kap2cWi/1d19LKoqThHPXFQxV+W6vbgJ+cFzc8O24gKMA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821895; c=relaxed/simple; bh=qq4f5X+mxLUKb++5vZav/c3qryo3uTpZCBcDBFGdgf4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IIduZD/mfuIophoI+dNL5Agx9+NUFI4/YPsQI71G0udAFbmOxhGhHas/WwiSIpH97nnf9x1lMFrn7tFjpDyEegm2W2ZzvVg/jLrLL5yQ8CSkzg9/YMe1753gQ2puCQbaJ9NShvxZZ5Fdxb3fR2L5mTXgTOH1W0fa9FKwtQhV8JQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=o8kDWFzX; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="o8kDWFzX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B7CFFC4CEEE; Fri, 9 May 2025 20:18:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821895; bh=qq4f5X+mxLUKb++5vZav/c3qryo3uTpZCBcDBFGdgf4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=o8kDWFzXS83Iyi+N9p8zX6i42iFDnHc8Ki0qZzyrTt54BAbpbhq/FIE00nYSsZRiH MZ59/aSlw8uYvBDHnogGYxlj3XeMHtBNJRS1gw7rqbcIQbg1h17m91vtHkTFtP9Drq 13XMlLI2Ku+mNLXcRGxjjVeyaHo3yIyrZShiXMMqdNcPUIL/5oedAbJINgCrIpvmDA CiKz2cYQBg3svOdQKgQJ1sG52997YYjig6z9GMU0/NY1uFj6BW6/zTqtR5BQ6pxXa+ aNm7/0Me/d2myIfpb9QICEo7gMRbSgPw0+cxWPC4t0ee46ArrHr1M2WUHE3v4fw3Zg 38XVPcXnozNIA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 43/62] x86/alternative: Define ELF section entry size for alternatives Date: Fri, 9 May 2025 13:17:07 -0700 Message-ID: <68a8126c21f4ee054d6c4d6262d0f465b5babd89.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for the objtool klp diff subcommand, define the entry size for the .altinstructions section in its ELF header. This will allow tooling to extract individual entries. Signed-off-by: Josh Poimboeuf --- arch/x86/include/asm/alternative.h | 7 +++++-- arch/x86/kernel/alternative.c | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alte= rnative.h index e18cdaa1573c..212761eec886 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h @@ -15,6 +15,8 @@ #define ALT_DIRECT_CALL(feature) ((ALT_FLAG_DIRECT_CALL << ALT_FLAGS_SHIFT= ) | (feature)) #define ALT_CALL_ALWAYS ALT_DIRECT_CALL(X86_FEATURE_ALWAYS) =20 +#define ALTINSTR_SIZE 14 + #ifndef __ASSEMBLER__ =20 #include @@ -165,7 +167,8 @@ static inline int alternatives_text_reserved(void *star= t, void *end) "773:\n" =20 #define ALTINSTR_ENTRY(ft_flags) \ - ".pushsection .altinstructions,\"a\"\n" \ + ".pushsection .altinstructions, \"aM\", @progbits, " \ + __stringify(ALTINSTR_SIZE) "\n" \ " .long 771b - .\n" /* label */ \ " .long 774f - .\n" /* new instruction */ \ " .4byte " __stringify(ft_flags) "\n" /* feature + flags */ \ @@ -328,7 +331,7 @@ void nop_func(void); 741: \ .skip -(((744f-743f)-(741b-740b)) > 0) * ((744f-743f)-(741b-740b)),0x90 ;\ 742: \ - .pushsection .altinstructions,"a" ; \ + .pushsection .altinstructions, "aM", @progbits, ALTINSTR_SIZE ; \ altinstr_entry 740b,743f,flag,742b-740b,744f-743f ; \ .popsection ; \ .pushsection .altinstr_replacement,"ax" ; \ diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index ec220e53cb52..d6064dd87dde 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -425,6 +425,8 @@ void __init_or_module noinline apply_alternatives(struc= t alt_instr *start, u8 *instr, *replacement; struct alt_instr *a, *b; =20 + BUILD_BUG_ON(ALTINSTR_SIZE !=3D sizeof(struct alt_instr)); + DPRINTK(ALT, "alt table %px, -> %px", start, end); =20 /* --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1843E298CBE; Fri, 9 May 2025 20:18:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821896; cv=none; b=ZN1egAaihfyLsc3zioLx8wlJ/15zm9KsXAREGXX2L6U4ftK2uIhdIExcxGtoSe++ZpWlnZjDnxMyPuPIIFby2yxKVCTHjSXKiws07gHfk7CmEPDsGJ/cYMfOxmLEzlUSiCBp8FAx+duuv41eV4e2x2AHCCge+kDfhksdTV09tbU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821896; c=relaxed/simple; bh=WrGEyNHSSw7Wx3DQ3criX7+p62Pve6p0318/Ksge9cQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jzKGUPZDP94oTjbzP97cYt18MyQJZiJQuHjFhFG1Fayr+N1yFj5PVLsA8koHe2hQtR6AbSgu7LPU3R7XDQWmpDgargSj3EHuOGKN1WJ8IyV8J6DOpuqHzacGElFteKbGBluRJMhhqbBHqnfhqpyO0DjKGZRdAPmu3YOQaNf7HFw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tx+VTOuN; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="tx+VTOuN" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6F3EFC4CEEF; Fri, 9 May 2025 20:18:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821896; bh=WrGEyNHSSw7Wx3DQ3criX7+p62Pve6p0318/Ksge9cQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tx+VTOuNeOAdNveLRr8D1TBDpGlVVTpewtqyC5XNZaf65xWLv9JRKOVIQrQwl2BnS kZt7OsU+avOREH80V0YaZFvgP5suwYeruN5UtG9oJDRzTWEtpeBkSExPmirmza81yt KQMQSpYcIGLggP0DOAOTyuMltPXcUI0Vu7jih6D3C1LFafvON+dMy5TPGoN9i+iI1q 4f9yS1wCDLWqv14zB/2+ZEpNgm0wZa8VUbZMNCY3AugEX2L7TK8pnOvUYWKVAjR/PK 01rbpGbAcJpuzJblDPaQZjNE27p7ZTIxwYOZC6APKV7hAqqS20VhYAYRXSk1oFtgjG 941II6UNRIcSQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 44/62] x86/jump_label: Define ELF section entry size for jump table Date: Fri, 9 May 2025 13:17:08 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for the objtool klp diff subcommand, define the entry size for the __jump_table section in its ELF header. This will allow tooling to extract individual entries. Signed-off-by: Josh Poimboeuf --- arch/x86/include/asm/jump_label.h | 32 +++++++++++++++++-------------- include/linux/jump_label.h | 20 +++++++++++-------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_= label.h index cd21554b3675..6081c33e1566 100644 --- a/arch/x86/include/asm/jump_label.h +++ b/arch/x86/include/asm/jump_label.h @@ -12,29 +12,31 @@ #include #include =20 -#define JUMP_TABLE_ENTRY(key, label) \ - ".pushsection __jump_table, \"a\"\n\t" \ - _ASM_ALIGN "\n\t" \ - ".long 1b - . \n\t" \ - ".long " label " - . \n\t" \ - _ASM_PTR " " key " - . \n\t" \ +#define JUMP_TABLE_ENTRY(key, label, size) \ + ".pushsection __jump_table, \"aM\", @progbits, " size "\n\t" \ + _ASM_ALIGN "\n\t" \ + ".long 1b - . \n\t" \ + ".long " label " - . \n\t" \ + _ASM_PTR " " key " - . \n\t" \ ".popsection \n\t" =20 /* This macro is also expanded on the Rust side. */ #ifdef CONFIG_HAVE_JUMP_LABEL_HACK -#define ARCH_STATIC_BRANCH_ASM(key, label) \ +#define ARCH_STATIC_BRANCH_ASM(key, label, size) \ "1: jmp " label " # objtool NOPs this \n\t" \ - JUMP_TABLE_ENTRY(key " + 2", label) + JUMP_TABLE_ENTRY(key " + 2", label, size) #else /* !CONFIG_HAVE_JUMP_LABEL_HACK */ -#define ARCH_STATIC_BRANCH_ASM(key, label) \ +#define ARCH_STATIC_BRANCH_ASM(key, label, size) \ "1: .byte " __stringify(BYTES_NOP5) "\n\t" \ - JUMP_TABLE_ENTRY(key, label) + JUMP_TABLE_ENTRY(key, label, size) #endif /* CONFIG_HAVE_JUMP_LABEL_HACK */ =20 static __always_inline bool arch_static_branch(struct static_key * const k= ey, const bool branch) { - asm goto(ARCH_STATIC_BRANCH_ASM("%c0 + %c1", "%l[l_yes]") - : : "i" (key), "i" (branch) : : l_yes); + asm goto(ARCH_STATIC_BRANCH_ASM("%c[key] + %c[branch]", "%l[l_yes]", "%c[= size]") + : : [key] "i" (key), [branch] "i" (branch), + [size] "i" (sizeof(struct jump_entry)) + : : l_yes); =20 return false; l_yes: @@ -45,8 +47,10 @@ static __always_inline bool arch_static_branch_jump(stru= ct static_key * const ke { asm goto("1:" "jmp %l[l_yes]\n\t" - JUMP_TABLE_ENTRY("%c0 + %c1", "%l[l_yes]") - : : "i" (key), "i" (branch) : : l_yes); + JUMP_TABLE_ENTRY("%c[key] + %c[branch]", "%l[l_yes]", "%c[size]") + : : [key] "i" (key), [branch] "i" (branch), + [size] "i" (sizeof(struct jump_entry)) + : : l_yes); =20 return false; l_yes: diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h index fdb79dd1ebd8..9ff1ecc8e7a8 100644 --- a/include/linux/jump_label.h +++ b/include/linux/jump_label.h @@ -110,16 +110,20 @@ struct static_key { #endif /* __ASSEMBLY__ */ =20 #ifdef CONFIG_JUMP_LABEL -#include - -#ifndef __ASSEMBLY__ -#ifdef CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE =20 +#if defined(CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE) && !defined(__ASSEMBLY__) +/* Must be defined before including */ struct jump_entry { s32 code; s32 target; long key; // key may be far away from the core kernel under KASLR }; +#endif + +#include + +#ifndef __ASSEMBLY__ +#ifdef CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE =20 static inline unsigned long jump_entry_code(const struct jump_entry *entry) { @@ -138,7 +142,7 @@ static inline struct static_key *jump_entry_key(const s= truct jump_entry *entry) return (struct static_key *)((unsigned long)&entry->key + offset); } =20 -#else +#else /* !CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE */ =20 static inline unsigned long jump_entry_code(const struct jump_entry *entry) { @@ -155,7 +159,7 @@ static inline struct static_key *jump_entry_key(const s= truct jump_entry *entry) return (struct static_key *)((unsigned long)entry->key & ~3UL); } =20 -#endif +#endif /* !CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE */ =20 static inline bool jump_entry_is_branch(const struct jump_entry *entry) { @@ -184,8 +188,8 @@ static inline int jump_entry_size(struct jump_entry *en= try) #endif } =20 -#endif -#endif +#endif /* !__ASSEMBLY__ */ +#endif /* CONFIG_JUMP_LABEL */ =20 #ifndef __ASSEMBLY__ =20 --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CF8A5298CDA; Fri, 9 May 2025 20:18:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821896; cv=none; b=OUiZDbVjb7sDAjgfP/ER1S+kHw1vHTtX1aCQA9i+tsDuTHjQvaYHHuRTmgB1mwYcmXEYD0Xs+iK+Vj1G55+B/eTiQ5TUDPj09r0tgGy1QqlMl3RP6r8i0LB0tehMm9MXKvEQqlCYvqHKewrCyeWO5RhdMPyqtMgPAmbxok1U278= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821896; c=relaxed/simple; bh=6Zot9E6ZFT2BtM6OWN9gJxNTDDNv77MxRe5bFHgepKA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gAcn9OhyUd98euABADiSzwzWc91cO49HqHWIxo9oknaR++9rND1xNnw8rjur7ECkpe+/T0zVcb79nitj53Bl6VM41IRrrmWxra9z4wLETTzKFDr0x8NpyDe7CTeJjPW0ReMAU4KhuI1pAL8RH8w8FtLl5/kMlPXWXLYaQ3mpAOs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UNg86nmL; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="UNg86nmL" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 268FCC4CEEE; Fri, 9 May 2025 20:18:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821896; bh=6Zot9E6ZFT2BtM6OWN9gJxNTDDNv77MxRe5bFHgepKA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UNg86nmLthG6r8CoN0b5Hoy+IMV+rcOoY2LVGBY0MLVhZvTXH72OSyuN98z/FqVBA gMwSKo1dVqlyPryIPmG6NjIs0RA20QEPuzTFUtIGqpUyoFehRtASOoDBNy61OMd4No RZy5oALjNtUSPleOD8S6IitH2exh/nqq3c4CKyD3LI64ID6h7+Q1nLIaDhWqE8uVik xqPoHm312cMoN4p/m3ohzxUv0wsH5qz9mgIcQaCP6fS99ejvF7PS7uh6pOpE/svjIQ YYRM78Gq1vTKvV70R+tI7n3noeax6MQ5wNI6dSA3eIw5WwUAjf0u76P9n1b7/dj0n4 aiAUk5lFSor1g== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 45/62] x86/extable: Define ELF section entry size for exception tables Date: Fri, 9 May 2025 13:17:09 -0700 Message-ID: <198cfbd12e54dfce1309828e146b90b1f7b200a5.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for the objtool klp diff subcommand, define the entry size for the __ex_table section in its ELF header. This will allow tooling to extract individual entries. Signed-off-by: Josh Poimboeuf --- arch/x86/include/asm/asm.h | 20 ++++++++++++-------- kernel/extable.c | 2 ++ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h index f963848024a5..62dff336f206 100644 --- a/arch/x86/include/asm/asm.h +++ b/arch/x86/include/asm/asm.h @@ -138,15 +138,17 @@ static __always_inline __pure void *rip_rel_ptr(void = *p) =20 # include =20 +#define EXTABLE_SIZE 12 + /* Exception table entry */ #ifdef __ASSEMBLER__ =20 -# define _ASM_EXTABLE_TYPE(from, to, type) \ - .pushsection "__ex_table","a" ; \ - .balign 4 ; \ - .long (from) - . ; \ - .long (to) - . ; \ - .long type ; \ +# define _ASM_EXTABLE_TYPE(from, to, type) \ + .pushsection "__ex_table", "aM", @progbits, EXTABLE_SIZE; \ + .balign 4 ; \ + .long (from) - . ; \ + .long (to) - . ; \ + .long type ; \ .popsection =20 # ifdef CONFIG_KPROBES @@ -189,7 +191,8 @@ static __always_inline __pure void *rip_rel_ptr(void *p) ".purgem extable_type_reg\n" =20 # define _ASM_EXTABLE_TYPE(from, to, type) \ - " .pushsection \"__ex_table\",\"a\"\n" \ + " .pushsection __ex_table, \"aM\", @progbits, " \ + __stringify(EXTABLE_SIZE) "\n" \ " .balign 4\n" \ " .long (" #from ") - .\n" \ " .long (" #to ") - .\n" \ @@ -197,7 +200,8 @@ static __always_inline __pure void *rip_rel_ptr(void *p) " .popsection\n" =20 # define _ASM_EXTABLE_TYPE_REG(from, to, type, reg) \ - " .pushsection \"__ex_table\",\"a\"\n" \ + " .pushsection __ex_table, \"aM\", @progbits, " \ + __stringify(EXTABLE_SIZE) "\n" \ " .balign 4\n" \ " .long (" #from ") - .\n" \ " .long (" #to ") - .\n" \ diff --git a/kernel/extable.c b/kernel/extable.c index 71f482581cab..0ae3ee2ef266 100644 --- a/kernel/extable.c +++ b/kernel/extable.c @@ -55,6 +55,8 @@ const struct exception_table_entry *search_exception_tabl= es(unsigned long addr) { const struct exception_table_entry *e; =20 + BUILD_BUG_ON(EXTABLE_SIZE !=3D sizeof(struct exception_table_entry)); + e =3D search_kernel_exception_table(addr); if (!e) e =3D search_module_extables(addr); --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 10307299A86; Fri, 9 May 2025 20:18:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821899; cv=none; b=tW1T48YyYPPK40cH4OtyUICmkGLcSZxOLI/wqjx1y787jGLnCN63HjuaxS8GP4VWit0WGI6FXQpqsT4IBUOshnAZYo0h5AxkJdBTDS52HFxBylaVQA1qH4Khrvr44JP/D1wHBWg4di/WWAuMoQ+jtqL1EwyxeS1LqvKiOYISpzY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821899; c=relaxed/simple; bh=It0WZrkllBLdfdgI1Pv+SSr5y5XJN+lhAvDI4mLBpMY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MGgPoLzGUzlkMGsCcLzoHw0bvEm3WuRk1x4DaF0YcPJNLdNm0Q4e29YpYFFPdxMoYitfS9oZJIlLmUTgHQwjek0SR1aAG9+yajypyhmJx4mG5cll1sajHpOQyNNXmA3FkD8KkMsNd4fZefuh2fXKA3NH0FJEBBKkwzPLkplRarE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=f/msG73K; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="f/msG73K" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D19C7C4CEE4; Fri, 9 May 2025 20:18:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821897; bh=It0WZrkllBLdfdgI1Pv+SSr5y5XJN+lhAvDI4mLBpMY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=f/msG73Kppblr3tk08Z1EUrPI+x6jrjanNXisxm/7tYhHxcFmYlWWT3GUycnB0oTx vDvR8HtKrQ6VGtIwPDy4ax8DvF27NikN/HX2oQtNuvLVKVIWR3UNZH8/tfbTHX/ch0 aJ954SRncwNuziObBX3KgbxbZZVIE3b5lotYwM8Q69M+aJXm3cWX8sVuQvx+8DXCPr z/EbYFHs8L3Q+fMwxLAEcR7m13ERzWQkUoArYXbsGFWr11K5fRLAVIu4bD31ooD+7W WobUXRMuPoYDBTYBYUhv9EcYHy63UsjK1hrXcL2VpJNVz+j50jMaVJW6A2JtyCId6O Tka28q5iby6Jg== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 46/62] x86/bug: Define ELF section entry size for the bug table Date: Fri, 9 May 2025 13:17:10 -0700 Message-ID: <6b808664d8ff4c5eaa9cd416563341f3446b243b.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for the objtool klp diff subcommand, define the entry size for the __bug_table section in its ELF header. This will allow tooling to extract individual entries. Signed-off-by: Josh Poimboeuf --- arch/x86/include/asm/bug.h | 44 ++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h index fb3534ddbea2..277938f4a40b 100644 --- a/arch/x86/include/asm/bug.h +++ b/arch/x86/include/asm/bug.h @@ -41,33 +41,35 @@ =20 #define _BUG_FLAGS(ins, flags, extra) \ do { \ - asm_inline volatile("1:\t" ins "\n" \ - ".pushsection __bug_table,\"a\"\n" \ - "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n" \ - "\t" __BUG_REL(%c0) "\t# bug_entry::file\n" \ - "\t.word %c1" "\t# bug_entry::line\n" \ - "\t.word %c2" "\t# bug_entry::flags\n" \ - "\t.org 2b+%c3\n" \ - ".popsection\n" \ - extra \ - : : "i" (__FILE__), "i" (__LINE__), \ - "i" (flags), \ - "i" (sizeof(struct bug_entry))); \ + asm_inline volatile( \ + "1:\t" ins "\n" \ + ".pushsection __bug_table, \"aM\", @progbits, %c3\n" \ + "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n" \ + "\t" __BUG_REL(%c0) "\t# bug_entry::file\n" \ + "\t.word %c1" "\t# bug_entry::line\n" \ + "\t.word %c2" "\t# bug_entry::flags\n" \ + "\t.org 2b+%c3\n" \ + ".popsection\n" \ + extra \ + : : "i" (__FILE__), "i" (__LINE__), \ + "i" (flags), \ + "i" (sizeof(struct bug_entry))); \ } while (0) =20 #else /* !CONFIG_DEBUG_BUGVERBOSE */ =20 #define _BUG_FLAGS(ins, flags, extra) \ do { \ - asm_inline volatile("1:\t" ins "\n" \ - ".pushsection __bug_table,\"a\"\n" \ - "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n" \ - "\t.word %c0" "\t# bug_entry::flags\n" \ - "\t.org 2b+%c1\n" \ - ".popsection\n" \ - extra \ - : : "i" (flags), \ - "i" (sizeof(struct bug_entry))); \ + asm_inline volatile( \ + "1:\t" ins "\n" \ + ".pushsection __bug_table, \"aM\", @progbits, %c1\n" \ + "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n" \ + "\t.word %c0" "\t# bug_entry::flags\n" \ + "\t.org 2b+%c1\n" \ + ".popsection\n" \ + extra \ + : : "i" (flags), \ + "i" (sizeof(struct bug_entry))); \ } while (0) =20 #endif /* CONFIG_DEBUG_BUGVERBOSE */ --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2E916298C10; Fri, 9 May 2025 20:18:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821898; cv=none; b=ghfr2RLcPuXEFHTnG/hmm0hC5TaWahNpXGeGWr4BO/peIFb4U3v5Ls4TQ62darWwkaaIpxPAMCijUTLNvo/jz3OH4FOaLtf3MyQAVGPFnaK8V48fRmVNuWGrp5z/EqpLIGOSJtyyOxRR3trdNYtti7LWHwA9FhNKZ1YziTpLGpo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821898; c=relaxed/simple; bh=awfvqbMu86VnqAeMjFyCXWKk5qbZjyx61gKZgFRh8pI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Vnoot4br5Ecn0z0gQXWfe/gcTZlppySSOLEmuJWV5RYuv70JxwCqdmCAJBdEwqBLM45UBs+lHaloeJvLSYdt3gSiHSc0jpi2u8PxOg7UaffPDJBg+sNtZC+dhPJ/tU3B9fIHlhwyXMxUQmIJPxXFODEk66vO6/WAztn4VIYReo0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Y6vqXNMx; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Y6vqXNMx" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8677AC4CEEF; Fri, 9 May 2025 20:18:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821898; bh=awfvqbMu86VnqAeMjFyCXWKk5qbZjyx61gKZgFRh8pI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Y6vqXNMxVYxvfw9p5D14I4JL7KpBC9wj+6hCC+VQCFVYT74tdxq+s/DgSrtn4nV2K cPO0tw5tf8ANeMuPkvU2NtA1Qbs/5M3zNLjGguCclX6uoMSo7PbFehAwX3cNAI1FtE TSoK90zMud8dlKEaoZretoQ2a00TC4NGD0mnREbeOGms9mVBeGmuHLLWlW7IiEe+QQ Q4cgVYz5XPsjqJbC2YSbBGe/aCPaSGTRTG+KqIwq+1L7v4v21yFXucPQMOCZg94ayZ UDnbmJKbi0uRFe92Q7gxgYq10zdxUJlT0eMLS/R/x8G3wQzw/Pn8pKtSl2IAfClgQf xN3qWeKQiHwqg== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 47/62] x86/orc: Define ELF section entry size for unwind hints Date: Fri, 9 May 2025 13:17:11 -0700 Message-ID: <43e3ed230c982e35e43a9c66247b995336253d2d.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for the objtool klp diff subcommand, define the entry size for the discard.unwind_hints section in its ELF header. This will allow tooling to extract individual entries. Signed-off-by: Josh Poimboeuf --- arch/x86/kernel/unwind_orc.c | 2 ++ include/linux/objtool.h | 9 ++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/unwind_orc.c b/arch/x86/kernel/unwind_orc.c index 977ee75e047c..4624d6d916a2 100644 --- a/arch/x86/kernel/unwind_orc.c +++ b/arch/x86/kernel/unwind_orc.c @@ -199,6 +199,8 @@ static struct orc_entry *orc_find(unsigned long ip) { static struct orc_entry *orc; =20 + BUILD_BUG_ON(UNWIND_HINT_SIZE !=3D sizeof(struct unwind_hint)); + if (ip =3D=3D 0) return &null_orc_entry; =20 diff --git a/include/linux/objtool.h b/include/linux/objtool.h index 366ad004d794..483dd3131826 100644 --- a/include/linux/objtool.h +++ b/include/linux/objtool.h @@ -8,11 +8,14 @@ =20 #include =20 +#define UNWIND_HINT_SIZE 12 + #ifndef __ASSEMBLY__ =20 -#define UNWIND_HINT(type, sp_reg, sp_offset, signal) \ +#define UNWIND_HINT(type, sp_reg, sp_offset, signal) \ "987: \n\t" \ - ".pushsection .discard.unwind_hints\n\t" \ + ".pushsection .discard.unwind_hints, \"M\", @progbits, "\ + __stringify(UNWIND_HINT_SIZE) "\n\t" \ /* struct unwind_hint */ \ ".long 987b - .\n\t" \ ".short " __stringify(sp_offset) "\n\t" \ @@ -88,7 +91,7 @@ */ .macro UNWIND_HINT type:req sp_reg=3D0 sp_offset=3D0 signal=3D0 .Lhere_\@: - .pushsection .discard.unwind_hints + .pushsection .discard.unwind_hints, "M", @progbits, UNWIND_HINT_SIZE /* struct unwind_hint */ .long .Lhere_\@ - . .short \sp_offset --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E5623299A82; Fri, 9 May 2025 20:18:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821899; cv=none; b=tYNmdfq5PeYjmkp1R+21agxz67pLlaZoGrZ29tEHsRCoFFhUYwJ0B9z/z+xLsbf0J/lyD26wezJ5xM/xhzWaUabPnAA2r1rpkWL3UfTzfwjm1kGOSRAOoCRfjimGhN71/0j3h2FuvpNm4CBL3L5T+Ce9abRklAiB+O3B3ECpZsc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821899; c=relaxed/simple; bh=jmRXds4o3AwT3YWdbyDdunUyXBqn350OclAJwQXw8Ps=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mhdopEEDhIA8iJiMZKE/s51W8m0Kwy+UBQJy90Hdl47Y68OtQ3TsL8d0GGQlIzPfLaPizoDQ3J60B61OsZQIHJnq8XX2wOgAojs+JA5eHGt+bbSdln8Z83wx/XFvoVbXb1Zoel2uKwT3JHxXcY4cBIXrkfty2IzfEUBl09h8wjQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MQ3Pu2tX; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MQ3Pu2tX" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3B754C4CEF0; Fri, 9 May 2025 20:18:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821898; bh=jmRXds4o3AwT3YWdbyDdunUyXBqn350OclAJwQXw8Ps=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MQ3Pu2tX2+1T+GabJclTmsL2Si4P6W2qh3RHD/TB8qtNL2MqhssfTPbxAmOoAL/cx nNE3pGXvsa8wh7dTtE0F/yB/hM2C+BrIG9Apm9C9Hi/W3N6WN2XH1KBIWYTf94KzZ0 +P+rRcFLNtd9Xyn87iFp7oH8ET+Q6nBxpuqelWK0HBvSUuCHzU/onAoiHKi5+VWzR0 yPq14TroQ3QWyE4aHmf9UGhBGR52fndAENP2XYg4zaevT+c9JNYJw++eHHYpFdU5UV OkWsuz8qk75V7Wi6jA2k3lqp+WxXLtz+wjvbyADKfr7Eyl07rARms5GX9kUh9E08go WEV92VDU7bgEQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 48/62] objtool: Make STACK_FRAME_NON_STANDARD consistent Date: Fri, 9 May 2025 13:17:12 -0700 Message-ID: <5a0ab7bfd7a64f1051cd7719327fa1f111082b29.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The C version of STACK_FRAME_NON_STANDARD differs from its asm counterpart in that it creates eight-byte entries (vs four) and creates a superfluous temporary variable. Make the entry sizes consistent by converting the C version to four byte entries. Signed-off-by: Josh Poimboeuf --- include/linux/objtool.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/include/linux/objtool.h b/include/linux/objtool.h index 483dd3131826..d4137a46ee70 100644 --- a/include/linux/objtool.h +++ b/include/linux/objtool.h @@ -33,9 +33,10 @@ * * For more information, see tools/objtool/Documentation/objtool.txt. */ -#define STACK_FRAME_NON_STANDARD(func) \ - static void __used __section(".discard.func_stack_frame_non_standard") \ - *__func_stack_frame_non_standard_##func =3D func +#define STACK_FRAME_NON_STANDARD(func) \ + asm(".pushsection .discard.func_stack_frame_non_standard, \"aw\"\n\t" \ + ".long " __stringify(func) " - .\n\t" \ + ".popsection") =20 /* * STACK_FRAME_NON_STANDARD_FP() is a frame-pointer-specific function igno= re --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 95CA1299A9A; Fri, 9 May 2025 20:18:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821899; cv=none; b=eqVpt3jOSvX3/UeUuD+RMz7HJVnCAivuN1qTna4t97FegK/2M/tkh1RCtMzjdGAzm28ZVE/5uJMGtU5QEhINp3y3/3DCaTscejUCY4hiPgSLmJ3ffglR4FbjhJ0xbZIbbe0X3RXv3+0CQsq/q9KL/JsKJlO2Et5WZZIBb8Sc5h4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821899; c=relaxed/simple; bh=jdYcNiJ4B6/6kSPtg1OujZwbu87DFz7lbE7C4Irv4hA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WdxaZGADW9i1YVemhglwJmCx/R9NWerOGOt/8rRzNcfJ6DX2K3Tf7u6bTzVFdEA2jHDGam42jZvu5vMuo+T7qg/oWSZ2YHgjhVfIzluom5z5kQDKoH9Tp2I7zGpq0gkaYoSSJerPflVWbUbPI2/ZV4Ek/QNEsaqYNRuVqaQjaJk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=owzxQTNB; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="owzxQTNB" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E8610C4CEE9; Fri, 9 May 2025 20:18:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821899; bh=jdYcNiJ4B6/6kSPtg1OujZwbu87DFz7lbE7C4Irv4hA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=owzxQTNBcpm2lAhl0R162KDQ0SaTeLZndd4cjh5aRnhSHELuxE3IfITNc6PQ/OtK2 gUFAns6rf4KxpdntGc8B8+/NcmSsaCOl52VxVGbYWOcPk3B6tkV+kl/a0OTB5aCrzj XxanOd2sRZEX/0hg3M5365u+iKqdZcrvPJIS36W5xOOdcoG+sAiuH+2MxjUtnjycEJ d6fT5HYHHNNmInE94bcj3WGeE35LgrzXwpWv8L2Bs6BYTIXLncT3BWgET0kWLWKi4F Rw+WoUp5m68ErvmJEtQ6IkWMX6gWjk4DvtofFiLM8cGr0lHPRTiQ1+24ImvHx3VNqi ULsSknEiRv7AA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 49/62] kbuild,objtool: Defer objtool validation step for CONFIG_LIVEPATCH Date: Fri, 9 May 2025 13:17:13 -0700 Message-ID: <0a12cca631dd6f4c55015e224acefb641b3824ce.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for the objtool klp diff subcommand, defer objtool validation for CONFIG_LIVEPATCH until the final pre-link archive (e.g., vmlinux.o, module-foo.o) is built. This will simplify the process of generating livepatch modules. Delayed objtool is generally preferred anyway, and is already standard for IBT and LTO. Eventually the per-translation-unit mode will be phased out. Signed-off-by: Josh Poimboeuf --- scripts/Makefile.lib | 2 +- scripts/link-vmlinux.sh | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index bfd55a6ad8f1..a68390ff5cd9 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -278,7 +278,7 @@ objtool-args =3D $(objtool-args-y) \ $(if $(delay-objtool), --link) \ $(if $(part-of-module), --module) =20 -delay-objtool :=3D $(or $(CONFIG_LTO_CLANG),$(CONFIG_X86_KERNEL_IBT)) +delay-objtool :=3D $(or $(CONFIG_LTO_CLANG),$(CONFIG_X86_KERNEL_IBT),$(CON= FIG_LIVEPATCH)) =20 cmd_objtool =3D $(if $(objtool-enabled), ; $(objtool) $(objtool-args) $@) cmd_gen_objtooldep =3D $(if $(objtool-enabled), { echo ; echo '$@: $$(wild= card $(objtool))' ; } >> $(dot-target).cmd) diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 51367c2bfc21..acffa3c935f2 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -60,7 +60,8 @@ vmlinux_link() # skip output file argument shift =20 - if is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT; then + if is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT || + is_enabled CONFIG_LIVEPATCH; then # Use vmlinux.o instead of performing the slow LTO link again. objs=3Dvmlinux.o libs=3D --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B609029A309; Fri, 9 May 2025 20:18:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821900; cv=none; b=jsroLyvH5QPsAuavNvrUmSdQ5/9vIxUwlDu94vIBIAGF4CMKhXcYm59710vVgvDWsaIn9X34ghCLTxDLG2rypUbcMGXvpl0NiBkfHAZyeR1U8131+1OX2v1qkB5zCqfNsX3TO1TsKN0l1SuM66QriUEHgPZ+XObPsWgaWwW3dT4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821900; c=relaxed/simple; bh=HMDqBuY0XaX+gHRj+aoHxUW74Y1+mI2jy1n0d+z6xQg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=L6Vj8agZsEkgkVkpU+1Pu7P+lknd74NsAHF5/Feh74CfExSQDqn02d+RQJ00Qn7YenSxYbvl91o0uv8yP828jSUCDh3v2BxQ3Km4z/jr6lRsoJLmTQW+Hw0QL11P0NGSpXfYGFYOpBqal4wOrgDD/mb+T5M7drV8DWU0a7NJ/4s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=bR1AEa/p; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="bR1AEa/p" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A3DE2C4CEE4; Fri, 9 May 2025 20:18:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821900; bh=HMDqBuY0XaX+gHRj+aoHxUW74Y1+mI2jy1n0d+z6xQg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bR1AEa/pPRJqdh1jg1kd+PrHrX/SEMlvdW3TnCuAnZeAMpIISxD2DIzo1tORc5Ce8 ZUS3hmCYgRYhkS9IlH+SjxWiHiN9Jpm++iZ8Nmg8dE5Cfg7vP8vQaku1eaISUuzUjo npFHSY/xOCGyLCzD0RA6R5Op3TF71J/HtPSGCi9gfea3p5EzvQJqdUIJm89T5xM6ZW fE2VGasKSxtGw7druKPDOxalzTNTPiMv/EyFyCCjKBkbX6dss+yY6VuPrewoLF7mJN 5z3VlVv1RhZ8s2OPH2nNOcHffnXcmKrE7VUEJZF9Py1XTkMcDQh4gIl9GIr5feChyj QyVO+RRH6BmsA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 50/62] objtool/klp: Add --checksum option to generate per-function checksums Date: Fri, 9 May 2025 13:17:14 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for the objtool klp diff subcommand, add a command-line option to generate a unique checksum for each function. This will enable detection of functions which have changed between two versions of an object file. Signed-off-by: Josh Poimboeuf --- tools/objtool/Makefile | 38 +++-- tools/objtool/builtin-check.c | 12 +- tools/objtool/check.c | 141 +++++++++++++++++- tools/objtool/elf.c | 46 +++++- tools/objtool/include/objtool/builtin.h | 3 +- tools/objtool/include/objtool/check.h | 5 +- tools/objtool/include/objtool/checksum.h | 42 ++++++ .../objtool/include/objtool/checksum_types.h | 25 ++++ tools/objtool/include/objtool/elf.h | 5 +- tools/objtool/include/objtool/objtool.h | 2 + 10 files changed, 293 insertions(+), 26 deletions(-) create mode 100644 tools/objtool/include/objtool/checksum.h create mode 100644 tools/objtool/include/objtool/checksum_types.h diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile index fc82d47f2b9a..958761c05b7c 100644 --- a/tools/objtool/Makefile +++ b/tools/objtool/Makefile @@ -2,6 +2,27 @@ include ../scripts/Makefile.include include ../scripts/Makefile.arch =20 +ifeq ($(SRCARCH),x86) + BUILD_ORC :=3D y + ARCH_HAS_KLP :=3D y +endif + +ifeq ($(SRCARCH),loongarch) + BUILD_ORC :=3D y +endif + +ifeq ($(ARCH_HAS_KLP),y) + HAVE_XXHASH =3D $(shell echo "int main() {}" | \ + $(HOSTCC) -xc - -o /dev/null -lxxhash 2> /dev/null && echo y || ec= ho n) + ifeq ($(HAVE_XXHASH),y) + LIBXXHASH_CFLAGS :=3D $(shell $(HOSTPKG_CONFIG) libxxhash --cflags 2>/de= v/null) \ + -DBUILD_KLP + LIBXXHASH_LIBS :=3D $(shell $(HOSTPKG_CONFIG) libxxhash --libs 2>/dev/= null || echo -lxxhash) + endif +endif + +export BUILD_ORC + ifeq ($(srctree),) srctree :=3D $(patsubst %/,%,$(dir $(CURDIR))) srctree :=3D $(patsubst %/,%,$(dir $(srctree))) @@ -36,10 +57,10 @@ INCLUDES :=3D -I$(srctree)/tools/include \ -I$(srctree)/tools/objtool/arch/$(SRCARCH)/include \ -I$(LIBSUBCMD_OUTPUT)/include =20 -OBJTOOL_CFLAGS :=3D -std=3Dgnu11 -fomit-frame-pointer -O2 -g \ - $(WARNINGS) $(INCLUDES) $(LIBELF_FLAGS) $(HOSTCFLAGS) +OBJTOOL_CFLAGS :=3D -std=3Dgnu11 -fomit-frame-pointer -O2 -g $(WARNINGS) \ + $(INCLUDES) $(LIBELF_FLAGS) $(LIBXXHASH_CFLAGS) $(HOSTCFLAGS) =20 -OBJTOOL_LDFLAGS :=3D $(LIBSUBCMD) $(LIBELF_LIBS) $(HOSTLDFLAGS) +OBJTOOL_LDFLAGS :=3D $(LIBSUBCMD) $(LIBELF_LIBS) $(LIBXXHASH_LIBS) $(HOSTL= DFLAGS) =20 # Allow old libelf to be used: elfshdr :=3D $(shell echo '$(pound)include ' | $(HOSTCC) $(OBJTO= OL_CFLAGS) -x c -E - 2>/dev/null | grep elf_getshdr) @@ -51,17 +72,6 @@ HOST_OVERRIDES :=3D CC=3D"$(HOSTCC)" LD=3D"$(HOSTLD)" AR= =3D"$(HOSTAR)" AWK =3D awk MKDIR =3D mkdir =20 -BUILD_ORC :=3D n - -ifeq ($(SRCARCH),x86) - BUILD_ORC :=3D y -endif - -ifeq ($(SRCARCH),loongarch) - BUILD_ORC :=3D y -endif - -export BUILD_ORC export srctree OUTPUT CFLAGS SRCARCH AWK include $(srctree)/tools/build/Makefile.include =20 diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index c7bab6a39ca1..9bb26138bb56 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -73,6 +73,7 @@ static int parse_hacks(const struct option *opt, const ch= ar *str, int unset) =20 static const struct option check_options[] =3D { OPT_GROUP("Actions:"), + OPT_BOOLEAN(0, "checksum", &opts.checksum, "generate per-function check= sums"), OPT_BOOLEAN(0 , "cfi", &opts.cfi, "annotate kernel control flow integri= ty (kCFI) function preambles"), OPT_CALLBACK_OPTARG('h', "hacks", NULL, NULL, "jump_label,noinstr,skylake= ", "patch toolchain bugs/limitations", parse_hacks), OPT_BOOLEAN('i', "ibt", &opts.ibt, "validate and annotate IBT"), @@ -158,7 +159,16 @@ static bool opts_valid(void) return false; } =20 - if (opts.hack_jump_label || + +#ifndef BUILD_KLP + if (opts.checksum) { + ERROR("--checksum not supported; install xxhash-devel and recompile"); + return false; + } +#endif + + if (opts.checksum || + opts.hack_jump_label || opts.hack_noinstr || opts.ibt || opts.mcount || diff --git a/tools/objtool/check.c b/tools/objtool/check.c index e4ca5edf73ad..4ca4d5190f35 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -15,6 +15,7 @@ #include #include #include +#include =20 #include #include @@ -988,6 +989,59 @@ static int create_direct_call_sections(struct objtool_= file *file) return 0; } =20 +#ifdef BUILD_KLP +static int create_sym_checksum_section(struct objtool_file *file) +{ + struct section *sec; + struct symbol *sym; + unsigned int idx =3D 0; + struct sym_checksum *checksum; + size_t entsize =3D sizeof(struct sym_checksum); + + sec =3D find_section_by_name(file->elf, SYM_CHECKSUM_SEC); + if (sec) { + if (!opts.dryrun) + WARN("file already has " SYM_CHECKSUM_SEC " section, skipping"); + + return 0; + } + + for_each_sym(file->elf, sym) + if (sym->csum.checksum) + idx++; + + if (!idx) + return 0; + + sec =3D elf_create_section_pair(file->elf, ".discard.sym_checksum", entsi= ze, + idx, idx); + if (!sec) + return -1; + + idx =3D 0; + for_each_sym(file->elf, sym) { + if (!sym->csum.checksum) + continue; + + if (!elf_init_reloc(file->elf, sec->rsec, idx, idx * entsize, + sym, 0, R_TEXT64)) + return -1; + + checksum =3D (struct sym_checksum *)sec->data->d_buf + idx; + checksum->addr =3D 0; /* reloc */ + checksum->checksum =3D sym->csum.checksum; + + mark_sec_changed(file->elf, sec, true); + + idx++; + } + + return 0; +} +#else +static int create_sym_checksum_section(struct objtool_file *file) { return= -EINVAL; } +#endif + /* * Warnings shouldn't be reported for ignored functions. */ @@ -1766,6 +1820,7 @@ static int handle_group_alt(struct objtool_file *file, nop->type =3D INSN_NOP; nop->sym =3D orig_insn->sym; nop->alt_group =3D new_alt_group; + nop->fake =3D 1; } =20 if (!special_alt->new_len) { @@ -2545,6 +2600,14 @@ static void mark_holes(struct objtool_file *file) } } =20 +static bool validate_branch_enabled(void) +{ + return opts.stackval || + opts.orc || + opts.uaccess || + opts.checksum; +} + static int decode_sections(struct objtool_file *file) { int ret; @@ -2580,7 +2643,7 @@ static int decode_sections(struct objtool_file *file) * Must be before add_jump_destinations(), which depends on 'func' * being set for alternatives, to enable proper sibling call detection. */ - if (opts.stackval || opts.orc || opts.uaccess || opts.noinstr) { + if (validate_branch_enabled() || opts.noinstr) { ret =3D add_special_section_alts(file); if (ret) return ret; @@ -3559,6 +3622,51 @@ static bool skip_alt_group(struct instruction *insn) return alt_insn->type =3D=3D INSN_CLAC || alt_insn->type =3D=3D INSN_STAC; } =20 +static void checksum_update_insn(struct objtool_file *file, struct symbol = *func, + struct instruction *insn) +{ + struct reloc *reloc =3D insn_reloc(file, insn); + struct symbol *dest =3D insn_call_dest(insn); + + if (dest && !reloc) { + checksum_update(func, insn, insn->sec->data->d_buf + insn->offset, 1); + checksum_update(func, insn, dest->name, strlen(dest->name)); + } else if (!insn->fake) { + checksum_update(func, insn, insn->sec->data->d_buf + insn->offset, insn-= >len); + } + + if (reloc) { + struct symbol *sym =3D reloc->sym; + + if (sym->sec && is_string_sec(sym->sec)) { + s64 addend; + char *str; + + addend =3D arch_insn_adjusted_addend(insn, reloc); + + str =3D sym->sec->data->d_buf + sym->offset + addend; + + checksum_update(func, insn, str, strlen(str)); + + } else { + u64 offset =3D arch_insn_adjusted_addend(insn, reloc); + + if (is_sec_sym(sym)) { + sym =3D find_symbol_containing(reloc->sym->sec, offset); + if (!sym) + return; + + offset -=3D sym->offset; + } + + checksum_update(func, insn, sym->demangled_name, + strlen(sym->demangled_name)); + + checksum_update(func, insn, &offset, sizeof(offset)); + } + } +} + /* * Follow the branch starting at the given instruction, and recursively fo= llow * any other branches (jumps). Meanwhile, track the frame pointer state at @@ -3579,6 +3687,9 @@ static int validate_branch(struct objtool_file *file,= struct symbol *func, while (1) { next_insn =3D next_insn_to_validate(file, insn); =20 + if (opts.checksum && func && insn->sec) + checksum_update_insn(file, func, insn); + if (func && insn_func(insn) && func !=3D insn_func(insn)->pfunc) { /* Ignore KCFI type preambles, which always fall through */ if (is_prefix_func(func)) @@ -3828,7 +3939,13 @@ static int validate_unwind_hint(struct objtool_file = *file, struct insn_state *state) { if (insn->hint && !insn->visited) { - int ret =3D validate_branch(file, insn_func(insn), insn, *state); + struct symbol *func =3D insn_func(insn); + int ret; + + if (opts.checksum) + checksum_init(func); + + ret =3D validate_branch(file, func, insn, *state); if (ret) BT_INSN(insn, "<=3D=3D=3D (hint)"); return ret; @@ -4176,6 +4293,7 @@ static int validate_symbol(struct objtool_file *file,= struct section *sec, struct symbol *sym, struct insn_state *state) { struct instruction *insn; + struct symbol *func; int ret; =20 if (!sym->len) { @@ -4193,9 +4311,18 @@ static int validate_symbol(struct objtool_file *file= , struct section *sec, if (opts.uaccess) state->uaccess =3D sym->uaccess_safe; =20 - ret =3D validate_branch(file, insn_func(insn), insn, *state); + func =3D insn_func(insn); + + if (opts.checksum) + checksum_init(func); + + ret =3D validate_branch(file, func, insn, *state); if (ret) BT_INSN(insn, "<=3D=3D=3D (sym)"); + + if (opts.checksum) + checksum_finish(func); + return ret; } =20 @@ -4672,7 +4799,7 @@ int check(struct objtool_file *file) if (opts.retpoline) warnings +=3D validate_retpoline(file); =20 - if (opts.stackval || opts.orc || opts.uaccess) { + if (validate_branch_enabled()) { int w =3D 0; =20 w +=3D validate_functions(file); @@ -4748,6 +4875,12 @@ int check(struct objtool_file *file) goto out; } =20 + if (opts.checksum) { + ret =3D create_sym_checksum_section(file); + if (ret) + goto out; + } + if (opts.orc && nr_insns) { ret =3D orc_create(file); if (ret) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 5e7620824136..a7ed357be5b9 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -412,7 +413,38 @@ static int read_sections(struct elf *elf) return 0; } =20 -static void elf_add_symbol(struct elf *elf, struct symbol *sym) +static const char *demangle_name(struct symbol *sym) +{ + char *str; + + if (!is_local_sym(sym)) + return sym->name; + + if (!is_func_sym(sym) && !is_object_sym(sym)) + return sym->name; + + if (!strstarts(sym->name, "__UNIQUE_ID_") && !strchr(sym->name, '.')) + return sym->name; + + str =3D strdup(sym->name); + if (!str) { + ERROR_GLIBC("strdup"); + return NULL; + } + + for (int i =3D strlen(str) - 1; i >=3D 0; i--) { + char c =3D str[i]; + + if (!isdigit(c) && c !=3D '.') { + str[i + 1] =3D '\0'; + break; + } + }; + + return str; +} + +static int elf_add_symbol(struct elf *elf, struct symbol *sym) { struct list_head *entry; struct rb_node *pnode; @@ -454,6 +486,12 @@ static void elf_add_symbol(struct elf *elf, struct sym= bol *sym) if (is_func_sym(sym) && strstr(sym->name, ".cold")) sym->cold =3D 1; sym->pfunc =3D sym->cfunc =3D sym; + + sym->demangled_name =3D demangle_name(sym); + if (!sym->demangled_name) + return -1; + + return 0; } =20 static int read_symbols(struct elf *elf) @@ -527,7 +565,8 @@ static int read_symbols(struct elf *elf) } else sym->sec =3D find_section_by_index(elf, 0); =20 - elf_add_symbol(elf, sym); + if (elf_add_symbol(elf, sym)) + return -1; } =20 if (opts.stats) { @@ -865,7 +904,8 @@ struct symbol *elf_create_symbol(struct elf *elf, const= char *name, mark_sec_changed(elf, symtab_shndx, true); } =20 - elf_add_symbol(elf, sym); + if (elf_add_symbol(elf, sym)) + return NULL; =20 return sym; } diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/includ= e/objtool/builtin.h index 6b08666fa69d..3ec233406cda 100644 --- a/tools/objtool/include/objtool/builtin.h +++ b/tools/objtool/include/objtool/builtin.h @@ -9,6 +9,7 @@ =20 struct opts { /* actions: */ + bool cfi; bool dump_orc; bool hack_jump_label; bool hack_noinstr; @@ -23,9 +24,9 @@ struct opts { bool sls; bool stackval; bool static_call; + bool checksum; bool uaccess; int prefix; - bool cfi; =20 /* options: */ bool backtrace; diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/= objtool/check.h index 0f4e7ac929ef..d73b0c3ae1ee 100644 --- a/tools/objtool/include/objtool/check.h +++ b/tools/objtool/include/objtool/check.h @@ -65,8 +65,9 @@ struct instruction { unret : 1, visited : 4, no_reloc : 1, - hole : 1; - /* 10 bit hole */ + hole : 1, + fake : 1; + /* 9 bit hole */ =20 struct alt_group *alt_group; struct instruction *jump_dest; diff --git a/tools/objtool/include/objtool/checksum.h b/tools/objtool/inclu= de/objtool/checksum.h new file mode 100644 index 000000000000..927ca74b5c39 --- /dev/null +++ b/tools/objtool/include/objtool/checksum.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef _OBJTOOL_CHECKSUM_H +#define _OBJTOOL_CHECKSUM_H + +#include + +#ifdef BUILD_KLP + +static inline void checksum_init(struct symbol *func) +{ + if (func && !func->csum.state) { + func->csum.state =3D XXH3_createState(); + XXH3_64bits_reset(func->csum.state); + } +} + +static inline void checksum_update(struct symbol *func, + struct instruction *insn, + const void *data, size_t size) +{ + XXH3_64bits_update(func->csum.state, data, size); +} + +static inline void checksum_finish(struct symbol *func) +{ + if (func && func->csum.state) { + func->csum.checksum =3D XXH3_64bits_digest(func->csum.state); + func->csum.state =3D NULL; + } +} + +#else /* !BUILD_KLP */ + +static inline void checksum_init(struct symbol *func) {} +static inline void checksum_update(struct symbol *func, + struct instruction *insn, + const void *data, size_t size) {} +static inline void checksum_finish(struct symbol *func) {} + +#endif /* !BUILD_KLP */ + +#endif /* _OBJTOOL_CHECKSUM_H */ diff --git a/tools/objtool/include/objtool/checksum_types.h b/tools/objtool= /include/objtool/checksum_types.h new file mode 100644 index 000000000000..507efdd8ab5b --- /dev/null +++ b/tools/objtool/include/objtool/checksum_types.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _OBJTOOL_CHECKSUM_TYPES_H +#define _OBJTOOL_CHECKSUM_TYPES_H + +struct sym_checksum { + u64 addr; + u64 checksum; +}; + +#ifdef BUILD_KLP + +#include + +struct checksum { + XXH3_state_t *state; + XXH64_hash_t checksum; +}; + +#else /* !BUILD_KLP */ + +struct checksum {}; + +#endif /* !BUILD_KLP */ + +#endif /* _OBJTOOL_CHECKSUM_TYPES_H */ diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index a0fc252e1993..4d1023fdb700 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -13,6 +13,8 @@ #include #include #include + +#include #include =20 #define SYM_NAME_LEN 512 @@ -57,7 +59,7 @@ struct symbol { struct elf_hash_node name_hash; GElf_Sym sym; struct section *sec; - const char *name; + const char *name, *demangled_name; unsigned int idx, len; unsigned long offset; unsigned long __subtree_last; @@ -79,6 +81,7 @@ struct symbol { struct list_head pv_target; struct reloc *relocs; struct section *group_sec; + struct checksum csum; }; =20 struct reloc { diff --git a/tools/objtool/include/objtool/objtool.h b/tools/objtool/includ= e/objtool/objtool.h index c0dc86a78ff6..90c591b5bd68 100644 --- a/tools/objtool/include/objtool/objtool.h +++ b/tools/objtool/include/objtool/objtool.h @@ -14,6 +14,8 @@ =20 #define __weak __attribute__((weak)) =20 +#define SYM_CHECKSUM_SEC ".discard.sym_checksum" + struct pv_state { bool clean; struct list_head targets; --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7E3D0299AB0; Fri, 9 May 2025 20:18:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821901; cv=none; b=TZD1BkF30os0831YUC/qzQkYGsCh3a4lRF+BR/QinWbIUdxQQXJp8IezXXiWBA4vj1iR6jVfsm+GsJE3nXG2jHxSq+LxucEglyR6jcWoOcYwww2UtrIH442h06b+2f8c0r5WJv6eV0qvzOd128zcfZq/rVvOvu4BRxCJMwndOqQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821901; c=relaxed/simple; bh=1YKYnjLs13Leq2MuzKlp2LCDvypqiGjyWag+THpNkyk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lUhAnISh9zZhhxOpNK+tyc6Ywed6B9McZAcMwXfrG+eGgGi+bxq7V2pXhyarKRAizDr3PdX5e4sSxOF0NXv4EEJ0kIc9LjHnblZYEquLHiz43xWNsAJs9zPmz4dgcYbLocK3q9mwZ0Jb+Ph1wjxgasGqs2lN1Mgm5+OL8QmYLkA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dUXP/lrD; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dUXP/lrD" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5A8A6C4CEF0; Fri, 9 May 2025 20:18:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821900; bh=1YKYnjLs13Leq2MuzKlp2LCDvypqiGjyWag+THpNkyk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dUXP/lrDcGtVxvM6uik2kaqEdJzORd/U+fG9ciRUSmbN6WLNYSxYRpC7ldzD0RILF 7dGUQs+qGYhKkYxAdJyeO1SWtIxnYyPrfI8lQa6RAFcP2jdPD1qu4ujdVk94o7ncbI vP0ksFH1A4r069Ku9PllnM+v0BeQEJgEj1q1Vx7SuFI/NtB6puMjfvDO5YYLO0hmiB YCNOoGhq2wNJeJci2IB0S1t1GKSFwJl5YcHQVS5IvTvvKr4zSRpT7PJtnkaAjwLSed QbB86ptGslUH3vw7DFpXzono12s1Hu9r3TYSRG7N20QdLa1Ioz7wwrzkUdWNMZ14Nw ObTJVn27glxPQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 51/62] objtool/klp: Add --debug-checksum= to show per-instruction checksums Date: Fri, 9 May 2025 13:17:15 -0700 Message-ID: <7d6a7093e117e7678aee82fedfa6cfad094a46d8.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a --debug-checksum=3D option to the check subcommand to print the calculated checksum of each instruction in the given functions. This is useful for determining where two versions of a function begin to diverge. Signed-off-by: Josh Poimboeuf --- tools/objtool/builtin-check.c | 6 ++++ tools/objtool/check.c | 42 ++++++++++++++++++++++++ tools/objtool/include/objtool/builtin.h | 1 + tools/objtool/include/objtool/checksum.h | 1 + tools/objtool/include/objtool/elf.h | 1 + tools/objtool/include/objtool/warn.h | 19 +++++++++++ 6 files changed, 70 insertions(+) diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index 9bb26138bb56..84918593d935 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -92,6 +92,7 @@ static const struct option check_options[] =3D { =20 OPT_GROUP("Options:"), OPT_BOOLEAN(0, "backtrace", &opts.backtrace, "unwind on error"), + OPT_STRING(0, "debug-checksum", &opts.debug_checksum, "funcs", "enable= checksum debug output"), OPT_BOOLEAN(0, "dry-run", &opts.dryrun, "don't write modifications"), OPT_BOOLEAN(0, "link", &opts.link, "object is a linked object"), OPT_BOOLEAN(0, "module", &opts.module, "object is part of a kernel modu= le"), @@ -167,6 +168,11 @@ static bool opts_valid(void) } #endif =20 + if (opts.debug_checksum && !opts.checksum) { + ERROR("--debug-checksum requires --checksum"); + return false; + } + if (opts.checksum || opts.hack_jump_label || opts.hack_noinstr || diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 4ca4d5190f35..30a5eb725931 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -3622,6 +3622,44 @@ static bool skip_alt_group(struct instruction *insn) return alt_insn->type =3D=3D INSN_CLAC || alt_insn->type =3D=3D INSN_STAC; } =20 +static int checksum_debug_init(struct objtool_file *file) +{ + char *dup, *s; + + if (!opts.debug_checksum) + return 0; + + dup =3D strdup(opts.debug_checksum); + if (!dup) { + ERROR_GLIBC("strdup"); + return -1; + } + + s =3D dup; + while (*s) { + struct symbol *func; + char *comma; + + comma =3D strchr(s, ','); + if (comma) + *comma =3D '\0'; + + func =3D find_symbol_by_name(file->elf, s); + if (!func || !is_func_sym(func)) + WARN("--debug-checksum: can't find '%s'", s); + else + func->debug_checksum =3D 1; + + if (!comma) + break; + + s =3D comma + 1; + } + + free(dup); + return 0; +} + static void checksum_update_insn(struct objtool_file *file, struct symbol = *func, struct instruction *insn) { @@ -4789,6 +4827,10 @@ int check(struct objtool_file *file) cfi_hash_add(&init_cfi); cfi_hash_add(&func_cfi); =20 + ret =3D checksum_debug_init(file); + if (ret) + goto out; + ret =3D decode_sections(file); if (ret) goto out; diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/includ= e/objtool/builtin.h index 3ec233406cda..ceabafb43327 100644 --- a/tools/objtool/include/objtool/builtin.h +++ b/tools/objtool/include/objtool/builtin.h @@ -30,6 +30,7 @@ struct opts { =20 /* options: */ bool backtrace; + const char *debug_checksum; bool dryrun; bool link; bool mnop; diff --git a/tools/objtool/include/objtool/checksum.h b/tools/objtool/inclu= de/objtool/checksum.h index 927ca74b5c39..7fe21608722a 100644 --- a/tools/objtool/include/objtool/checksum.h +++ b/tools/objtool/include/objtool/checksum.h @@ -19,6 +19,7 @@ static inline void checksum_update(struct symbol *func, const void *data, size_t size) { XXH3_64bits_update(func->csum.state, data, size); + dbg_checksum(func, insn, XXH3_64bits_digest(func->csum.state)); } =20 static inline void checksum_finish(struct symbol *func) diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index 4d1023fdb700..4cfd09e66cb5 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -78,6 +78,7 @@ struct symbol { u8 ignore : 1; u8 cold : 1; u8 prefix : 1; + u8 debug_checksum : 1; struct list_head pv_target; struct reloc *relocs; struct section *group_sec; diff --git a/tools/objtool/include/objtool/warn.h b/tools/objtool/include/o= bjtool/warn.h index cb8fe846d9dd..29173a1368d7 100644 --- a/tools/objtool/include/objtool/warn.h +++ b/tools/objtool/include/objtool/warn.h @@ -102,4 +102,23 @@ static inline char *offstr(struct section *sec, unsign= ed long offset) #define ERROR_FUNC(sec, offset, format, ...) __WARN_FUNC(ERROR_STR, sec, o= ffset, format, ##__VA_ARGS__) #define ERROR_INSN(insn, format, ...) WARN_FUNC(insn->sec, insn->offset, f= ormat, ##__VA_ARGS__) =20 + +#define __dbg(format, ...) \ + fprintf(stderr, \ + "DEBUG: %s%s" format "\n", \ + objname ?: "", \ + objname ? ": " : "", \ + ##__VA_ARGS__) + +#define dbg_checksum(func, insn, checksum) \ +({ \ + if (unlikely(insn->sym && insn->sym->pfunc && \ + insn->sym->pfunc->debug_checksum)) { \ + char *insn_off =3D offstr(insn->sec, insn->offset); \ + __dbg("checksum: %s %s %016lx", \ + func->name, insn_off, checksum); \ + free(insn_off); \ + } \ +}) + #endif /* _WARN_H */ --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CF41829A333; Fri, 9 May 2025 20:18:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821901; cv=none; b=qNbl5lElZTwq/deRHY3FEboK+kcocXFZksXZr/xE5b91Ka1KH5jSt14xJoDWA3CkJGZQFhjeD8x5jAglKvm2oiGcYs3O3USVVkQIOJDEFw13VyBp+CU45/O6DULbfmJMClLhpouM2galEp3gDrdtARrZGsdNtIkSIMGYf5qIuvI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821901; c=relaxed/simple; bh=Pa7ruEFgxellGCnG9+Ryw2ME/sshNpspU2B3DMJmB8c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mm3ZdQfYG5OgdIXLG7RqI1XfvPkcKPfOD/xjUzok3Sbp37m4rFe9hzTsODmfxDiKrll66ut7Issn9ajcKl7KtvpWcOCqVCps23yBh6UhiBrk2/xqN5neYl+TQ9SyLtSugrbL4TAT4PTwilDssiNMgniLWo1I0ImKV0bIp6Oxr6k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Z6MhHulS; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Z6MhHulS" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 11D07C4CEF1; Fri, 9 May 2025 20:18:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821901; bh=Pa7ruEFgxellGCnG9+Ryw2ME/sshNpspU2B3DMJmB8c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Z6MhHulSYg6H0awIZfJHClmNToSBPYLxPi7Us5GeRS/yigD/U9El6x7z2rZdLp08P ywyYA3uYA2/TZ+ulpAMnK7v+AQ0qu4aSL8y36YmI3P02e+XS6z5lhlMNxZm11gFtHg VTQOHLnahK97p5EFywXLAIBB6G2ZFLWzo3MRrOIkjP0ZNNDN6Z0BNx1rBcbDfoDhM5 R3XOvcgKb0ju5/ImxAbbIpBhwcZIiYWXm4WtF2DoMmW7HBQoAxjGRbkrPnTIYweZ/V P6MdzfXofNVuS8OTKEr6THjFWhrTsZmrs/WSYbwGNPHZfuSh87i+F3gcCpI0X/XGKA GegStDQQif2Ow== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 52/62] objtool/klp: Introduce klp diff subcommand for diffing object files Date: Fri, 9 May 2025 13:17:16 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a new klp diff subcommand which performs a binary diff between two object files and extracts changed functions into a new object which can then be linked into a livepatch module. This builds on concepts from the longstanding out-of-tree kpatch [1] project which began in 2012 and has been used for many years to generate livepatch modules for production kernels. However, this is a complete rewrite which incorporates hard-earned lessons from 12+ years of maintaining kpatch. Key improvements compared to kpatch-build: - Integrated with objtool: Leverages objtool's existing control-flow graph analysis to help detect changed functions. - Works on vmlinux.o: Supports late-linked objects, making it compatible with LTO, IBT, and similar. - Simplified code base: ~3k fewer lines of code. - Upstream: No more out-of-tree #ifdef hacks, far less cruft. - Cleaner internals: Vastly simplified logic for symbol/section/reloc inclusion and special section extraction. - Robust __LINE__ macro handling: Avoids false positive binary diffs caused by the __LINE__ macro by introducing a fix-patch-lines script (coming in a later patch) which injects #line directives into the source .patch to preserve the original line numbers at compile time. Note the end result of this subcommand is not yet functionally complete. Livepatch needs some ELF magic which linkers don't like: - Two relocation sections (.rela*, .klp.rela*) for the same text section. - Use of SHN_LIVEPATCH to mark livepatch symbols. Unfortunately linkers tend to mangle such things. To work around that, klp diff generates a linker-compliant intermediate binary which encodes the relevant KLP section/reloc/symbol metadata. After module linking, a klp post-link step (coming soon) will clean up the mess and convert the linked .ko into a fully compliant livepatch module. Note this subcommand requires the diffed binaries to have been compiled with -ffunction-sections and -fdata-sections, and processed with 'objtool --checksum'. Those constraints will be handled by a klp-build script introduced in a later patch. Without '-ffunction-sections -fdata-sections', reliable object diffing would be infeasible due to toolchain limitations: - For intra-file+intra-section references, the compiler might occasionally generated hard-coded instruction offsets instead of relocations. - Section-symbol-based references can be ambiguous: - Overlapping or zero-length symbols create ambiguity as to which symbol is being referenced. - A reference to the end of a symbol (e.g., checking array bounds) can be misinterpreted as a reference to the next symbol, or vice versa. A potential future alternative to '-ffunction-sections -fdata-sections' would be to introduce a toolchain option that forces symbol-based (non-section) relocations. Signed-off-by: Josh Poimboeuf --- MAINTAINERS | 2 +- include/linux/livepatch.h | 25 +- include/linux/livepatch_external.h | 76 ++ kernel/livepatch/core.c | 4 +- scripts/module.lds.S | 10 +- tools/include/linux/livepatch_external.h | 76 ++ tools/objtool/Build | 4 +- tools/objtool/Makefile | 3 +- tools/objtool/arch/x86/decode.c | 40 + tools/objtool/builtin-klp.c | 52 + tools/objtool/elf.c | 21 +- tools/objtool/include/objtool/arch.h | 1 + tools/objtool/include/objtool/builtin.h | 2 + tools/objtool/include/objtool/elf.h | 52 +- tools/objtool/include/objtool/klp.h | 31 + tools/objtool/include/objtool/objtool.h | 2 + tools/objtool/klp-diff.c | 1429 ++++++++++++++++++++++ tools/objtool/objtool.c | 41 +- tools/objtool/sync-check.sh | 1 + tools/objtool/weak.c | 7 + 20 files changed, 1834 insertions(+), 45 deletions(-) create mode 100644 include/linux/livepatch_external.h create mode 100644 tools/include/linux/livepatch_external.h create mode 100644 tools/objtool/builtin-klp.c create mode 100644 tools/objtool/include/objtool/klp.h create mode 100644 tools/objtool/klp-diff.c diff --git a/MAINTAINERS b/MAINTAINERS index 9d0b78e3f866..06f4a10c7209 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13788,7 +13788,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/gi= t/livepatching/livepatching.g F: Documentation/ABI/testing/sysfs-kernel-livepatch F: Documentation/livepatch/ F: arch/powerpc/include/asm/livepatch.h -F: include/linux/livepatch.h +F: include/linux/livepatch*.h F: kernel/livepatch/ F: kernel/module/livepatch.c F: samples/livepatch/ diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h index 51a258c24ff5..772919e8096a 100644 --- a/include/linux/livepatch.h +++ b/include/linux/livepatch.h @@ -13,6 +13,7 @@ #include #include #include +#include #include =20 #if IS_ENABLED(CONFIG_LIVEPATCH) @@ -77,30 +78,6 @@ struct klp_func { bool transition; }; =20 -struct klp_object; - -/** - * struct klp_callbacks - pre/post live-(un)patch callback structure - * @pre_patch: executed before code patching - * @post_patch: executed after code patching - * @pre_unpatch: executed before code unpatching - * @post_unpatch: executed after code unpatching - * @post_unpatch_enabled: flag indicating if post-unpatch callback - * should run - * - * All callbacks are optional. Only the pre-patch callback, if provided, - * will be unconditionally executed. If the parent klp_object fails to - * patch for any reason, including a non-zero error status returned from - * the pre-patch callback, no further callbacks will be executed. - */ -struct klp_callbacks { - int (*pre_patch)(struct klp_object *obj); - void (*post_patch)(struct klp_object *obj); - void (*pre_unpatch)(struct klp_object *obj); - void (*post_unpatch)(struct klp_object *obj); - bool post_unpatch_enabled; -}; - /** * struct klp_object - kernel object structure for live patching * @name: module name (or NULL for vmlinux) diff --git a/include/linux/livepatch_external.h b/include/linux/livepatch_e= xternal.h new file mode 100644 index 000000000000..138af19b0f5c --- /dev/null +++ b/include/linux/livepatch_external.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * External livepatch interfaces for patch creation tooling + */ + +#ifndef _LINUX_LIVEPATCH_EXTERNAL_H_ +#define _LINUX_LIVEPATCH_EXTERNAL_H_ + +#include + +#define KLP_RELOC_SEC_PREFIX ".klp.rela." +#define KLP_SYM_PREFIX ".klp.sym." + +#define __KLP_PRE_PATCH_PREFIX __klp_pre_patch_callback_ +#define __KLP_POST_PATCH_PREFIX __klp_post_patch_callback_ +#define __KLP_PRE_UNPATCH_PREFIX __klp_pre_unpatch_callback_ +#define __KLP_POST_UNPATCH_PREFIX __klp_post_unpatch_callback_ + +#define KLP_PRE_PATCH_PREFIX __stringify(__KLP_PRE_PATCH_PREFIX) +#define KLP_POST_PATCH_PREFIX __stringify(__KLP_POST_PATCH_PREFIX) +#define KLP_PRE_UNPATCH_PREFIX __stringify(__KLP_PRE_UNPATCH_PREFIX) +#define KLP_POST_UNPATCH_PREFIX __stringify(__KLP_POST_UNPATCH_PREFIX) + +struct klp_object; + +typedef int (*klp_pre_patch_t)(struct klp_object *obj); +typedef void (*klp_post_patch_t)(struct klp_object *obj); +typedef void (*klp_pre_unpatch_t)(struct klp_object *obj); +typedef void (*klp_post_unpatch_t)(struct klp_object *obj); + +/** + * struct klp_callbacks - pre/post live-(un)patch callback structure + * @pre_patch: executed before code patching + * @post_patch: executed after code patching + * @pre_unpatch: executed before code unpatching + * @post_unpatch: executed after code unpatching + * @post_unpatch_enabled: flag indicating if post-unpatch callback + * should run + * + * All callbacks are optional. Only the pre-patch callback, if provided, + * will be unconditionally executed. If the parent klp_object fails to + * patch for any reason, including a non-zero error status returned from + * the pre-patch callback, no further callbacks will be executed. + */ +struct klp_callbacks { + klp_pre_patch_t pre_patch; + klp_post_patch_t post_patch; + klp_pre_unpatch_t pre_unpatch; + klp_post_unpatch_t post_unpatch; + bool post_unpatch_enabled; +}; + +/* + * 'struct klp_{func,object}_ext' are compact "external" representations of + * 'struct klp_{func,object}'. They are used by objtool for livepatch + * generation. The structs are then read by the livepatch module and conv= erted + * to the real structs before calling klp_enable_patch(). + * + * TODO make these the official API for klp_enable_patch(). That should + * simplify livepatch's interface as well as its data structure lifetime + * management. + */ +struct klp_func_ext { + const char *old_name; + void *new_func; + unsigned long sympos; +}; + +struct klp_object_ext { + const char *name; + struct klp_func_ext *funcs; + struct klp_callbacks callbacks; + unsigned int nr_funcs; +}; + +#endif /* _LINUX_LIVEPATCH_EXTERNAL_H_ */ diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 7e443c2cf7d4..0044a8125013 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -224,7 +224,7 @@ static int klp_resolve_symbols(Elf_Shdr *sechdrs, const= char *strtab, =20 /* Format: .klp.sym.sym_objname.sym_name,sympos */ cnt =3D sscanf(strtab + sym->st_name, - ".klp.sym.%55[^.].%511[^,],%lu", + KLP_SYM_PREFIX "%55[^.].%511[^,],%lu", sym_objname, sym_name, &sympos); if (cnt !=3D 3) { pr_err("symbol %s has an incorrectly formatted name\n", @@ -303,7 +303,7 @@ static int klp_write_section_relocs(struct module *pmod= , Elf_Shdr *sechdrs, * See comment in klp_resolve_symbols() for an explanation * of the selected field width value. */ - cnt =3D sscanf(shstrtab + sec->sh_name, ".klp.rela.%55[^.]", + cnt =3D sscanf(shstrtab + sec->sh_name, KLP_RELOC_SEC_PREFIX "%55[^.]", sec_objname); if (cnt !=3D 1) { pr_err("section %s has an incorrectly formatted name\n", diff --git a/scripts/module.lds.S b/scripts/module.lds.S index 0b5ea63d1c67..05abb3ceabef 100644 --- a/scripts/module.lds.S +++ b/scripts/module.lds.S @@ -34,8 +34,16 @@ SECTIONS { =20 __patchable_function_entries : { *(__patchable_function_entries) } =20 + __klp_funcs 0: ALIGN(8) { KEEP(*(__klp_funcs)) } + + __klp_objects 0: ALIGN(8) { + __start_klp_objects =3D .; + KEEP(*(__klp_objects)) + __stop_klp_objects =3D .; + } + #ifdef CONFIG_ARCH_USES_CFI_TRAPS - __kcfi_traps : { KEEP(*(.kcfi_traps)) } + __kcfi_traps : { KEEP(*(.kcfi_traps)) } #endif =20 .text : { diff --git a/tools/include/linux/livepatch_external.h b/tools/include/linux= /livepatch_external.h new file mode 100644 index 000000000000..138af19b0f5c --- /dev/null +++ b/tools/include/linux/livepatch_external.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * External livepatch interfaces for patch creation tooling + */ + +#ifndef _LINUX_LIVEPATCH_EXTERNAL_H_ +#define _LINUX_LIVEPATCH_EXTERNAL_H_ + +#include + +#define KLP_RELOC_SEC_PREFIX ".klp.rela." +#define KLP_SYM_PREFIX ".klp.sym." + +#define __KLP_PRE_PATCH_PREFIX __klp_pre_patch_callback_ +#define __KLP_POST_PATCH_PREFIX __klp_post_patch_callback_ +#define __KLP_PRE_UNPATCH_PREFIX __klp_pre_unpatch_callback_ +#define __KLP_POST_UNPATCH_PREFIX __klp_post_unpatch_callback_ + +#define KLP_PRE_PATCH_PREFIX __stringify(__KLP_PRE_PATCH_PREFIX) +#define KLP_POST_PATCH_PREFIX __stringify(__KLP_POST_PATCH_PREFIX) +#define KLP_PRE_UNPATCH_PREFIX __stringify(__KLP_PRE_UNPATCH_PREFIX) +#define KLP_POST_UNPATCH_PREFIX __stringify(__KLP_POST_UNPATCH_PREFIX) + +struct klp_object; + +typedef int (*klp_pre_patch_t)(struct klp_object *obj); +typedef void (*klp_post_patch_t)(struct klp_object *obj); +typedef void (*klp_pre_unpatch_t)(struct klp_object *obj); +typedef void (*klp_post_unpatch_t)(struct klp_object *obj); + +/** + * struct klp_callbacks - pre/post live-(un)patch callback structure + * @pre_patch: executed before code patching + * @post_patch: executed after code patching + * @pre_unpatch: executed before code unpatching + * @post_unpatch: executed after code unpatching + * @post_unpatch_enabled: flag indicating if post-unpatch callback + * should run + * + * All callbacks are optional. Only the pre-patch callback, if provided, + * will be unconditionally executed. If the parent klp_object fails to + * patch for any reason, including a non-zero error status returned from + * the pre-patch callback, no further callbacks will be executed. + */ +struct klp_callbacks { + klp_pre_patch_t pre_patch; + klp_post_patch_t post_patch; + klp_pre_unpatch_t pre_unpatch; + klp_post_unpatch_t post_unpatch; + bool post_unpatch_enabled; +}; + +/* + * 'struct klp_{func,object}_ext' are compact "external" representations of + * 'struct klp_{func,object}'. They are used by objtool for livepatch + * generation. The structs are then read by the livepatch module and conv= erted + * to the real structs before calling klp_enable_patch(). + * + * TODO make these the official API for klp_enable_patch(). That should + * simplify livepatch's interface as well as its data structure lifetime + * management. + */ +struct klp_func_ext { + const char *old_name; + void *new_func; + unsigned long sympos; +}; + +struct klp_object_ext { + const char *name; + struct klp_func_ext *funcs; + struct klp_callbacks callbacks; + unsigned int nr_funcs; +}; + +#endif /* _LINUX_LIVEPATCH_EXTERNAL_H_ */ diff --git a/tools/objtool/Build b/tools/objtool/Build index a3cdf8af6635..0b01657671d7 100644 --- a/tools/objtool/Build +++ b/tools/objtool/Build @@ -8,8 +8,8 @@ objtool-y +=3D builtin-check.o objtool-y +=3D elf.o objtool-y +=3D objtool.o =20 -objtool-$(BUILD_ORC) +=3D orc_gen.o -objtool-$(BUILD_ORC) +=3D orc_dump.o +objtool-$(BUILD_ORC) +=3D orc_gen.o orc_dump.o +objtool-$(BUILD_KLP) +=3D builtin-klp.o klp-diff.o =20 objtool-y +=3D libstring.o objtool-y +=3D libctype.o diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile index 958761c05b7c..48928c9bebef 100644 --- a/tools/objtool/Makefile +++ b/tools/objtool/Makefile @@ -15,13 +15,14 @@ ifeq ($(ARCH_HAS_KLP),y) HAVE_XXHASH =3D $(shell echo "int main() {}" | \ $(HOSTCC) -xc - -o /dev/null -lxxhash 2> /dev/null && echo y || ec= ho n) ifeq ($(HAVE_XXHASH),y) + BUILD_KLP :=3D y LIBXXHASH_CFLAGS :=3D $(shell $(HOSTPKG_CONFIG) libxxhash --cflags 2>/de= v/null) \ -DBUILD_KLP LIBXXHASH_LIBS :=3D $(shell $(HOSTPKG_CONFIG) libxxhash --libs 2>/dev/= null || echo -lxxhash) endif endif =20 -export BUILD_ORC +export BUILD_ORC BUILD_KLP =20 ifeq ($(srctree),) srctree :=3D $(patsubst %/,%,$(dir $(CURDIR))) diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decod= e.c index cdf385e54c69..ae4f83fcbadf 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -95,6 +95,46 @@ s64 arch_insn_adjusted_addend(struct instruction *insn, = struct reloc *reloc) return phys_to_virt(addend); } =20 +static void scan_for_insn(struct section *sec, unsigned long offset, + unsigned long *insn_off, unsigned int *insn_len) +{ + unsigned long o =3D 0; + struct insn insn; + + while (1) { + + insn_decode(&insn, sec->data->d_buf + o, sec_size(sec) - o, + INSN_MODE_64); + + if (o + insn.length > offset) { + *insn_off =3D o; + *insn_len =3D insn.length; + return; + } + + o +=3D insn.length; + } +} + +u64 arch_adjusted_addend(struct reloc *reloc) +{ + unsigned int type =3D reloc_type(reloc); + s64 addend =3D reloc_addend(reloc); + unsigned long insn_off; + unsigned int insn_len; + + if (type =3D=3D R_X86_64_PLT32) + return addend + 4; + + if (type !=3D R_X86_64_PC32 || !is_text_sec(reloc->sec->base)) + return addend; + + scan_for_insn(reloc->sec->base, reloc_offset(reloc), + &insn_off, &insn_len); + + return addend + insn_off + insn_len - reloc_offset(reloc); +} + unsigned long arch_jump_destination(struct instruction *insn) { return insn->offset + insn->len + insn->immediate; diff --git a/tools/objtool/builtin-klp.c b/tools/objtool/builtin-klp.c new file mode 100644 index 000000000000..9b13dd1182af --- /dev/null +++ b/tools/objtool/builtin-klp.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#include +#include +#include +#include +#include +#include + +struct subcmd { + const char *name; + const char *description; + int (*fn)(int, const char **); +}; + +static struct subcmd subcmds[] =3D { + { "diff", "Generate binary diff of two object files", cmd_klp_diff, }, +}; + +static void cmd_klp_usage(void) +{ + fprintf(stderr, "usage: objtool klp []\n\n"); + fprintf(stderr, "Subcommands:\n"); + + for (int i =3D 0; i < ARRAY_SIZE(subcmds); i++) { + struct subcmd *cmd =3D &subcmds[i]; + + fprintf(stderr, " %s\t%s\n", cmd->name, cmd->description); + } + + exit(1); +} + +int cmd_klp(int argc, const char **argv) +{ + argc--; + argv++; + + if (!argc) + cmd_klp_usage(); + + if (argc) { + for (int i =3D 0; i < ARRAY_SIZE(subcmds); i++) { + struct subcmd *cmd =3D &subcmds[i]; + + if (!strcmp(cmd->name, argv[0])) + return cmd->fn(argc, argv); + } + } + + cmd_klp_usage(); + return 0; +} diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index a7ed357be5b9..645f7ac12869 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -288,6 +288,18 @@ struct symbol *find_symbol_by_name(const struct elf *e= lf, const char *name) return NULL; } =20 +struct symbol *find_global_symbol_by_name(const struct elf *elf, const cha= r *name) +{ + struct symbol *sym; + + elf_hash_for_each_possible(symbol_name, sym, name_hash, str_hash(name)) { + if (!strcmp(sym->name, name) && !is_local_sym(sym)) + return sym; + } + + return NULL; +} + struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct secti= on *sec, unsigned long offset, unsigned int len) { @@ -475,6 +487,8 @@ static int elf_add_symbol(struct elf *elf, struct symbo= l *sym) else entry =3D &sym->sec->symbol_list; list_add(&sym->list, entry); + + list_add_tail(&sym->global_list, &elf->symbols); elf_hash_add(symbol, &sym->hash, sym->idx); elf_hash_add(symbol_name, &sym->name_hash, str_hash(sym->name)); =20 @@ -529,6 +543,9 @@ static int read_symbols(struct elf *elf) ERROR_GLIBC("calloc"); return -1; } + + INIT_LIST_HEAD(&elf->symbols); + for (i =3D 0; i < symbols_nr; i++) { sym =3D &elf->symbol_data[i]; =20 @@ -637,7 +654,7 @@ static int mark_group_syms(struct elf *elf) return -1; } =20 - list_for_each_entry(sec, &elf->sections, list) { + for_each_sec(elf, sec) { if (sec->sh.sh_type =3D=3D SHT_GROUP && sec->sh.sh_link =3D=3D symtab->idx) { sym =3D find_symbol_by_index(elf, sec->sh.sh_info); @@ -1220,6 +1237,8 @@ struct elf *elf_create_file(GElf_Ehdr *ehdr, const ch= ar *name) return NULL; } =20 + INIT_LIST_HEAD(&elf->symbols); + if (!elf_alloc_hash(section, 1000) || !elf_alloc_hash(section_name, 1000) || !elf_alloc_hash(symbol, 10000) || diff --git a/tools/objtool/include/objtool/arch.h b/tools/objtool/include/o= bjtool/arch.h index 07729a240159..03c86caec4d6 100644 --- a/tools/objtool/include/objtool/arch.h +++ b/tools/objtool/include/objtool/arch.h @@ -84,6 +84,7 @@ bool arch_callee_saved_reg(unsigned char reg); unsigned long arch_jump_destination(struct instruction *insn); =20 s64 arch_insn_adjusted_addend(struct instruction *insn, struct reloc *relo= c); +u64 arch_adjusted_addend(struct reloc *reloc); =20 const char *arch_nop_insn(int len); const char *arch_ret_insn(int len); diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/includ= e/objtool/builtin.h index ceabafb43327..e8eb3c54c373 100644 --- a/tools/objtool/include/objtool/builtin.h +++ b/tools/objtool/include/objtool/builtin.h @@ -51,4 +51,6 @@ int objtool_run(int argc, const char **argv); =20 void print_args(void); =20 +int cmd_klp(int argc, const char **argv); + #endif /* _BUILTIN_H */ diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index 4cfd09e66cb5..f62ac8081f27 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -17,6 +17,7 @@ #include #include =20 +#define SEC_NAME_LEN 512 #define SYM_NAME_LEN 512 =20 #ifdef LIBELF_USE_DEPRECATED @@ -50,10 +51,12 @@ struct section { bool _changed, text, rodata, noinstr, init, truncate; struct reloc *relocs; unsigned long nr_alloc_relocs; + struct section *twin; }; =20 struct symbol { struct list_head list; + struct list_head global_list; struct rb_node node; struct elf_hash_node hash; struct elf_hash_node name_hash; @@ -79,10 +82,13 @@ struct symbol { u8 cold : 1; u8 prefix : 1; u8 debug_checksum : 1; + u8 changed : 1; + u8 included : 1; struct list_head pv_target; struct reloc *relocs; struct section *group_sec; struct checksum csum; + struct symbol *twin, *clone; }; =20 struct reloc { @@ -100,6 +106,7 @@ struct elf { const char *name, *tmp_name; unsigned int num_files; struct list_head sections; + struct list_head symbols; unsigned long num_relocs; =20 int symbol_bits; @@ -175,6 +182,7 @@ struct section *find_section_by_name(const struct elf *= elf, const char *name); struct symbol *find_func_by_offset(struct section *sec, unsigned long offs= et); struct symbol *find_symbol_by_offset(struct section *sec, unsigned long of= fset); struct symbol *find_symbol_by_name(const struct elf *elf, const char *name= ); +struct symbol *find_global_symbol_by_name(const struct elf *elf, const cha= r *name); struct symbol *find_symbol_containing(const struct section *sec, unsigned = long offset); int find_symbol_hole_containing(const struct section *sec, unsigned long o= ffset); struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *se= c, unsigned long offset); @@ -435,22 +443,44 @@ static inline void set_sym_next_reloc(struct reloc *r= eloc, struct reloc *next) #define sec_for_each_sym(sec, sym) \ list_for_each_entry(sym, &sec->symbol_list, list) =20 +#define sec_prev_sym(sym) \ + sym->sec && sym->list.prev !=3D &sym->sec->symbol_list ? \ + list_prev_entry(sym, list) : NULL + #define for_each_sym(elf, sym) \ - for (struct section *__sec, *__fake =3D (struct section *)1; \ - __fake; __fake =3D NULL) \ - for_each_sec(elf, __sec) \ - sec_for_each_sym(__sec, sym) + list_for_each_entry(sym, &elf->symbols, global_list) + +#define for_each_sym_continue(elf, sym) \ + list_for_each_entry_continue(sym, &elf->symbols, global_list) + +#define rsec_next_reloc(rsec, reloc) \ + reloc_idx(reloc) < sec_num_entries(rsec) - 1 ? reloc + 1 : NULL =20 #define for_each_reloc(rsec, reloc) \ - for (int __i =3D 0, __fake =3D 1; __fake; __fake =3D 0) \ - for (reloc =3D rsec->relocs; \ - __i < sec_num_entries(rsec); \ - __i++, reloc++) + for (reloc =3D rsec->relocs; reloc; reloc =3D rsec_next_reloc(rsec, reloc= )) =20 #define for_each_reloc_from(rsec, reloc) \ - for (int __i =3D reloc_idx(reloc); \ - __i < sec_num_entries(rsec); \ - __i++, reloc++) + for (; reloc; reloc =3D rsec_next_reloc(rsec, reloc)) + +#define sym_for_each_reloc(elf, sym, reloc) \ + for (reloc =3D find_reloc_by_dest_range(elf, sym->sec, \ + sym->offset, sym->len); \ + reloc && reloc_offset(reloc) < sym->offset + sym->len; \ + reloc =3D rsec_next_reloc(sym->sec->rsec, reloc)) + +static inline struct symbol *get_func_prefix(struct symbol *func) +{ + struct symbol *prev; + + if (!is_func_sym(func)) + return NULL; + + prev =3D sec_prev_sym(func); + if (prev && is_prefix_func(prev)) + return prev; + + return NULL; +} =20 #define OFFSET_STRIDE_BITS 4 #define OFFSET_STRIDE (1UL << OFFSET_STRIDE_BITS) diff --git a/tools/objtool/include/objtool/klp.h b/tools/objtool/include/ob= jtool/klp.h new file mode 100644 index 000000000000..07928fac059b --- /dev/null +++ b/tools/objtool/include/objtool/klp.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef _OBJTOOL_KLP_H +#define _OBJTOOL_KLP_H + +/* + * __klp_objects and __klp_funcs are created by klp diff and used by the p= atch + * module init code to build the klp_patch, klp_object and klp_func structs + * needed by the livepatch API. + */ +#define KLP_OBJECTS_SEC "__klp_objects" +#define KLP_FUNCS_SEC "__klp_funcs" + +/* + * __klp_relocs is an intermediate section which are created by klp diff a= nd + * converted into KLP symbols/relas by "objtool klp post-link". This is n= eeded + * to work around the linker, which doesn't preserve SHN_LIVEPATCH or + * SHF_RELA_LIVEPATCH, nor does it support having two RELA sections for a + * single PROGBITS section. + */ +#define KLP_RELOCS_SEC "__klp_relocs" +#define KLP_STRINGS_SEC ".rodata.klp.str1.1" + +struct klp_reloc { + void *offset; + void *sym; + u32 type; +}; + +int cmd_klp_diff(int argc, const char **argv); + +#endif /* _OBJTOOL_KLP_H */ diff --git a/tools/objtool/include/objtool/objtool.h b/tools/objtool/includ= e/objtool/objtool.h index 90c591b5bd68..37e9fe4492d6 100644 --- a/tools/objtool/include/objtool/objtool.h +++ b/tools/objtool/include/objtool/objtool.h @@ -41,6 +41,8 @@ struct objtool_file { struct pv_state *pv_ops; }; =20 +char *top_level_dir(const char *file); + struct objtool_file *objtool_open_read(const char *_objname); =20 int objtool_pv_add(struct objtool_file *file, int idx, struct symbol *func= ); diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c new file mode 100644 index 000000000000..f17e4809ad4b --- /dev/null +++ b/tools/objtool/klp-diff.c @@ -0,0 +1,1429 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#define _GNU_SOURCE /* memmem() */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define sizeof_field(TYPE, MEMBER) sizeof((((TYPE *)0)->MEMBER)) + +struct elfs { + struct elf *orig, *patched, *out; + const char *modname; +}; + +struct export { + struct hlist_node hash; + char *mod, *sym; +}; + +static const char * const klp_diff_usage[] =3D { + "objtool klp diff [] ", + NULL, +}; + +static const struct option klp_diff_options[] =3D { + OPT_END(), +}; + +static DEFINE_HASHTABLE(exports, 15); + +static inline u32 str_hash(const char *str) +{ + return jhash(str, strlen(str), 0); +} + +/* + * Do a sanity check to make sure the changed object was built with + * -ffunction-sections and -fdata-sections. + */ +static int validate_ffunction_fdata_sections(struct elf *elf) +{ + struct symbol *sym; + bool found_text =3D false, found_data =3D false; + + for_each_sym(elf, sym) { + char sec_name[SEC_NAME_LEN]; + + if (!found_text && is_func_sym(sym)) { + snprintf(sec_name, SEC_NAME_LEN, ".text.%s", sym->name); + if (!strcmp(sym->sec->name, sec_name)) + found_text =3D true; + } + + if (!found_data && is_object_sym(sym)) { + snprintf(sec_name, SEC_NAME_LEN, ".data.%s", sym->name); + if (!strcmp(sym->sec->name, sec_name)) + found_data =3D true; + } + + if (found_text && found_data) + return 0; + } + + ERROR("changed object '%s' not built with -ffunction-sections and -fdata-= sections", elf->name); + return -1; +} + +static int read_exports(void) +{ + const char *symvers =3D "Module.symvers"; + char line[1024], *path =3D NULL; + FILE *file; + + file =3D fopen(symvers, "r"); + if (!file) { + path =3D top_level_dir(symvers); + if (!path) { + ERROR("can't open '%s', \"objtool diff\" should be run from the kernel = tree", symvers); + return -1; + } + + file =3D fopen(path, "r"); + if (!file) { + ERROR_GLIBC("fopen"); + return -1; + } + } + + while (fgets(line, 1024, file)) { + char *sym, *mod, *exp; + struct export *export; + + sym =3D strchr(line, '\t'); + if (!sym) { + ERROR("malformed Module.symvers"); + return -1; + } + + *sym++ =3D '\0'; + + mod =3D strchr(sym, '\t'); + if (!mod) { + ERROR("malformed Module.symvers"); + return -1; + } + + *mod++ =3D '\0'; + + exp =3D strchr(mod, '\t'); + if (!exp) { + ERROR("malformed Module.symvers"); + return -1; + } + + *exp++ =3D '\0'; + + if (*sym =3D=3D '\0' || *mod =3D=3D '\0') { + ERROR("malformed Module.symvers"); + return -1; + } + + export =3D calloc(1, sizeof(*export)); + if (!export) { + ERROR_GLIBC("calloc"); + return -1; + } + + export->mod =3D strdup(mod); + if (!export->mod) { + ERROR_GLIBC("strdup"); + return -1; + } + export->sym =3D strdup(sym); + if (!export->sym) { + ERROR_GLIBC("strdup"); + return -1; + } + + hash_add(exports, &export->hash, str_hash(sym)); + } + + free(path); + fclose(file); + + return 0; +} + +static int read_sym_checksums(struct elf *elf) +{ + struct section *sec; + + sec =3D find_section_by_name(elf, SYM_CHECKSUM_SEC); + if (!sec) { + ERROR("'%s' missing " SYM_CHECKSUM_SEC " section, file not processed by = 'objtool --checksum'?", + elf->name); + return -1; + } + + if (!sec->rsec) { + ERROR("missing reloc section for " SYM_CHECKSUM_SEC); + return -1; + } + + if (sec_size(sec) % sizeof(struct sym_checksum)) { + ERROR("struct sym_checksum size mismatch"); + return -1; + } + + for (int i =3D 0; i < sec_size(sec) / sizeof(struct sym_checksum); i++) { + struct sym_checksum *sym_checksum; + struct reloc *reloc; + struct symbol *sym; + + sym_checksum =3D (struct sym_checksum *)sec->data->d_buf + i; + + reloc =3D find_reloc_by_dest(elf, sec, i * sizeof(*sym_checksum)); + if (!reloc) { + ERROR("can't find reloc for sym_checksum[%d]", i); + return -1; + } + + sym =3D reloc->sym; + + if (is_sec_sym(sym)) { + ERROR("not sure how to handle section %s", sym->name); + return -1; + } + + if (is_func_sym(sym)) + sym->csum.checksum =3D sym_checksum->checksum; + } + + return 0; +} + +static struct symbol *first_file_symbol(struct elf *elf) +{ + struct symbol *sym; + + for_each_sym(elf, sym) + if (is_file_sym(sym)) + return sym; + + return NULL; +} + +static struct symbol *next_file_symbol(struct elf *elf, struct symbol *sym) +{ + for_each_sym_continue(elf, sym) + if (is_file_sym(sym)) + return sym; + + return NULL; +} + +/* + * Certain static local variables should never be correlated. They will be + * used in place rather than referencing the originals. + */ +static bool is_uncorrelated_static_local(struct symbol *sym) +{ + static const char * const vars[] =3D { + "__key.", + "__warned.", + "__already_done.", + "__func__.", + "_rs.", + "CSWTCH.", + }; + + if (!is_object_sym(sym) || !is_local_sym(sym)) + return false; + + if (!strcmp(sym->sec->name, ".data.once")) + return true; + + for (int i =3D 0; i < ARRAY_SIZE(vars); i++) { + if (strstarts(sym->name, vars[i])) + return true; + } + + return false; +} + +/* + * Clang emits several useless .Ltmp_* code labels. + */ +static bool is_clang_tmp_label(struct symbol *sym) +{ + return sym->type =3D=3D STT_NOTYPE && + is_text_sec(sym->sec) && + strstarts(sym->name, ".Ltmp") && + isdigit(sym->name[5]); +} + +static bool is_special_section(struct section *sec) +{ + static const char * const specials[] =3D { + ".altinstructions", + ".smp_locks", + "__bug_table", + "__ex_table", + "__jump_table", + "__mcount_loc", + + /* + * Extract .static_call_sites here to inherit non-module + * preferential treatment. The later static call processing + * during klp module build will be skipped when it sees this + * section already exists. + */ + ".static_call_sites", + }; + + static const char * const non_special_discards[] =3D { + ".discard.addressable", + SYM_CHECKSUM_SEC, + }; + + for (int i =3D 0; i < ARRAY_SIZE(specials); i++) + if (!strcmp(sec->name, specials[i])) + return true; + + /* Most .discard sections are special */ + for (int i =3D 0; i < ARRAY_SIZE(non_special_discards); i++) + if (!strcmp(sec->name, non_special_discards[i])) + return false; + + return strstarts(sec->name, ".discard."); +} + +/* + * These sections are referenced by special sections but aren't considered + * special sections themselves. + */ +static bool is_special_section_aux(struct section *sec) +{ + static const char * const specials_aux[] =3D { + ".altinstr_replacement", + ".altinstr_aux", + }; + + for (int i =3D 0; i < ARRAY_SIZE(specials_aux); i++) + if (!strcmp(sec->name, specials_aux[i])) + return true; + + return false; +} + +/* + * These symbols should never be correlated, so their local patched versio= ns + * are used instead of linking to the originals. + */ +static bool dont_correlate(struct symbol *sym) +{ + return is_file_sym(sym) || + is_null_sym(sym) || + is_sec_sym(sym) || + is_prefix_func(sym) || + is_uncorrelated_static_local(sym) || + is_clang_tmp_label(sym) || + is_string_sec(sym->sec) || + is_special_section(sym->sec) || + is_special_section_aux(sym->sec) || + strstarts(sym->name, "__initcall__"); +} + +/* + * For each symbol in the original kernel, find its corresponding "twin" i= n the + * patched kernel. + */ +static int correlate_symbols(struct elfs *e) +{ + struct symbol *file1_sym, *file2_sym; + struct symbol *sym1, *sym2; + + /* Correlate locals */ + for (file1_sym =3D first_file_symbol(e->orig), + file2_sym =3D first_file_symbol(e->patched); ; + file1_sym =3D next_file_symbol(e->orig, file1_sym), + file2_sym =3D next_file_symbol(e->patched, file2_sym)) { + + if (!file1_sym && file2_sym) { + ERROR("FILE symbol mismatch: NULL !=3D %s", file2_sym->name); + return -1; + } + + if (file1_sym && !file2_sym) { + ERROR("FILE symbol mismatch: %s !=3D NULL", file1_sym->name); + return -1; + } + + if (!file1_sym) + break; + + if (strcmp(file1_sym->name, file2_sym->name)) { + ERROR("FILE symbol mismatch: %s !=3D %s", file1_sym->name, file2_sym->n= ame); + return -1; + } + + file1_sym->twin =3D file2_sym; + file2_sym->twin =3D file1_sym; + + sym1 =3D file1_sym; + + for_each_sym_continue(e->orig, sym1) { + if (is_file_sym(sym1) || !is_local_sym(sym1)) + break; + + if (dont_correlate(sym1)) + continue; + + sym2 =3D file2_sym; + for_each_sym_continue(e->patched, sym2) { + if (is_file_sym(sym2) || !is_local_sym(sym2)) + break; + + if (sym2->twin || dont_correlate(sym2)) + continue; + + if (strcmp(sym1->demangled_name, sym2->demangled_name)) + continue; + + sym1->twin =3D sym2; + sym2->twin =3D sym1; + break; + } + } + } + + /* Correlate globals */ + for_each_sym(e->orig, sym1) { + if (sym1->bind =3D=3D STB_LOCAL) + continue; + + sym2 =3D find_global_symbol_by_name(e->patched, sym1->name); + + if (sym2 && !sym2->twin && !strcmp(sym1->name, sym2->name)) { + sym1->twin =3D sym2; + sym2->twin =3D sym1; + } + } + + for_each_sym(e->orig, sym1) { + if (sym1->twin || dont_correlate(sym1)) + continue; + WARN("no correlation: %s", sym1->name); + } + + return 0; +} + +/* "sympos" is used by livepatch to disambiguate duplicate symbol names */ +static unsigned long find_sympos(struct elf *elf, struct symbol *sym) +{ + unsigned long sympos =3D 0, nr_matches =3D 0; + bool has_dup =3D false; + struct symbol *s; + + if (sym->bind !=3D STB_LOCAL) + return 0; + + for_each_sym(elf, s) { + if (!strcmp(s->name, sym->name)) { + nr_matches++; + if (s =3D=3D sym) + sympos =3D nr_matches; + else + has_dup =3D true; + } + } + + if (!sympos) { + ERROR("can't find sympos for %s", sym->name); + return ULONG_MAX; + } + + return has_dup ? sympos : 0; +} + +static int clone_sym_relocs(struct elfs *e, struct symbol *patched_sym); + +static struct symbol *__clone_symbol(struct elf *elf, struct symbol *patch= ed_sym, + bool data_too) +{ + struct section *out_sec =3D NULL; + unsigned long offset =3D 0; + struct symbol *out_sym; + + if (data_too && !is_undef_sym(patched_sym)) { + struct section *patched_sec =3D patched_sym->sec; + + out_sec =3D find_section_by_name(elf, patched_sec->name); + if (!out_sec) { + out_sec =3D elf_create_section(elf, patched_sec->name, 0, + patched_sec->sh.sh_entsize, + patched_sec->sh.sh_type, + patched_sec->sh.sh_addralign, + patched_sec->sh.sh_flags); + if (!out_sec) + return NULL; + } + + if (is_string_sec(patched_sym->sec)) { + out_sym =3D elf_create_section_symbol(elf, out_sec); + if (!out_sym) + return NULL; + + goto sym_created; + } + + if (!is_sec_sym(patched_sym)) + offset =3D sec_size(out_sec); + + if (patched_sym->len || is_sec_sym(patched_sym)) { + void *data =3D NULL; + size_t size; + + /* bss doesn't have data */ + if (patched_sym->sec->data->d_buf) + data =3D patched_sym->sec->data->d_buf + patched_sym->offset; + + if (is_sec_sym(patched_sym)) + size =3D sec_size(patched_sym->sec); + else + size =3D patched_sym->len; + + if (!elf_add_data(elf, out_sec, data, size)) + return NULL; + } + } + + out_sym =3D elf_create_symbol(elf, patched_sym->name, out_sec, + patched_sym->bind, patched_sym->type, + offset, patched_sym->len); + if (!out_sym) + return NULL; + +sym_created: + patched_sym->clone =3D out_sym; + out_sym->clone =3D patched_sym; + + return out_sym; +} + +/* + * Copy a symbol to the output object, optionally including its data and + * relocations. + */ +static struct symbol *clone_symbol(struct elfs *e, struct symbol *patched_= sym, + bool data_too) +{ + struct symbol *pfx; + + if (patched_sym->clone) + return patched_sym->clone; + + /* Make sure the prefix gets cloned first */ + if (is_func_sym(patched_sym) && data_too) { + pfx =3D get_func_prefix(patched_sym); + if (pfx) + clone_symbol(e, pfx, true); + } + + if (!__clone_symbol(e->out, patched_sym, data_too)) + return NULL; + + if (data_too && clone_sym_relocs(e, patched_sym)) + return NULL; + + return patched_sym->clone; +} + +static void mark_included_function(struct symbol *func) +{ + struct symbol *pfx; + + func->included =3D 1; + + /* Include prefix function */ + pfx =3D get_func_prefix(func); + if (pfx) + pfx->included =3D 1; + + /* Make sure .cold parent+child always stay together */ + if (func->cfunc && func->cfunc !=3D func) + func->cfunc->included =3D 1; + if (func->pfunc && func->pfunc !=3D func) + func->pfunc->included =3D 1; +} + +/* + * Copy all changed functions (and their dependencies) from the patched ob= ject + * to the output object. + */ +static int mark_changed_functions(struct elfs *e) +{ + struct symbol *sym_orig, *patched_sym; + bool changed =3D false; + + /* Find changed functions */ + for_each_sym(e->orig, sym_orig) { + if (!is_func_sym(sym_orig) || is_prefix_func(sym_orig)) + continue; + + patched_sym =3D sym_orig->twin; + if (!patched_sym) + continue; + + if (sym_orig->csum.checksum !=3D patched_sym->csum.checksum) { + patched_sym->changed =3D 1; + mark_included_function(patched_sym); + changed =3D true; + } + } + + /* Find added functions and print them */ + for_each_sym(e->patched, patched_sym) { + if (!is_func_sym(patched_sym) || is_prefix_func(patched_sym)) + continue; + + if (!patched_sym->twin) { + printf("%s: new function: %s\n", objname, patched_sym->name); + mark_included_function(patched_sym); + changed =3D true; + } + } + + /* Print changed functions */ + for_each_sym(e->patched, patched_sym) { + if (patched_sym->changed) + printf("%s: changed function: %s\n", objname, patched_sym->name); + } + + return !changed ? -1 : 0; +} + +static int clone_included_functions(struct elfs *e) +{ + struct symbol *patched_sym; + + for_each_sym(e->patched, patched_sym) { + if (patched_sym->included) { + if (!clone_symbol(e, patched_sym, true)) + return -1; + } + } + + return 0; +} + +/* + * Determine whether a relocation should reference the section rather than= the + * underlying symbol. + */ +static bool section_reference_needed(struct section *sec) +{ + /* + * String symbols are zero-length and uncorrelated. It's easier to + * deal with them as section symbols. + */ + if (is_string_sec(sec)) + return true; + + /* + * .rodata has mostly anonymous data so there's no way to determine the + * length of a needed reference. just copy the whole section if needed. + */ + if (strstarts(sec->name, ".rodata")) + return true; + + /* UBSAN anonymous data */ + if (strstarts(sec->name, ".data..Lubsan") || /* GCC */ + strstarts(sec->name, ".data..L__unnamed_")) /* Clang */ + return true; + + return false; +} + +static bool is_reloc_allowed(struct reloc *reloc) +{ + return section_reference_needed(reloc->sym->sec) =3D=3D is_sec_sym(reloc-= >sym); +} + +static struct export *find_export(struct symbol *sym) +{ + struct export *export; + + hash_for_each_possible(exports, export, hash, str_hash(sym->name)) { + if (!strcmp(export->sym, sym->name)) + return export; + } + + return NULL; +} + +static const char *__find_modname(struct elfs *e) +{ + struct section *sec; + char *name; + + sec =3D find_section_by_name(e->orig, ".modinfo"); + if (!sec) { + ERROR("missing .modinfo section"); + return NULL; + } + + name =3D memmem(sec->data->d_buf, sec_size(sec), "\0name=3D", 6); + if (name) + return name + 6; + + name =3D strdup(e->orig->name); + if (!name) { + ERROR_GLIBC("strdup"); + return NULL; + } + + for (char *c =3D name; *c; c++) { + if (*c =3D=3D '/') + name =3D c + 1; + else if (*c =3D=3D '-') + *c =3D '_'; + else if (*c =3D=3D '.') { + *c =3D '\0'; + break; + } + } + + return name; +} + +/* Get the object's module name as defined by the kernel (and klp_object) = */ +static const char *find_modname(struct elfs *e) +{ + const char *modname; + + if (e->modname) + return e->modname; + + modname =3D __find_modname(e); + e->modname =3D modname; + return modname; +} + +/* + * Copying a function from its native compiled environment to a kernel mod= ule + * removes its natural access to local functions/variables and unexported + * globals. References to such symbols need to be converted to KLP relocs= so + * the kernel arch relocation code knows to apply them and where to find t= he + * symbols. Particularly, duplicate static symbols need to be disambiguat= ed. + */ +static bool klp_reloc_needed(struct reloc *patched_reloc) +{ + struct symbol *patched_sym =3D patched_reloc->sym; + struct export *export; + + /* no external symbol to reference */ + if (dont_correlate(patched_sym)) + return false; + + /* For included functions, a regular reloc will do. */ + if (patched_sym->included) + return false; + + /* + * If exported by a module, it has to be a klp reloc. Thanks to the + * clusterfoot that is late module patching, the patch module is + * allowed to be loaded before any modules it depends on. + * + * If exported by vmlinux, a normal reloc will do. + */ + export =3D find_export(patched_sym); + if (export) + return strcmp(export->mod, "vmlinux"); + + if (!patched_sym->twin) { + /* + * Presumably the symbol and its reference were added by the + * patch. The symbol could be defined in this .o or in another + * .o in the patch module. + * + * This check needs to be *after* the export check due to the + * possibility of the patch adding a new UNDEF reference to an + * exported symbol. + */ + return false; + } + + /* Unexported symbol which lives in the original vmlinux or module. */ + return true; +} + +static int convert_reloc_sym_to_secsym(struct elf *elf, struct reloc *relo= c) +{ + struct symbol *sym =3D reloc->sym; + struct section *sec =3D sym->sec; + + if (!sec->sym && !elf_create_section_symbol(elf, sec)) + return -1; + + reloc->sym =3D sec->sym; + set_reloc_sym(elf, reloc, sym->idx); + set_reloc_addend(elf, reloc, sym->offset + reloc_addend(reloc)); + return 0; +} + +static int convert_reloc_secsym_to_sym(struct elf *elf, struct reloc *relo= c) +{ + struct symbol *sym =3D reloc->sym; + struct section *sec =3D sym->sec; + + /* If the symbol has a dedicated section, it's easy to find */ + sym =3D find_symbol_by_offset(sec, 0); + if (sym && sym->len =3D=3D sec_size(sec)) + goto found_sym; + + /* No dedicated section; find the symbol manually */ + sym =3D find_symbol_containing(sec, arch_adjusted_addend(reloc)); + if (!sym) { + /* + * This can happen for special section references to weak code + * whose symbol has been stripped by the linker. + */ + return -1; + } + +found_sym: + reloc->sym =3D sym; + set_reloc_sym(elf, reloc, sym->idx); + set_reloc_addend(elf, reloc, reloc_addend(reloc) - sym->offset); + return 0; +} + +/* + * Convert a relocation symbol reference to the needed format: either a se= ction + * symbol or the underlying symbol itself. + */ +static int convert_reloc_sym(struct elf *elf, struct reloc *reloc) +{ + if (is_reloc_allowed(reloc)) + return 0; + + if (section_reference_needed(reloc->sym->sec)) + return convert_reloc_sym_to_secsym(elf, reloc); + else + return convert_reloc_secsym_to_sym(elf, reloc); +} + +/* + * Convert a regular relocation to a klp relocation (sort of). + */ +static int clone_reloc_klp(struct elfs *e, struct reloc *patched_reloc, + struct section *sec, unsigned long offset, + struct export *export) +{ + struct symbol *patched_sym =3D patched_reloc->sym; + s64 addend =3D reloc_addend(patched_reloc); + const char *sym_modname, *sym_orig_name; + static struct section *klp_relocs; + struct symbol *sym, *klp_sym; + unsigned long klp_reloc_off; + char sym_name[SYM_NAME_LEN]; + struct klp_reloc klp_reloc; + unsigned long sympos; + + if (!patched_sym->twin) { + ERROR("unexpected klp reloc for new symbol %s", patched_sym->name); + return -1; + } + + /* + * Keep the original reloc intact for now to avoid breaking objtool run + * which relies on proper relocations for many of its features. This + * will be disabled later by "objtool klp post-link". + * + * Convert it to UNDEF (and WEAK to avoid modpost warnings). + */ + + sym =3D patched_sym->clone; + if (!sym) { + /* STB_WEAK: avoid modpost undefined symbol warnings */ + sym =3D elf_create_symbol(e->out, patched_sym->name, NULL, + STB_WEAK, patched_sym->type, 0, 0); + if (!sym) + return -1; + + patched_sym->clone =3D sym; + sym->clone =3D patched_sym; + } + + if (!elf_create_reloc(e->out, sec, offset, sym, addend, reloc_type(patche= d_reloc))) + return -1; + + /* + * Create the KLP symbol. + */ + + if (export) { + sym_modname =3D export->mod; + sym_orig_name =3D export->sym; + sympos =3D 0; + } else { + sym_modname =3D find_modname(e); + if (!sym_modname) + return -1; + + sym_orig_name =3D patched_sym->twin->name; + sympos =3D find_sympos(e->orig, patched_sym->twin); + if (sympos =3D=3D ULONG_MAX) + return -1; + } + + /* symbol format: .klp.sym.modname.sym_name,sympos */ + snprintf(sym_name, SYM_NAME_LEN, KLP_SYM_PREFIX "%s.%s,%ld", + sym_modname, sym_orig_name, sympos); + + klp_sym =3D find_symbol_by_name(e->out, sym_name); + if (!klp_sym) { + /* STB_WEAK: avoid modpost undefined symbol warnings */ + klp_sym =3D elf_create_symbol(e->out, sym_name, NULL, + STB_WEAK, patched_sym->type, 0, 0); + if (!klp_sym) + return -1; + } + + /* + * Create the __klp_relocs entry. This will be converted to an actual + * KLP rela by "objtool klp post-link". + * + * This intermediate step is necessary to prevent corruption by the + * linker, which doesn't know how to properly handle two rela sections + * applying to the same base section. + */ + + if (!klp_relocs) { + klp_relocs =3D elf_create_section(e->out, KLP_RELOCS_SEC, 0, + 0, SHT_PROGBITS, 8, SHF_ALLOC); + if (!klp_relocs) + return -1; + } + + klp_reloc_off =3D sec_size(klp_relocs); + memset(&klp_reloc, 0, sizeof(klp_reloc)); + + klp_reloc.type =3D reloc_type(patched_reloc); + if (!elf_add_data(e->out, klp_relocs, &klp_reloc, sizeof(klp_reloc))) + return -1; + + /* klp_reloc.offset */ + if (!sec->sym && !elf_create_section_symbol(e->out, sec)) + return -1; + + if (!elf_create_reloc(e->out, klp_relocs, + klp_reloc_off + offsetof(struct klp_reloc, offset), + sec->sym, offset, R_ABS64)) + return -1; + + /* klp_reloc.sym */ + if (!elf_create_reloc(e->out, klp_relocs, + klp_reloc_off + offsetof(struct klp_reloc, sym), + klp_sym, addend, R_ABS64)) + return -1; + + return 0; +} + +/* Copy a reloc and its symbol to the output object */ +static int clone_reloc(struct elfs *e, struct reloc *patched_reloc, + struct section *sec, unsigned long offset) +{ + struct symbol *patched_sym =3D patched_reloc->sym; + struct export *export =3D find_export(patched_sym); + long addend =3D reloc_addend(patched_reloc); + struct symbol *out_sym; + bool klp; + + if (!is_reloc_allowed(patched_reloc)) { + ERROR_FUNC(patched_reloc->sec->base, reloc_offset(patched_reloc), + "missing symbol for reference to %s+%ld", + patched_sym->name, addend); + return -1; + } + + klp =3D klp_reloc_needed(patched_reloc); + + if (klp) { + if (clone_reloc_klp(e, patched_reloc, sec, offset, export)) + return -1; + + return 0; + } + + /* + * Why !export sets 'data_too': + * + * Unexported non-klp symbols need to live in the patch module, + * otherwise there will be unresolved symbols. Notably, this includes: + * + * - New functions/data + * - String sections + * - Special section entries + * - Uncorrelated static local variables + * - UBSAN sections + */ + out_sym =3D clone_symbol(e, patched_sym, patched_sym->included || !export= ); + if (!out_sym) + return -1; + + /* + * For strings, all references use section symbols, thanks to + * section_reference_needed(). clone_symbol() has cloned an empty + * version of the string section. Now copy the string itself. + */ + if (is_string_sec(patched_sym->sec)) { + const char *str =3D patched_sym->sec->data->d_buf + addend; + + addend =3D elf_add_string(e->out, out_sym->sec, str); + if (addend =3D=3D -1) + return -1; + } + + if (!elf_create_reloc(e->out, sec, offset, out_sym, addend, + reloc_type(patched_reloc))) + return -1; + + return 0; +} + +/* Copy all relocs needed for a symbol's contents */ +static int clone_sym_relocs(struct elfs *e, struct symbol *patched_sym) +{ + struct section *patched_rsec =3D patched_sym->sec->rsec; + struct reloc *patched_reloc; + unsigned long start, end; + struct symbol *out_sym; + + out_sym =3D patched_sym->clone; + if (!out_sym) { + ERROR("no clone for %s", patched_sym->name); + return -1; + } + + if (!patched_rsec) + return 0; + + if (!is_sec_sym(patched_sym) && !patched_sym->len) + return 0; + + if (is_string_sec(patched_sym->sec)) + return 0; + + if (is_sec_sym(patched_sym)) { + start =3D 0; + end =3D sec_size(patched_sym->sec); + } else { + start =3D patched_sym->offset; + end =3D start + patched_sym->len; + } + + for_each_reloc(patched_rsec, patched_reloc) { + unsigned long offset; + + if (reloc_offset(patched_reloc) < start || + reloc_offset(patched_reloc) >=3D end) + continue; + + /* + * Skip any reloc referencing .altinstr_aux. Its code is + * always patched by alternatives. See ALTERNATIVE_TERNARY(). + */ + if (patched_reloc->sym->sec && + !strcmp(patched_reloc->sym->sec->name, ".altinstr_aux")) + continue; + + if (convert_reloc_sym(e->patched, patched_reloc)) { + ERROR_FUNC(patched_rsec->base, reloc_offset(patched_reloc), + "failed to convert reloc sym '%s' to its proper format", + patched_reloc->sym->name); + return -1; + } + + offset =3D out_sym->offset + (reloc_offset(patched_reloc) - patched_sym-= >offset); + + if (clone_reloc(e, patched_reloc, out_sym->sec, offset)) + return -1; + } + return 0; + +} + +/* Keep a special section entry if it references an included function */ +static bool should_keep_special_sym(struct elf *elf, struct symbol *sym) +{ + struct reloc *reloc; + + if (is_sec_sym(sym) || !sym->sec->rsec) + return false; + + sym_for_each_reloc(elf, sym, reloc) { + if (convert_reloc_sym(elf, reloc)) + continue; + + if (is_func_sym(reloc->sym) && reloc->sym->included) + return true; + } + + return false; +} + +static int special_section_entry_size(struct section *sec) +{ + unsigned int reloc_size; + + if (sec->sh.sh_entsize) + return sec->sh.sh_entsize; + + if (!sec->rsec) + return 0; + + /* Check for a simple array of pointers */ + reloc_size =3D arch_reloc_size(sec->rsec->relocs); + if (sec_size(sec) =3D=3D reloc_size * sec_num_entries(sec->rsec)) + return reloc_size; + + return 0; +} + +static int create_fake_symbol(struct elf *elf, struct section *sec, + unsigned long offset, size_t size) +{ + unsigned int type; + char name[256]; + static int ctr; + char *c; + + snprintf(name, 256, "__DISCARD_%s_%d", sec->name, ctr++); + + for (c =3D name; *c; c++) + if (*c =3D=3D '.') + *c =3D '_'; + + /* + * STT_NOTYPE: Prevent objtool from validating .altinstr_replacement + * while still allowing objdump to disassemble it. + */ + type =3D is_text_sec(sec) ? STT_NOTYPE : STT_OBJECT; + if (!elf_create_symbol(elf, name, sec, STB_LOCAL, type, offset, size)) + return -1; + + return 0; +} + +static int clone_special_section(struct elfs *e, struct section *patched_s= ec) +{ + struct symbol *patched_sym; + unsigned int entry_size; + unsigned long offset; + + entry_size =3D special_section_entry_size(patched_sec); + if (!entry_size) { + ERROR("%s: unknown entry size", patched_sec->name); + return -1; + } + + /* + * In the patched object, create a fake symbol for each special section + * entry. This makes the below extracting of entries much easier. + */ + for (offset =3D 0; offset < sec_size(patched_sec); offset +=3D entry_size= ) { + if (create_fake_symbol(e->patched, patched_sec, offset, entry_size)) + return -1; + + /* Symbolize alternative replacements: */ + if (!strcmp(patched_sec->name, ".altinstructions")) { + struct reloc *reloc; + unsigned char size; + + reloc =3D find_reloc_by_dest(e->patched, patched_sec, offset + ALT_NEW_= OFFSET); + if (!reloc) { + ERROR_FUNC(patched_sec, offset + ALT_NEW_OFFSET, "can't find new reloc= "); + return -1; + } + + size =3D *(unsigned char *)(patched_sec->data->d_buf + offset + ALT_NEW= _LEN_OFFSET); + + if (create_fake_symbol(e->patched, reloc->sym->sec, + reloc->sym->offset + reloc_addend(reloc), size)) + return -1; + } + } + + /* + * Extract all special section entries (and their dependencies) which + * reference included functions. + */ + sec_for_each_sym(patched_sec, patched_sym) { + if (!is_object_sym(patched_sym)) + continue; + + if (!should_keep_special_sym(e->patched, patched_sym)) + continue; + + if (!clone_symbol(e, patched_sym, true)) + return -1; + } + + return 0; +} + +/* Extract only the needed bits from special sections */ +static int clone_special_sections(struct elfs *e) +{ + struct section *patched_sec; + + for_each_sec(e->patched, patched_sec) { + if (is_special_section(patched_sec)) { + if (clone_special_section(e, patched_sec)) + return -1; + } + } + + return 0; +} + +/* + * Create __klp_objects and __klp_funcs sections which are intermediate + * sections provided as input to the patch module's init code for building= the + * klp_patch, klp_object and klp_func structs for the livepatch API. + */ +static int create_klp_sections(struct elfs *e) +{ + size_t obj_size =3D sizeof(struct klp_object_ext); + size_t func_size =3D sizeof(struct klp_func_ext); + struct section *obj_sec, *funcs_sec, *str_sec; + struct symbol *funcs_sym, *str_sym, *sym; + char sym_name[SYM_NAME_LEN]; + unsigned int nr_funcs =3D 0; + const char *modname; + void *obj_data; + s64 addend; + + obj_sec =3D elf_create_section_pair(e->out, KLP_OBJECTS_SEC, obj_size, 0= , 0); + if (!obj_sec) + return -1; + + funcs_sec =3D elf_create_section_pair(e->out, KLP_FUNCS_SEC, func_size, 0= , 0); + if (!funcs_sec) + return -1; + + funcs_sym =3D elf_create_section_symbol(e->out, funcs_sec); + if (!funcs_sym) + return -1; + + str_sec =3D elf_create_section(e->out, KLP_STRINGS_SEC, 0, 0, + SHT_PROGBITS, 1, + SHF_ALLOC | SHF_STRINGS | SHF_MERGE); + if (!str_sec) + return -1; + + if (elf_add_string(e->out, str_sec, "") =3D=3D -1) + return -1; + + str_sym =3D elf_create_section_symbol(e->out, str_sec); + if (!str_sym) + return -1; + + /* allocate klp_object_ext */ + obj_data =3D elf_add_data(e->out, obj_sec, NULL, obj_size); + if (!obj_data) + return -1; + + modname =3D find_modname(e); + if (!modname) + return -1; + + /* klp_object_ext.name */ + if (strcmp(modname, "vmlinux")) { + addend =3D elf_add_string(e->out, str_sec, modname); + if (addend =3D=3D -1) + return -1; + + if (!elf_create_reloc(e->out, obj_sec, + offsetof(struct klp_object_ext, name), + str_sym, addend, R_ABS64)) + return -1; + } + + /* klp_object_ext.funcs */ + if (!elf_create_reloc(e->out, obj_sec, offsetof(struct klp_object_ext, fu= ncs), + funcs_sym, 0, R_ABS64)) + return -1; + + for_each_sym(e->out, sym) { + unsigned long offset =3D nr_funcs * func_size; + unsigned long sympos; + void *func_data; + + if (!is_func_sym(sym) || sym->cold || !sym->clone || !sym->clone->change= d) + continue; + + /* allocate klp_func_ext */ + func_data =3D elf_add_data(e->out, funcs_sec, NULL, func_size); + if (!func_data) + return -1; + + /* klp_func_ext.old_name */ + addend =3D elf_add_string(e->out, str_sec, sym->clone->twin->name); + if (addend =3D=3D -1) + return -1; + + if (!elf_create_reloc(e->out, funcs_sec, + offset + offsetof(struct klp_func_ext, old_name), + str_sym, addend, R_ABS64)) + return -1; + + /* klp_func_ext.new_func */ + if (!elf_create_reloc(e->out, funcs_sec, + offset + offsetof(struct klp_func_ext, new_func), + sym, 0, R_ABS64)) + return -1; + + /* klp_func_ext.sympos */ + BUILD_BUG_ON(sizeof(sympos) !=3D sizeof_field(struct klp_func_ext, sympo= s)); + sympos =3D find_sympos(e->orig, sym->clone->twin); + if (sympos =3D=3D ULONG_MAX) + return -1; + memcpy(func_data + offsetof(struct klp_func_ext, sympos), &sympos, + sizeof_field(struct klp_func_ext, sympos)); + + nr_funcs++; + } + + /* klp_object_ext.nr_funcs */ + BUILD_BUG_ON(sizeof(nr_funcs) !=3D sizeof_field(struct klp_object_ext, nr= _funcs)); + memcpy(obj_data + offsetof(struct klp_object_ext, nr_funcs), &nr_funcs, + sizeof_field(struct klp_object_ext, nr_funcs)); + + /* + * Find callback pointers created by KLP_PRE_PATCH_CALLBACK() and + * friends, and add them to the klp object. + */ + + snprintf(sym_name, SYM_NAME_LEN, KLP_PRE_PATCH_PREFIX "%s", modname); + sym =3D find_symbol_by_name(e->out, sym_name); + if (sym) { + struct reloc *reloc; + + reloc =3D find_reloc_by_dest(e->out, sym->sec, sym->offset); + + if (!elf_create_reloc(e->out, obj_sec, + offsetof(struct klp_object_ext, callbacks) + + offsetof(struct klp_callbacks, pre_patch), + reloc->sym, reloc_addend(reloc), R_ABS64)) + return -1; + } + + snprintf(sym_name, SYM_NAME_LEN, KLP_POST_PATCH_PREFIX "%s", modname); + sym =3D find_symbol_by_name(e->out, sym_name); + if (sym) { + struct reloc *reloc; + + reloc =3D find_reloc_by_dest(e->out, sym->sec, sym->offset); + + if (!elf_create_reloc(e->out, obj_sec, + offsetof(struct klp_object_ext, callbacks) + + offsetof(struct klp_callbacks, post_patch), + reloc->sym, reloc_addend(reloc), R_ABS64)) + return -1; + } + + snprintf(sym_name, SYM_NAME_LEN, KLP_PRE_UNPATCH_PREFIX "%s", modname); + sym =3D find_symbol_by_name(e->out, sym_name); + if (sym) { + struct reloc *reloc; + + reloc =3D find_reloc_by_dest(e->out, sym->sec, sym->offset); + + if (!elf_create_reloc(e->out, obj_sec, + offsetof(struct klp_object_ext, callbacks) + + offsetof(struct klp_callbacks, pre_unpatch), + reloc->sym, reloc_addend(reloc), R_ABS64)) + return -1; + } + + snprintf(sym_name, SYM_NAME_LEN, KLP_POST_UNPATCH_PREFIX "%s", modname); + sym =3D find_symbol_by_name(e->out, sym_name); + if (sym) { + struct reloc *reloc; + + reloc =3D find_reloc_by_dest(e->out, sym->sec, sym->offset); + + if (!elf_create_reloc(e->out, obj_sec, + offsetof(struct klp_object_ext, callbacks) + + offsetof(struct klp_callbacks, post_unpatch), + reloc->sym, reloc_addend(reloc), R_ABS64)) + return -1; + } + + return 0; +} + +int cmd_klp_diff(int argc, const char **argv) +{ + struct elfs e =3D {0}; + + argc =3D parse_options(argc, argv, klp_diff_options, klp_diff_usage, 0); + if (argc !=3D 3) + usage_with_options(klp_diff_usage, klp_diff_options); + + objname =3D argv[0]; + + e.orig =3D elf_open_read(argv[0], O_RDONLY); + e.patched =3D elf_open_read(argv[1], O_RDONLY); + e.out =3D NULL; + + if (!e.orig || !e.patched) + return -1; + + if (read_exports()) + return -1; + + if (read_sym_checksums(e.orig)) + return -1; + + if (read_sym_checksums(e.patched)) + return -1; + + if (correlate_symbols(&e)) + return -1; + + if (mark_changed_functions(&e)) + return 0; + + if (validate_ffunction_fdata_sections(e.orig) || + validate_ffunction_fdata_sections(e.patched)) + return -1; + + e.out =3D elf_create_file(&e.orig->ehdr, argv[2]); + if (!e.out) + return -1; + + if (clone_included_functions(&e)) + return -1; + + if (clone_special_sections(&e)) + return -1; + + if (create_klp_sections(&e)) + return -1; + + if (elf_write(e.out)) + return -1; + + return elf_close(e.out); +} + diff --git a/tools/objtool/objtool.c b/tools/objtool/objtool.c index 5c8b974ad0f9..c8f611c1320d 100644 --- a/tools/objtool/objtool.c +++ b/tools/objtool/objtool.c @@ -16,8 +16,6 @@ #include #include =20 -bool help; - static struct objtool_file file; =20 struct objtool_file *objtool_open_read(const char *filename) @@ -71,6 +69,39 @@ int objtool_pv_add(struct objtool_file *f, int idx, stru= ct symbol *func) return 0; } =20 +char *top_level_dir(const char *file) +{ + ssize_t len, self_len, file_len; + char self[PATH_MAX], *str; + int i; + + len =3D readlink("/proc/self/exe", self, sizeof(self) - 1); + if (len <=3D 0) + return NULL; + self[len] =3D '\0'; + + for (i =3D 0; i < 3; i++) { + char *s =3D strrchr(self, '/'); + if (!s) + return NULL; + *s =3D '\0'; + } + + self_len =3D strlen(self); + file_len =3D strlen(file); + + str =3D malloc(self_len + file_len + 2); + if (!str) + return NULL; + + memcpy(str, self, self_len); + str[self_len] =3D '/'; + strcpy(str + self_len + 1, file); + + return str; +} + + int main(int argc, const char **argv) { static const char *UNUSED =3D "OBJTOOL_NOT_IMPLEMENTED"; @@ -79,5 +110,11 @@ int main(int argc, const char **argv) exec_cmd_init("objtool", UNUSED, UNUSED, UNUSED); pager_init(UNUSED); =20 + if (argc > 1 && !strcmp(argv[1], "klp")) { + argc--; + argv++; + return cmd_klp(argc, argv); + } + return objtool_run(argc, argv); } diff --git a/tools/objtool/sync-check.sh b/tools/objtool/sync-check.sh index 81d120d05442..e1d98fb03157 100755 --- a/tools/objtool/sync-check.sh +++ b/tools/objtool/sync-check.sh @@ -16,6 +16,7 @@ arch/x86/include/asm/orc_types.h arch/x86/include/asm/emulate_prefix.h arch/x86/lib/x86-opcode-map.txt arch/x86/tools/gen-insn-attr-x86.awk +include/linux/livepatch_external.h include/linux/static_call_types.h " =20 diff --git a/tools/objtool/weak.c b/tools/objtool/weak.c index d83f607733b0..d6562f292259 100644 --- a/tools/objtool/weak.c +++ b/tools/objtool/weak.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include =20 #define UNSUPPORTED(name) \ ({ \ @@ -24,3 +26,8 @@ int __weak orc_create(struct objtool_file *file) { UNSUPPORTED("ORC"); } + +int __weak cmd_klp(int argc, const char **argv) +{ + UNSUPPORTED("klp"); +} --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E919E29A317; Fri, 9 May 2025 20:18:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821903; cv=none; b=sP5vWeTOEH8kp81k+d2PEiFwxERzZPEyTriM9CEDUbL3XGy060d2Ji3gYfqmAw1uAeK2AdbnXlaQ88msolZiMjAIbgBoGGTDRtMseIggL0sOvkcsr+ydLI+Yf4900s9n/Fc6+GowUNxiab/y0fVbgY1v8vlSOwTSPLsD7FqPgHI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821903; c=relaxed/simple; bh=edNOy3Waot2Nt6C5oHuvoejyS0Y+zfnAykzKEZZAQMQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nFwMERfc6ogBYmM3VzSnGR/TqE+GCNrJYj0EYQZ+chqQ5A4yj6G+qcHIWcZYqesVqw1MP5DnYzhQbVocuo4R+e/Z9kz2ZXxukVYYMCSTMLfjLWrP+DavPGw2wUgkhMeC3qIqUAcUhBT54tuc2PbjxTPHifS171Z0Nywf1cT96a0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pyTW9Usz; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pyTW9Usz" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DA6F6C4CEEE; Fri, 9 May 2025 20:18:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821902; bh=edNOy3Waot2Nt6C5oHuvoejyS0Y+zfnAykzKEZZAQMQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pyTW9UsztF6uv9TSaHJ1XLeJVlzT5xop7HtVog8bBQKTML5Te9Nlmx7RvUDyeFyAt 45F07rrKK5cvMNVy/f7x3Ot9PM19XcyeXRmuVoMBKz/E/L/FodMlTnNKRAwiyjiYFg DuyZcr3Ao3gTKYxvtfkx9ggHwvHk7zx0+wpR9YZm51tZYknwW/0RNAE89TKiCB3LFg lzEKHwxzZawyjLnauHM8p5XuAp55eBDMDqSoL9L559vstF6ielLnBbNqmmU2iI/gRD aBjex7Qs18JtPZPGnVxfdyF/WLTM9zRKctXg1xGJqjUpq0py2w5gZeaF6lplgsdPrP yv0Va00m1ptxQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 53/62] objtool/klp: Add --debug option to show cloning decisions Date: Fri, 9 May 2025 13:17:17 -0700 Message-ID: <140f6ddac534bcbf3a7e3c096bf15588ada7ae3c.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a --debug option to klp diff which prints cloning decisions and an indented dependency tree for all cloned symbols and relocations. This helps visualize which symbols and relocations were included and why. Signed-off-by: Josh Poimboeuf --- tools/objtool/include/objtool/warn.h | 21 ++++++++ tools/objtool/klp-diff.c | 75 ++++++++++++++++++++++++++++ tools/objtool/objtool.c | 3 ++ 3 files changed, 99 insertions(+) diff --git a/tools/objtool/include/objtool/warn.h b/tools/objtool/include/o= bjtool/warn.h index 29173a1368d7..e88322d97573 100644 --- a/tools/objtool/include/objtool/warn.h +++ b/tools/objtool/include/objtool/warn.h @@ -102,6 +102,10 @@ static inline char *offstr(struct section *sec, unsign= ed long offset) #define ERROR_FUNC(sec, offset, format, ...) __WARN_FUNC(ERROR_STR, sec, o= ffset, format, ##__VA_ARGS__) #define ERROR_INSN(insn, format, ...) WARN_FUNC(insn->sec, insn->offset, f= ormat, ##__VA_ARGS__) =20 +extern bool debug; +extern int indent; + +static inline void unindent(int *unused) { indent--; } =20 #define __dbg(format, ...) \ fprintf(stderr, \ @@ -110,6 +114,23 @@ static inline char *offstr(struct section *sec, unsign= ed long offset) objname ? ": " : "", \ ##__VA_ARGS__) =20 +#define dbg(args...) \ +({ \ + if (unlikely(debug)) \ + __dbg(args); \ +}) + +#define __dbg_indent(format, ...) \ +({ \ + if (unlikely(debug)) \ + __dbg("%*s" format, indent * 8, "", ##__VA_ARGS__); \ +}) + +#define dbg_indent(args...) \ + int __attribute__((cleanup(unindent))) __dummy_##__COUNTER__; \ + __dbg_indent(args); \ + indent++ + #define dbg_checksum(func, insn, checksum) \ ({ \ if (unlikely(insn->sym && insn->sym->pfunc && \ diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index f17e4809ad4b..144525e74da3 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -36,6 +36,8 @@ static const char * const klp_diff_usage[] =3D { }; =20 static const struct option klp_diff_options[] =3D { + OPT_GROUP("Options:"), + OPT_BOOLEAN('d', "debug", &debug, "enable debug output"), OPT_END(), }; =20 @@ -46,6 +48,38 @@ static inline u32 str_hash(const char *str) return jhash(str, strlen(str), 0); } =20 +static char *escape_str(const char *orig) +{ + size_t len =3D 0; + const char *a; + char *b, *new; + + for (a =3D orig; *a; a++) { + switch (*a) { + case '\001': len +=3D 5; break; + case '\n': + case '\t': len +=3D 2; break; + default: len++; + } + } + + new =3D malloc(len + 1); + if (!new) + return NULL; + + for (a =3D orig, b =3D new; *a; a++) { + switch (*a) { + case '\001': memcpy(b, "", 5); b +=3D 5; break; + case '\n': *b++ =3D '\\'; *b++ =3D 'n'; break; + case '\t': *b++ =3D '\\'; *b++ =3D 't'; break; + default: *b++ =3D *a; + } + } + + *b =3D '\0'; + return new; +} + /* * Do a sanity check to make sure the changed object was built with * -ffunction-sections and -fdata-sections. @@ -516,6 +550,28 @@ static struct symbol *__clone_symbol(struct elf *elf, = struct symbol *patched_sym return out_sym; } =20 +static const char *sym_type(struct symbol *sym) +{ + switch (sym->type) { + case STT_NOTYPE: return "NOTYPE"; + case STT_OBJECT: return "OBJECT"; + case STT_FUNC: return "FUNC"; + case STT_SECTION: return "SECTION"; + case STT_FILE: return "FILE"; + default: return "UNKNOWN"; + } +} + +static const char *sym_bind(struct symbol *sym) +{ + switch (sym->bind) { + case STB_LOCAL : return "LOCAL"; + case STB_GLOBAL: return "GLOBAL"; + case STB_WEAK: return "WEAK"; + default: return "UNKNOWN"; + } +} + /* * Copy a symbol to the output object, optionally including its data and * relocations. @@ -528,6 +584,8 @@ static struct symbol *clone_symbol(struct elfs *e, stru= ct symbol *patched_sym, if (patched_sym->clone) return patched_sym->clone; =20 + dbg_indent("%s%s", patched_sym->name, data_too ? " [+DATA]" : ""); + /* Make sure the prefix gets cloned first */ if (is_func_sym(patched_sym) && data_too) { pfx =3D get_func_prefix(patched_sym); @@ -889,6 +947,8 @@ static int clone_reloc_klp(struct elfs *e, struct reloc= *patched_reloc, =20 klp_sym =3D find_symbol_by_name(e->out, sym_name); if (!klp_sym) { + __dbg_indent("%s", sym_name); + /* STB_WEAK: avoid modpost undefined symbol warnings */ klp_sym =3D elf_create_symbol(e->out, sym_name, NULL, STB_WEAK, patched_sym->type, 0, 0); @@ -937,6 +997,17 @@ static int clone_reloc_klp(struct elfs *e, struct relo= c *patched_reloc, return 0; } =20 +#define dbg_clone_reloc(sec, offset, patched_sym, addend, export, klp) \ + dbg_indent("%s+0x%lx: %s%s0x%lx [%s%s%s%s%s%s]", \ + sec->name, offset, patched_sym->name, \ + addend >=3D 0 ? "+" : "-", labs(addend), \ + sym_type(patched_sym), \ + patched_sym->type =3D=3D STT_SECTION ? "" : " ", \ + patched_sym->type =3D=3D STT_SECTION ? "" : sym_bind(patched_sym), \ + is_undef_sym(patched_sym) ? " UNDEF" : "", \ + export ? " EXPORTED" : "", \ + klp ? " KLP" : "") + /* Copy a reloc and its symbol to the output object */ static int clone_reloc(struct elfs *e, struct reloc *patched_reloc, struct section *sec, unsigned long offset) @@ -956,6 +1027,8 @@ static int clone_reloc(struct elfs *e, struct reloc *p= atched_reloc, =20 klp =3D klp_reloc_needed(patched_reloc); =20 + dbg_clone_reloc(sec, offset, patched_sym, addend, export, klp); + if (klp) { if (clone_reloc_klp(e, patched_reloc, sec, offset, export)) return -1; @@ -987,6 +1060,8 @@ static int clone_reloc(struct elfs *e, struct reloc *p= atched_reloc, if (is_string_sec(patched_sym->sec)) { const char *str =3D patched_sym->sec->data->d_buf + addend; =20 + __dbg_indent("\"%s\"", escape_str(str)); + addend =3D elf_add_string(e->out, out_sym->sec, str); if (addend =3D=3D -1) return -1; diff --git a/tools/objtool/objtool.c b/tools/objtool/objtool.c index c8f611c1320d..3c26ed561c7e 100644 --- a/tools/objtool/objtool.c +++ b/tools/objtool/objtool.c @@ -16,6 +16,9 @@ #include #include =20 +bool debug; +int indent; + static struct objtool_file file; =20 struct objtool_file *objtool_open_read(const char *filename) --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4080829A9CE; Fri, 9 May 2025 20:18:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821903; cv=none; b=KWSR4l77IwkyQZ7y6GD6bZ+cdcczOiOtVZEopbQoRGt2ur8XCa0UcaZ7dzSbd85GeyE321BvunD9x0ZShGdoz+C/sp2ikP6XxMR69jtObZcuMEi+CDd/z6RcEhwflWBkbM2pkugi6bNS65EcEttOwA3CPJg1SCwau4z7BnM7Nfc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821903; c=relaxed/simple; bh=1U4IJV0uW78vO8Khu5J+rxPyIScDURWKxt92jsNcq3M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QkUKjy57MvrBv7Jjg9x/9SIewHwP0+RuvcoQqnNY6feRj03DIW52zvNxVtJjrU3JjdwXdt4OQcCZ8BVJNsoWF039f2smJybBicn/J43dI2/tadU3zrNiKUnydCS3ETeg/lZBP/CDtHRuGnv1REiaSneBhkowy+aohoQIyuiW6Ac= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=iYezD6EM; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="iYezD6EM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8E94EC4CEEF; Fri, 9 May 2025 20:18:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821903; bh=1U4IJV0uW78vO8Khu5J+rxPyIScDURWKxt92jsNcq3M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iYezD6EM7c019vsHC5knMU2p7mnxHzSM/OWTD2tbcCZCfXEOSBDhMRaUUUf0A8L+B 2LF1IJozDXbuTFW7ot+giaFnWtblD0AAkjeage5IV0BSf/yhQ4cGK/2Nz3Okflu0kG vHsQdO6jBR53RdQfWXPs9uaautUwlrFqB+tg9WgvjIU8i6DN26nqQQ+YBnX4HRNyQF dsWtPAUE3CfzqY/j8kq0QsoMd8mXda/cdMJTkFOUAI1Wsf6iRmm2zkCyEWwTvkOa04 E5wRkzPciH4aNQua8MtDer9VnBgz7yZLEKUR5IXnofkQoCSBsV34aaHZDLF1JPuoUD a5BFQoKMJa2xQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 54/62] objtool/klp: Add post-link subcommand to finalize livepatch modules Date: Fri, 9 May 2025 13:17:18 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Livepatch needs some ELF magic which linkers don't like: - Two relocation sections (.rela*, .klp.rela*) for the same text section. - Use of SHN_LIVEPATCH to mark livepatch symbols. Unfortunately linkers tend to mangle such things. To work around that, klp diff generates a linker-compliant intermediate binary which encodes the relevant KLP section/reloc/symbol metadata. After module linking, the .ko then needs to be converted to an actual livepatch module. Introduce a new klp post-link subcommand to do so. Signed-off-by: Josh Poimboeuf --- tools/objtool/Build | 2 +- tools/objtool/builtin-klp.c | 1 + tools/objtool/include/objtool/klp.h | 4 + tools/objtool/klp-post-link.c | 165 ++++++++++++++++++++++++++++ 4 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 tools/objtool/klp-post-link.c diff --git a/tools/objtool/Build b/tools/objtool/Build index 0b01657671d7..8cd71b9a5eef 100644 --- a/tools/objtool/Build +++ b/tools/objtool/Build @@ -9,7 +9,7 @@ objtool-y +=3D elf.o objtool-y +=3D objtool.o =20 objtool-$(BUILD_ORC) +=3D orc_gen.o orc_dump.o -objtool-$(BUILD_KLP) +=3D builtin-klp.o klp-diff.o +objtool-$(BUILD_KLP) +=3D builtin-klp.o klp-diff.o klp-post-link.o =20 objtool-y +=3D libstring.o objtool-y +=3D libctype.o diff --git a/tools/objtool/builtin-klp.c b/tools/objtool/builtin-klp.c index 9b13dd1182af..56d5a5b92f72 100644 --- a/tools/objtool/builtin-klp.c +++ b/tools/objtool/builtin-klp.c @@ -14,6 +14,7 @@ struct subcmd { =20 static struct subcmd subcmds[] =3D { { "diff", "Generate binary diff of two object files", cmd_klp_diff, }, + { "post-link", "Finalize klp symbols/relocs after module linking", cmd_k= lp_post_link, }, }; =20 static void cmd_klp_usage(void) diff --git a/tools/objtool/include/objtool/klp.h b/tools/objtool/include/ob= jtool/klp.h index 07928fac059b..ad830a7ce55b 100644 --- a/tools/objtool/include/objtool/klp.h +++ b/tools/objtool/include/objtool/klp.h @@ -2,6 +2,9 @@ #ifndef _OBJTOOL_KLP_H #define _OBJTOOL_KLP_H =20 +#define SHF_RELA_LIVEPATCH 0x00100000 +#define SHN_LIVEPATCH 0xff20 + /* * __klp_objects and __klp_funcs are created by klp diff and used by the p= atch * module init code to build the klp_patch, klp_object and klp_func structs @@ -27,5 +30,6 @@ struct klp_reloc { }; =20 int cmd_klp_diff(int argc, const char **argv); +int cmd_klp_post_link(int argc, const char **argv); =20 #endif /* _OBJTOOL_KLP_H */ diff --git a/tools/objtool/klp-post-link.c b/tools/objtool/klp-post-link.c new file mode 100644 index 000000000000..05be6251e35f --- /dev/null +++ b/tools/objtool/klp-post-link.c @@ -0,0 +1,165 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Read the intermediate KLP reloc/symbol representations created by klp d= iff + * and convert them to the proper format required by livepatch. This need= s to + * run last to avoid linker wreckage. Linkers don't tend to handle the "t= wo + * rela sections for a single base section" case very well, nor do they li= ke + * SHN_LIVEPATCH. + * + * This is the final tool in the livepatch module generation pipeline: + * + * kernel builds -> objtool klp diff -> module link -> objtool klp post-= link + */ + +#include +#include +#include +#include +#include +#include + +static int fix_klp_relocs(struct elf *elf) +{ + struct section *symtab, *klp_relocs; + + klp_relocs =3D find_section_by_name(elf, KLP_RELOCS_SEC); + if (!klp_relocs) + return 0; + + symtab =3D find_section_by_name(elf, ".symtab"); + if (!symtab) { + ERROR("missing .symtab"); + return -1; + } + + for (int i =3D 0; i < sec_size(klp_relocs) / sizeof(struct klp_reloc); i+= +) { + struct klp_reloc *klp_reloc; + unsigned long klp_reloc_off; + struct section *sec, *tmp, *klp_rsec; + unsigned long offset; + struct reloc *reloc; + char sym_modname[64]; + char rsec_name[SEC_NAME_LEN]; + u64 addend; + struct symbol *sym, *klp_sym; + + klp_reloc_off =3D i * sizeof(*klp_reloc); + klp_reloc =3D klp_relocs->data->d_buf + klp_reloc_off; + + /* + * Read __klp_relocs[i]: + */ + + /* klp_reloc.sec_offset */ + reloc =3D find_reloc_by_dest(elf, klp_relocs, + klp_reloc_off + offsetof(struct klp_reloc, offset)); + if (!reloc) { + ERROR("malformed " KLP_RELOCS_SEC " section"); + return -1; + } + + sec =3D reloc->sym->sec; + offset =3D reloc_addend(reloc); + + /* klp_reloc.sym */ + reloc =3D find_reloc_by_dest(elf, klp_relocs, + klp_reloc_off + offsetof(struct klp_reloc, sym)); + if (!reloc) { + ERROR("malformed " KLP_RELOCS_SEC " section"); + return -1; + } + + klp_sym =3D reloc->sym; + addend =3D reloc_addend(reloc); + + /* symbol format: .klp.sym.modname.sym_name,sympos */ + if (sscanf(klp_sym->name + strlen(KLP_SYM_PREFIX), "%55[^.]", sym_modnam= e) !=3D 1) + ERROR("can't find modname in klp symbol '%s'", klp_sym->name); + + /* + * Create the KLP rela: + */ + + /* section format: .klp.rela.sec_objname.section_name */ + snprintf(rsec_name, SEC_NAME_LEN, KLP_RELOC_SEC_PREFIX "%s.%s", + sym_modname, sec->name); + + klp_rsec =3D find_section_by_name(elf, rsec_name); + if (!klp_rsec) { + klp_rsec =3D elf_create_section(elf, rsec_name, 0, + elf_rela_size(elf), + SHT_RELA, elf_addr_size(elf), + SHF_ALLOC | SHF_INFO_LINK | SHF_RELA_LIVEPATCH); + if (!klp_rsec) + return -1; + + klp_rsec->sh.sh_link =3D symtab->idx; + klp_rsec->sh.sh_info =3D sec->idx; + klp_rsec->base =3D sec; + } + + tmp =3D sec->rsec; + sec->rsec =3D klp_rsec; + if (!elf_create_reloc(elf, sec, offset, klp_sym, addend, klp_reloc->type= )) + return -1; + sec->rsec =3D tmp; + + /* + * Fix up the corresponding KLP symbol: + */ + + klp_sym->sym.st_shndx =3D SHN_LIVEPATCH; + if (!gelf_update_sym(symtab->data, klp_sym->idx, &klp_sym->sym)) { + ERROR_ELF("gelf_update_sym"); + return -1; + } + + /* + * Disable the original non-KLP reloc by converting it to R_*_NONE: + */ + + reloc =3D find_reloc_by_dest(elf, sec, offset); + sym =3D reloc->sym; + sym->sym.st_shndx =3D SHN_LIVEPATCH; + set_reloc_type(elf, reloc, 0); + if (!gelf_update_sym(symtab->data, sym->idx, &sym->sym)) { + ERROR_ELF("gelf_update_sym"); + return -1; + } + } + + return 0; +} + +/* + * This runs on the livepatch module after all other linking has been done= . It + * converts the intermediate __klp_relocs section into proper KLP relocs t= o be + * processed by livepatch. This needs to run last to avoid linker wreckag= e. + * Linkers don't tend to handle the "two rela sections for a single base + * section" case very well, nor do they appreciate SHN_LIVEPATCH. + */ +int cmd_klp_post_link(int argc, const char **argv) +{ + struct elf *elf; + + argc--; + argv++; + + if (argc !=3D 1) { + fprintf(stderr, "%d\n", argc); + fprintf(stderr, "usage: objtool link \n"); + return -1; + } + + elf =3D elf_open_read(argv[0], O_RDWR); + if (!elf) + return -1; + + if (fix_klp_relocs(elf)) + return -1; + + if (elf_write(elf)) + return -1; + + return elf_close(elf); +} --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E6E8129A9E6; Fri, 9 May 2025 20:18:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821904; cv=none; b=rOC8T0wGBiytRBfgIjjpmj4uA1aCSrCy6uJHQMAn999N1CVQk/2fWFzb6KJpOQvs1fYZpWvDxz1m6Lw/tZbjTxbV/jfBYKuKpVdiTKByI5AEDYyapfssz5V4asawkm3oK744NgU3cTDRm88aKqbjxXIk2FUhy23uGTYwOL6qVg4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821904; c=relaxed/simple; bh=q9hs8SL1tf9ITX/Y15AxbLLDH2L8NCjoM7DGgCW/bxI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fPUUvp2IyZ11U4kE0OqWov3ovz3cCyQRel0YHmeBx0+3JBRtCVSJQyQHjkLMITVdOxb9Z89XrFvq3nt4QZG0OkjhbPj+Bm6IKw0Mz782r94eOYIGW1x+hZVMZ4m5y/CzB6qG1uJTWUK7lGcTT9uGSxhOFQwiI0SOntSUD8i9Y6k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jFsUZOVR; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="jFsUZOVR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4542AC4CEEE; Fri, 9 May 2025 20:18:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821903; bh=q9hs8SL1tf9ITX/Y15AxbLLDH2L8NCjoM7DGgCW/bxI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jFsUZOVROaHNjJdmAoytDuzRj0fjRsDLZUgDLchBhC3DhiNjRihlYHzI7Mp7io+2b XOai4pJ/7zXZ6543zaq7Mxj/s5mdnWlH9Sb56TSApkrEx/raBpInSx3qSj09f2K4il EubTH+ORPw5DvyOBjvB5CfulHExHkJKLF7YNLIfYQGmSm0GgIJldtGgyN1LLP9qNNw mNBp0wU9oI8aHRY8LfHmWlU21cMUPFrVOMDBbTuJfdEDUtQHvy94HVPdgwNp5bA6jo e9jPQTG6/4vNC23qL/ilZBrlfTNHbNRX3Gr7L04qHE1PTD28uh1ZOdgh9WJcUREOOQ 99O6MOJjTl2+A== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 55/62] objtool: Disallow duplicate prefix symbols Date: Fri, 9 May 2025 13:17:19 -0700 Message-ID: <23e6ec37b579514e13ca33f08c6f1eaba9958d6d.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for adding objtool 'check' support for analyzing livepatch modules, error out if a duplicate prefix symbol is attempted. Signed-off-by: Josh Poimboeuf --- tools/objtool/check.c | 12 +++++++++++- tools/objtool/elf.c | 9 +++++++++ tools/objtool/include/objtool/elf.h | 3 +++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 30a5eb725931..bc9bc37efa55 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -4271,6 +4271,7 @@ static int add_prefix_symbol(struct objtool_file *fil= e, struct symbol *func) for (prev =3D prev_insn_same_sec(file, insn); prev; prev =3D prev_insn_same_sec(file, prev)) { + struct symbol *sym_pfx; u64 offset; =20 if (prev->type !=3D INSN_NOP) @@ -4284,7 +4285,12 @@ static int add_prefix_symbol(struct objtool_file *fi= le, struct symbol *func) if (offset < opts.prefix) continue; =20 - elf_create_prefix_symbol(file->elf, func, opts.prefix); + sym_pfx =3D elf_create_prefix_symbol(file->elf, func, opts.prefix); + if (!sym_pfx) { + WARN("duplicate prefix symbol for %s\n", func->name); + return -1; + } + break; } =20 @@ -4320,6 +4326,10 @@ static int add_prefix_symbols(struct objtool_file *f= ile) if (!is_func_sym(func)) continue; =20 + /* + * Ignore this error on purpose, there are valid + * reasons for this to fail. + */ add_prefix_symbol(file, func); } } diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 645f7ac12869..de1d8554d979 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -946,11 +946,20 @@ elf_create_prefix_symbol(struct elf *elf, struct symb= ol *orig, size_t size) size_t namelen =3D strlen(orig->name) + sizeof("__pfx_"); char name[SYM_NAME_LEN]; unsigned long offset; + struct symbol *sym; =20 snprintf(name, namelen, "__pfx_%s", orig->name); =20 + sym =3D orig; offset =3D orig->sym.st_value - size; =20 + sec_for_each_sym_continue_reverse(orig->sec, sym) { + if (sym->offset < offset) + break; + if (sym->offset =3D=3D offset && !strcmp(sym->name, name)) + return NULL; + } + return elf_create_symbol(elf, name, orig->sec, GELF_ST_BIND(orig->sym.st_info), GELF_ST_TYPE(orig->sym.st_info), diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index f62ac8081f27..1bf9c0a1112d 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -443,6 +443,9 @@ static inline void set_sym_next_reloc(struct reloc *rel= oc, struct reloc *next) #define sec_for_each_sym(sec, sym) \ list_for_each_entry(sym, &sec->symbol_list, list) =20 +#define sec_for_each_sym_continue_reverse(sec, sym) \ + list_for_each_entry_continue_reverse(sym, &sec->symbol_list, list) + #define sec_prev_sym(sym) \ sym->sec && sym->list.prev !=3D &sym->sec->symbol_list ? \ list_prev_entry(sym, list) : NULL --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 241BC29AAEB; Fri, 9 May 2025 20:18:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821905; cv=none; b=AqFaYdLWxG52zJixBiNOYhyv24urBwAUdvfv5/wro9IOw2W9jiiEMy7i8WiUdHUH1sC1snE7nn+RD2KV8m07HH+AVtCigekJUsV8vogNoyF7k2djDcluryX3lEL49zrxVErKZjn5Zwer2ccZPmhsQu4A02dAhlxhhtEDtncaZCw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821905; c=relaxed/simple; bh=iNTRpBq9KLho7r5MiQ2IzJKM2/5WdHdwn8puwfQIvvA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Bo0+azVvShsefftoDUd6MddjELZ2nnkiuwRLAdWVgqzeBRpGZuh1Cl2Vb8JN8+bchpr9eUrXmr8hxaAXNeTsoF0KVyf0884PETb178XUkQGfshBY5BN4zeB9Nz7xxv1e7R7lM7RpC1e2BZ1zHAW++N148vb4Rn73oebutDxuZLM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=aZIBN9zH; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="aZIBN9zH" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F3448C4CEE9; Fri, 9 May 2025 20:18:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821904; bh=iNTRpBq9KLho7r5MiQ2IzJKM2/5WdHdwn8puwfQIvvA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aZIBN9zHCJe+uAanE2vUybr8PO2kYEt3PY82bWKVr8+Q5ezTxInme/a8NXhHp/yY8 8hRjfmorYsAgdLSwdsY3VZBURwmNu0uP01WwCeZFLhLZVap0m/L3wDEv1EXuQzgoQl vTvGRv+TSMmrPOC4M3O+Gyp6i+pbRct8mPjiSaL5V/8Z16j7mVmQh0grzFbpO/fEF7 QaB0R9wyKDO9iZGbYYNBrEFDjmw26BhuCQjfR59M11/oYXZnsq3cAa63t6mmjzqR2Z 2PdT/Rpw/6t0h1UXczu5m4gOPVqa0OhzzZOlHXscJAuP2Im7+FwXaVuufsQMkAO1TK PA6GASwBMi6ow== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 56/62] objtool: Add base objtool support for livepatch modules Date: Fri, 9 May 2025 13:17:20 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation for klp-build, enable "classic" objtool to work on livepatch modules: - Avoid duplicate symbol/section warnings for prefix symbols and the .static_call_sites and __mcount_loc sections which may have already been extracted by klp diff. - Add __klp_funcs to the IBT function pointer section whitelist. - Prevent KLP symbols from getting incorrectly classified as cold subfunctions. Signed-off-by: Josh Poimboeuf --- tools/objtool/check.c | 44 +++++++++++++++++++++---- tools/objtool/elf.c | 4 ++- tools/objtool/include/objtool/elf.h | 1 + tools/objtool/include/objtool/objtool.h | 2 +- 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index bc9bc37efa55..5bd1b8d000bd 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -3,6 +3,7 @@ * Copyright (C) 2015-2017 Josh Poimboeuf */ =20 +#define _GNU_SOURCE /* memmem() */ #include #include #include @@ -627,6 +628,20 @@ static int init_pv_ops(struct objtool_file *file) return 0; } =20 +static bool is_livepatch_module(struct objtool_file *file) +{ + struct section *sec; + + if (!opts.module) + return false; + + sec =3D find_section_by_name(file->elf, ".modinfo"); + if (!sec) + return false; + + return memmem(sec->data->d_buf, sec_size(sec), "\0livepatch=3DY", 12); +} + static int create_static_call_sections(struct objtool_file *file) { struct static_call_site *site; @@ -638,7 +653,12 @@ static int create_static_call_sections(struct objtool_= file *file) =20 sec =3D find_section_by_name(file->elf, ".static_call_sites"); if (sec) { - if (!opts.dryrun) + /* + * Livepatch modules may have already extracted the static call + * site entries to take advantage of vmlinux static call + * privileges. + */ + if (!!opts.dryrun || !file->klp) WARN("file already has .static_call_sites section, skipping"); =20 return 0; @@ -684,7 +704,7 @@ static int create_static_call_sections(struct objtool_f= ile *file) =20 key_sym =3D find_symbol_by_name(file->elf, tmp); if (!key_sym) { - if (!opts.module) { + if (!opts.module || file->klp) { ERROR("static_call: can't find static_call_key symbol: %s", tmp); return -1; } @@ -911,7 +931,11 @@ static int create_mcount_loc_sections(struct objtool_f= ile *file) =20 sec =3D find_section_by_name(file->elf, "__mcount_loc"); if (sec) { - if (!opts.dryrun) + /* + * Livepatch modules have already extracted their __mcount_loc + * entries to cover the !CONFIG_FTRACE_MCOUNT_USE_OBJTOOL case. + */ + if (!opts.dryrun && !file->klp) WARN("file already has __mcount_loc section, skipping"); =20 return 0; @@ -2612,6 +2636,8 @@ static int decode_sections(struct objtool_file *file) { int ret; =20 + file->klp =3D is_livepatch_module(file); + mark_rodata(file); =20 ret =3D init_pv_ops(file); @@ -4285,8 +4311,13 @@ static int add_prefix_symbol(struct objtool_file *fi= le, struct symbol *func) if (offset < opts.prefix) continue; =20 + /* + * Ignore attempts to make duplicate symbols in livepatch + * modules. They've already extracted the prefix symbols + * except for the newly compiled init.c. + */ sym_pfx =3D elf_create_prefix_symbol(file->elf, func, opts.prefix); - if (!sym_pfx) { + if (!sym_pfx && !file->klp) { WARN("duplicate prefix symbol for %s\n", func->name); return -1; } @@ -4621,6 +4652,7 @@ static int validate_ibt(struct objtool_file *file) !strncmp(sec->name, ".debug", 6) || !strcmp(sec->name, ".altinstructions") || !strcmp(sec->name, ".ibt_endbr_seal") || + !strcmp(sec->name, ".kcfi_traps") || !strcmp(sec->name, ".orc_unwind_ip") || !strcmp(sec->name, ".retpoline_sites") || !strcmp(sec->name, ".smp_locks") || @@ -4630,12 +4662,12 @@ static int validate_ibt(struct objtool_file *file) !strcmp(sec->name, "__bug_table") || !strcmp(sec->name, "__ex_table") || !strcmp(sec->name, "__jump_table") || + !strcmp(sec->name, "__klp_funcs") || !strcmp(sec->name, "__mcount_loc") || - !strcmp(sec->name, ".kcfi_traps") || !strcmp(sec->name, ".llvm.call-graph-profile") || !strcmp(sec->name, ".llvm_bb_addr_map") || !strcmp(sec->name, "__tracepoints") || - strstr(sec->name, "__patchable_function_entries")) + !strcmp(sec->name, "__patchable_function_entries")) continue; =20 for_each_reloc(sec->rsec, reloc) diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index de1d8554d979..ae1c852ff8d8 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -496,8 +496,10 @@ static int elf_add_symbol(struct elf *elf, struct symb= ol *sym) (strstarts(sym->name, "__pfx") || strstarts(sym->name, "__cfi_"))) sym->prefix =3D 1; =20 + if (strstarts(sym->name, ".klp.sym")) + sym->klp =3D 1; =20 - if (is_func_sym(sym) && strstr(sym->name, ".cold")) + if (!sym->klp && is_func_sym(sym) && strstr(sym->name, ".cold")) sym->cold =3D 1; sym->pfunc =3D sym->cfunc =3D sym; =20 diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/ob= jtool/elf.h index 1bf9c0a1112d..adfe508f96f5 100644 --- a/tools/objtool/include/objtool/elf.h +++ b/tools/objtool/include/objtool/elf.h @@ -84,6 +84,7 @@ struct symbol { u8 debug_checksum : 1; u8 changed : 1; u8 included : 1; + u8 klp : 1; struct list_head pv_target; struct reloc *relocs; struct section *group_sec; diff --git a/tools/objtool/include/objtool/objtool.h b/tools/objtool/includ= e/objtool/objtool.h index 37e9fe4492d6..731965a742e9 100644 --- a/tools/objtool/include/objtool/objtool.h +++ b/tools/objtool/include/objtool/objtool.h @@ -30,7 +30,7 @@ struct objtool_file { struct list_head mcount_loc_list; struct list_head endbr_list; struct list_head call_list; - bool ignore_unreachables, hints, rodata; + bool ignore_unreachables, hints, rodata, klp; =20 unsigned int nr_endbr; unsigned int nr_endbr_int; --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 589E729AAF4; Fri, 9 May 2025 20:18:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821905; cv=none; b=iyXyZBNWsJV/Fe3NKYHI3aCwiw3VbaI+5dy3dObnV7KHgVAvbR6n9KpoCUUHrdXf73thJ3hgU0AH42fWGc039k17ey+XRjdpTYuo2jSbEWykBNVW3P1upIzPMPoCbtRnmxQP7oqlPySW5btJF1ans4MH2U/uA3yvkkwaRKp+pts= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821905; c=relaxed/simple; bh=J92Bg9zXyMxGmwqrjnS9kK9B64dzel95HCv0iSVLp0Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=H67xDazo+MFVgu1EPHvPGFivCXAWdnsk2Cjfc/sffdpMulLi0dTn8RK+ks9Zc7vChrxa3lBF2mZD339AQppLLjIeBLJVWn+FtoBsqI7knit9rz+nh5wW/33z/YuGtUOOabQQJCo0dVw6rEy6aZo2MgGosWNPHI28npveVJztgnQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kfmVj/sw; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="kfmVj/sw" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A8A3FC4CEF0; Fri, 9 May 2025 20:18:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821905; bh=J92Bg9zXyMxGmwqrjnS9kK9B64dzel95HCv0iSVLp0Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kfmVj/swclUa0eXpVXNHBVpDrISySXGVn4ArNqUzazp9vgYAnOajrfrnE6uLI+Zc3 GyMLFn3Yqp8TQLm0CM291tJSuwwACkvuVQSVaW2RgKv99W67ef5JYNlyXLKE3EieeF oKTmSgT6O1M6ms9Wv65Pw2flIRBnPnSXJZoUTps8vPyt52OMbXvaXD0o1/ZCsabsnd 7dK9Orj2aJ9ubbQuVRQv50I6hfGSt9zEqLgonvM3N/wsolZHL4r3Amq4I8dmwAbA95 0/S1hMpFMEoJhoMJzxNqw0CfoTIecjEeGFPCF6BQDZtsWxQytCviBC809dKmpUpPS5 KVhALdERi9D7w== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 57/62] livepatch/klp-build: Introduce fix-patch-lines script to avoid __LINE__ diff noise Date: Fri, 9 May 2025 13:17:21 -0700 Message-ID: <9de1929a526c40454bb0e839085eaa3ce5bde5ed.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The __LINE__ macro creates challenges for binary diffing. When a .patch file adds or removes lines, it shifts the line numbers for all code below it. This can cause the code generation of functions using __LINE__ to change due to the line number constant being embedded in a MOV instruction, despite there being no semantic difference. Avoid such false positives by adding a fix-patch-lines script which can be used to insert a #line directive in each patch hunk affecting the line numbering. This script will be used by klp-build, which will be introduced in a subsequent patch. Signed-off-by: Josh Poimboeuf --- MAINTAINERS | 1 + scripts/livepatch/fix-patch-lines | 79 +++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100755 scripts/livepatch/fix-patch-lines diff --git a/MAINTAINERS b/MAINTAINERS index 06f4a10c7209..20f8be69c558 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13792,6 +13792,7 @@ F: include/linux/livepatch*.h F: kernel/livepatch/ F: kernel/module/livepatch.c F: samples/livepatch/ +F: scripts/livepatch/ F: tools/testing/selftests/livepatch/ =20 LLC (802.2) diff --git a/scripts/livepatch/fix-patch-lines b/scripts/livepatch/fix-patc= h-lines new file mode 100755 index 000000000000..73c5e3dea46e --- /dev/null +++ b/scripts/livepatch/fix-patch-lines @@ -0,0 +1,79 @@ +#!/usr/bin/awk -f +# SPDX-License-Identifier: GPL-2.0 +# +# Use #line directives to preserve original __LINE__ numbers across patche= s to +# avoid unwanted compilation changes. + +BEGIN { + in_hunk =3D 0 + skip =3D 0 +} + +/^--- / { + skip =3D $2 !~ /\.(c|h)$/ + print + next +} + +/^@@/ { + if (skip) { + print + next + } + + in_hunk =3D 1 + + # for @@ -1,3 +1,4 @@: + # 1: line number in old file + # 3: how many lines the hunk covers in old file + # 1: line number in new file + # 4: how many lines the hunk covers in new file + + match($0, /^@@ -([0-9]+)(,([0-9]+))? \+([0-9]+)(,([0-9]+))? @@/, m) + + # Set 'cur' to the old file's line number at the start of the hunk. It + # gets incremented for every context line and every line removal, so + # that it always represents the old file's current line number. + cur =3D m[1] + + # last =3D last line number of current hunk + last =3D cur + (m[3] ? m[3] : 1) - 1 + + need_line_directive =3D 0 + + print + next +} + +{ + if (skip || !in_hunk || $0 ~ /^\\ No newline at end of file/) { + print + next + } + + # change line + if ($0 ~ /^[+-]/) { + # inject #line after this group of changes + need_line_directive =3D 1 + + if ($0 ~ /^-/) + cur++ + + print + next + } + + # If this is the first context line after a group of changes, inject + # the #line directive to force the compiler to correct the line + # numbering to match the original file. + if (need_line_directive) { + print "+#line " cur + need_line_directive =3D 0 + } + + if (cur =3D=3D last) + in_hunk =3D 0 + + cur++ + print +} --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 07E4429AB0D; Fri, 9 May 2025 20:18:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821906; cv=none; b=DIrzkQ2qbxcT3eJKuoKz/AXL+CX1Nys+HgBrSfb/reJXVYpM8CAkkhiVuI0amtPJBnxbGx9WhOjw/DwLzEyp+ONWOJFKG89845nIPmqRdKxm6Ax0XNXjASTB6jGqN7x7YZvJAWvjNn4Mib31paAUDKX8LgWQjXsFRw0xzZCSELw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821906; c=relaxed/simple; bh=sUazod9fDHv6Y0sMdgofaAG7+zcMTxL59nufwr9DdXI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qCyzs7YoiILcXbQIlimlkbfXP5kb8rjxxmRwVhpcZIxeTcXOelB14XzaCsQEgEWrcXbUNML4pE50D0jOhkK8mCASiN7Fhq/Xkjrt4I1rO7vCDZqCW2ToLJ9ekfFW44DQ8yXRtnr25cdTAv/CIKvCiXjYX3/54YAw5R/niRTgGf0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=q8Eb7YQJ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="q8Eb7YQJ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5E170C4CEEE; Fri, 9 May 2025 20:18:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821905; bh=sUazod9fDHv6Y0sMdgofaAG7+zcMTxL59nufwr9DdXI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=q8Eb7YQJAThvBkuGKqgfPanDm3ob3CMsGx4JM1AetYfv0DYx345u4/f4DXW9LsnB5 qLfw3EezTGP/cEotZad9T0lLsamujT/OZ53mKU8PWAztmbHTNpPQXScnN0eA1Ic/J9 TuU7zS13fgSYGO45BgdglnV+rHCUaAzIw10h2j6Kdo+hExs/vvqfPoFUL/5qzTNzC3 ZYH0OhzDnckhRe0iT+ztTEq4Rm5ZmsSswzB6C4keKdC3G23B3YZBNgcHObZUS4rHIn TOeNaGV+cnTD2rSodXE/62AxaeFO0Z33oHIlY7CrjFqmEMOJPFoD5hXp9Gyt/g7Dec IuAgN7i1qVO3w== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 58/62] livepatch/klp-build: Add stub init code for livepatch modules Date: Fri, 9 May 2025 13:17:22 -0700 Message-ID: <97663fd9f60494bf4d027114fab13540102b26fe.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a module initialization stub which can be linked with binary diff objects to produce a livepatch module. Signed-off-by: Josh Poimboeuf --- scripts/livepatch/init.c | 108 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 scripts/livepatch/init.c diff --git a/scripts/livepatch/init.c b/scripts/livepatch/init.c new file mode 100644 index 000000000000..2274d8f5a482 --- /dev/null +++ b/scripts/livepatch/init.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Init code for a livepatch kernel module + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include + +extern struct klp_object_ext __start_klp_objects[]; +extern struct klp_object_ext __stop_klp_objects[]; + +static struct klp_patch *patch; + +static int __init livepatch_mod_init(void) +{ + struct klp_object *objs; + unsigned int nr_objs; + int ret; + + nr_objs =3D __stop_klp_objects - __start_klp_objects; + + if (!nr_objs) { + pr_err("nothing to patch!\n"); + ret =3D -EINVAL; + goto err; + } + + patch =3D kzalloc(sizeof(*patch), GFP_KERNEL); + if (!patch) { + ret =3D -ENOMEM; + goto err; + } + + objs =3D kzalloc(sizeof(struct klp_object) * (nr_objs + 1), GFP_KERNEL); + if (!objs) { + ret =3D -ENOMEM; + goto err_free_patch; + } + + for (int i =3D 0; i < nr_objs; i++) { + struct klp_object_ext *obj_ext =3D __start_klp_objects + i; + struct klp_func_ext *funcs_ext =3D obj_ext->funcs; + unsigned int nr_funcs =3D obj_ext->nr_funcs; + struct klp_func *funcs =3D objs[i].funcs; + struct klp_object *obj =3D objs + i; + + funcs =3D kzalloc(sizeof(struct klp_func) * (nr_funcs + 1), GFP_KERNEL); + if (!funcs) { + ret =3D -ENOMEM; + for (int j =3D 0; j < i; j++) + kfree(objs[i].funcs); + goto err_free_objs; + } + + for (int j =3D 0; j < nr_funcs; j++) { + funcs[j].old_name =3D funcs_ext[j].old_name; + funcs[j].new_func =3D funcs_ext[j].new_func; + funcs[j].old_sympos =3D funcs_ext[j].sympos; + } + + obj->name =3D obj_ext->name; + obj->funcs =3D funcs; + + memcpy(&obj->callbacks, &obj_ext->callbacks, sizeof(struct klp_callbacks= )); + } + + patch->mod =3D THIS_MODULE; + patch->objs =3D objs; + + /* TODO patch->states */ + +#ifdef KLP_NO_REPLACE + patch->replace =3D false; +#else + patch->replace =3D true; +#endif + + return klp_enable_patch(patch); + +err_free_objs: + kfree(objs); +err_free_patch: + kfree(patch); +err: + return ret; +} + +static void __exit livepatch_mod_exit(void) +{ + unsigned int nr_objs; + + nr_objs =3D __stop_klp_objects - __start_klp_objects; + + for (int i =3D 0; i < nr_objs; i++) + kfree(patch->objs[i].funcs); + + kfree(patch->objs); + kfree(patch); +} + +module_init(livepatch_mod_init); +module_exit(livepatch_mod_exit); +MODULE_LICENSE("GPL"); +MODULE_INFO(livepatch, "Y"); +MODULE_DESCRIPTION("Livepatch module"); --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B5B6225F99E; Fri, 9 May 2025 20:18:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821906; cv=none; b=Z00QmLad+nCDJjfC7Q5T66iD0gOoTT07VLiqPQNm1/qM6fNEAK/GA7GM4bFNOniuR2fF5NsHc2gU83KcLgwdLKXFHK4zTMY98ay3HYAGBqdT0B1fEoGvZZgZDy9KKrTNY2hmrqco6ruUkznF359MYC+rDeF17RwvHNzMydUc1io= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821906; c=relaxed/simple; bh=K7S9V/CGtP7DC5m69+qZjgglsv1CBcatCZU2CSQ7YfI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tA+ktBML2SBUqVx7r1EC3la+ch57XLYGyOs2HdhElYZHo1DXePRHxYAeeebF6S9N9uDHOFN/nazJY5wWYqkFPSTRsg3Qv1DRKIJGfTQIaxmaV/eTPrRDy5Y39BLqWTMD0XdJwF8vb9qG0Tt4IvgQBLTPP9lTK+O93V4Aw93pjqY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=X91Ymlt6; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="X91Ymlt6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 14032C4CEEF; Fri, 9 May 2025 20:18:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821906; bh=K7S9V/CGtP7DC5m69+qZjgglsv1CBcatCZU2CSQ7YfI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=X91Ymlt6h3Y4Q61YN5gu8mOLwGg+QGo439hp5u108TdWj6VSM1to2lOt5hSskGhwH 6jSyCMxutp8f68U7QBEl6nfjYFeKr8oiUkEgSA4nGaOVLZz7ZEBJB+Iego4Y0RCWAx l+Hk1IadSabrpV5qSQH9Uf/o5gUnNrPJZDQIyWw6r88I5/iL1x5l8j9KyM8k3tAhhb gQbEscm9FaVzRI9Jg/wjfGJkYJPg90uAuAu9rgQ6mR3COdnQESIy1D7DTHyvXK+NIa KRVScXfe3uuKfkVPB7K9XFdAM5gyPFH5jVwTubcPgLLla6+5dFDYvhXMb3YqvF4kKh MuO2B67hMstNg== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 59/62] livepatch/klp-build: Introduce klp-build script for generating livepatch modules Date: Fri, 9 May 2025 13:17:23 -0700 Message-ID: <10ccbeb0f4bcd7d0a10cc9b9bd12fdc4894f83ee.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a klp-build script which automates the generation of a livepatch module from a source .patch file by performing the following steps: - Builds an original kernel with -function-sections and -fdata-sections, plus objtool function checksumming. - Applies the .patch file and rebuilds the kernel using the same options. - Runs 'objtool klp diff' to detect changed functions and generate intermediate binary diff objects. - Builds a kernel module which links the diff objects with some livepatch module init code (scripts/livepatch/init.c). - Finalizes the livepatch module (aka work around linker wreckage) using 'objtool klp post-link'. Signed-off-by: Josh Poimboeuf --- scripts/livepatch/klp-build | 697 ++++++++++++++++++++++++++++++++++++ 1 file changed, 697 insertions(+) create mode 100755 scripts/livepatch/klp-build diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build new file mode 100755 index 000000000000..ebbece6f6b8d --- /dev/null +++ b/scripts/livepatch/klp-build @@ -0,0 +1,697 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Build a livepatch module +# + +# shellcheck disable=3DSC1090 + +if (( BASH_VERSINFO[0] < 4 \ + || (BASH_VERSINFO[0] =3D=3D 4 && BASH_VERSINFO[1] < 4) )); then + echo "error: this script requires bash 4.4+" >&2 + exit 1 +fi + +set -o errexit +set -o errtrace +set -o pipefail +set -o nounset + +# Allow doing 'cmd | mapfile -t array' instead of 'mapfile -t array < <(cm= d)'. +# This helps keep execution in pipes so pipefail+errexit can catch errors. +shopt -s lastpipe + +unset SKIP_CLEANUP XTRACE +REPLACE=3D1 +SHORT_CIRCUIT=3D0 +shopt -o xtrace | grep -q 'on' && XTRACE=3D1 +# Avoid removing the previous $TMP_DIR until args have been fully processe= d. +KEEP_TMP=3D1 + +CPUS=3D"$(getconf _NPROCESSORS_ONLN)" +VERBOSE=3D"-s" + + +SCRIPT=3D"$(basename "$0")" +SCRIPT_DIR=3D"$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +FIX_PATCH_LINES=3D"$SCRIPT_DIR/fix-patch-lines" + +SRC=3D"$(pwd)" +OBJ=3D"$(pwd)" + +CONFIG=3D"$OBJ/.config" +TMP_DIR=3D"$OBJ/klp-tmp" + +ORIG_DIR=3D"$TMP_DIR/orig" +PATCHED_DIR=3D"$TMP_DIR/patched" +DIFF_DIR=3D"$TMP_DIR/diff" +KMOD_DIR=3D"$TMP_DIR/kmod" + +STASH_DIR=3D"$TMP_DIR/stash" +TIMESTAMP=3D"$TMP_DIR/timestamp" +PATCH_TMP_DIR=3D"$TMP_DIR/tmp" + +KLP_DIFF_LOG=3D"$DIFF_DIR/diff.log" + +grep0() { + command grep "$@" || true +} + +status() { + echo "$*" +} + +warn() { + echo "error: $(basename "$SCRIPT"): $*" >&2 +} + +die() { + warn "$@" + exit 1 +} + +declare -a STASHED_FILES + +stash_file() { + local file=3D"$1" + local rel_file=3D"${file#"$SRC"/}" + + [[ ! -e "$file" ]] && die "no file to stash: $file" + + mkdir -p "$STASH_DIR/$(dirname "$rel_file")" + cp -f "$file" "$STASH_DIR/$rel_file" + + STASHED_FILES+=3D("$rel_file") +} + +restore_files() { + local file + + for file in "${STASHED_FILES[@]}"; do + mv -f "$STASH_DIR/$file" "$SRC/$file" || warn "can't restore file: $file" + done + + STASHED_FILES=3D() +} + +cleanup() { + set +o nounset + revert_patches "--recount" + restore_files + [[ "$KEEP_TMP" -eq 0 ]] && rm -rf "$TMP_DIR" + true +} + +trap_err() { + warn "line ${BASH_LINENO[0]}: '$BASH_COMMAND'" +} + +trap cleanup EXIT INT TERM HUP +trap trap_err ERR + +__usage() { + cat < Output file [default: livepatch-.ko] + --no-replace Disable livepatch atomic replace + -v, --verbose Pass V=3D1 to kernel/module builds + +Advanced Options: + -S, --short-circuit=3DSTEP Start at build step (requires prior --keep-t= mp) + 1|orig Build original kernel (default) + 2|patched Build patched kernel + 3|diff Diff objects + 4|kmod Build patch module + -T, --keep-tmp Preserve tmp dir on exit + +EOF +} + +usage() { + __usage >&2 +} + +process_args() { + local keep_tmp=3D0 + local short + local long + local args + + short=3D"ho:vS:T" + long=3D"help,output:,no-replace,verbose,short-circuit:,keep-tmp" + + args=3D$(getopt --options "$short" --longoptions "$long" -- "$@") || { + echo; usage; exit + } + eval set -- "$args" + + while true; do + case "$1" in + -h | --help) + usage + exit 0 + ;; + -o | --output) + [[ "$2" !=3D *.ko ]] && die "output filename should end with .ko" + OUTFILE=3D"$2" + NAME=3D"$(basename "$OUTFILE")" + NAME=3D"${NAME%.ko}" + NAME=3D"$(module_name_string "$NAME")" + shift 2 + ;; + --no-replace) + REPLACE=3D0 + shift + ;; + -v | --verbose) + VERBOSE=3D"V=3D1" + shift + ;; + -S | --short-circuit) + [[ ! -d "$TMP_DIR" ]] && die "--short-circuit requires preserved klp-t= mp dir" + keep_tmp=3D1 + case "$2" in + 1 | orig) SHORT_CIRCUIT=3D1; ;; + 2 | patched) SHORT_CIRCUIT=3D2; ;; + 3 | diff) SHORT_CIRCUIT=3D3; ;; + 4 | mod) SHORT_CIRCUIT=3D4; ;; + *) die "invalid short-circuit step '$2'" ;; + esac + shift 2 + ;; + -T | --keep-tmp) + keep_tmp=3D1 + shift + ;; + --) + shift + break + ;; + *) + usage + exit 1 + ;; + esac + done + + if [[ $# -eq 0 ]]; then + usage + exit 1 + fi + + KEEP_TMP=3D"$keep_tmp" + PATCHES=3D("$@") +} + +# temporarily disable xtrace for especially verbose code +xtrace_save() { + [[ -v XTRACE ]] && set +x + return 0 +} + +xtrace_restore() { + [[ -v XTRACE ]] && set -x + return 0 +} + +validate_config() { + xtrace_save "reading .config" + source "$CONFIG" || die "no .config file in $(dirname "$CONFIG")" + xtrace_restore + + [[ -v CONFIG_LIVEPATCH ]] \ + || die "CONFIG_LIVEPATCH not enabled" + + [[ -v CONFIG_GCC_PLUGIN_LATENT_ENTROPY ]] \ + && die "kernel option 'CONFIG_GCC_PLUGIN_LATENT_ENTROPY' not supported" + + [[ -v CONFIG_GCC_PLUGIN_RANDSTRUCT ]] \ + && die "kernel option 'CONFIG_GCC_PLUGIN_RANDSTRUCT' not supported" + + return 0 +} + +# Only allow alphanumerics and '_' and '-' in the module name. Everything= else +# is replaced with '-'. Also truncate to 55 chars so the full name + NUL +# terminator fits in the kernel's 56-byte module name array. +module_name_string() { + echo "${1//[^a-zA-Z0-9_-]/-}" | cut -c 1-55 +} + +# If the module name wasn't specified on the cmdline with --output, give i= t a +# name based on the patch name. +set_module_name() { + [[ -v NAME ]] && return 0 + + if [[ "${#PATCHES[@]}" -eq 1 ]]; then + NAME=3D"$(basename "${PATCHES[0]}")" + NAME=3D"${NAME%.*}" + else + NAME=3D"patch" + fi + + NAME=3D"livepatch-$NAME" + NAME=3D"$(module_name_string "$NAME")" + + OUTFILE=3D"$NAME.ko" +} + +# Hardcode the value printed by the localversion script to prevent patch +# application from appending it with '+' due to a dirty git working tree. +set_kernelversion() { + local file=3D"$SRC/scripts/setlocalversion" + local localversion + + stash_file "$file" + + localversion=3D"$(cd "$SRC" && make --no-print-directory kernelversion)" + localversion=3D"$(cd "$SRC" && KERNELVERSION=3D"$localversion" ./scripts/= setlocalversion)" + [[ -z "$localversion" ]] && die "setlocalversion failed" + + echo "echo $localversion" > "$file" +} + +get_patch_files() { + local patch=3D"$1" + + grep0 -E '^(--- |\+\+\+ )' "$patch" \ + | gawk '{print $2}' \ + | sed 's|^[^/]*/||' \ + | sort -u +} + +# Make sure git re-stats the changed files +git_refresh() { + local patch=3D"$1" + local files=3D() + + [[ ! -d "$SRC/.git" ]] && return + + get_patch_files "$patch" | mapfile -t files + + ( + cd "$SRC" + git update-index -q --refresh -- "${files[@]}" + ) +} + +check_unsupported_patches() { + local patch + + for patch in "${PATCHES[@]}"; do + local files=3D() + + get_patch_files "$patch" | mapfile -t files + + for file in "${files[@]}"; do + case "$file" in + lib/*|*.S) + die "unsupported patch to $file" + ;; + esac + done + done +} + +apply_patch() { + local patch=3D"$1" + shift + local extra_args=3D("$@") + + [[ ! -f "$patch" ]] && die "$patch doesn't exist" + + ( cd "$SRC" && git apply "${extra_args[@]}" "$patch" ) + + APPLIED_PATCHES+=3D("$patch") +} + +revert_patch() { + local patch=3D"$1" + shift + local extra_args=3D("$@") + local tmp=3D() + + ( cd "$SRC" && git apply --reverse "${extra_args[@]}" "$patch" ) + git_refresh "$patch" + + for p in "${APPLIED_PATCHES[@]}"; do + [[ "$p" =3D=3D "$patch" ]] && continue + tmp+=3D("$p") + done + + APPLIED_PATCHES=3D("${tmp[@]}") +} + +apply_patches() { + local patch + + for patch in "${PATCHES[@]}"; do + apply_patch "$patch" + done +} + +revert_patches() { + local extra_args=3D("$@") + local patches=3D("${APPLIED_PATCHES[@]}") + + for (( i=3D${#patches[@]}-1 ; i>=3D0 ; i-- )) ; do + revert_patch "${patches[$i]}" "${extra_args[@]}" + done + + APPLIED_PATCHES=3D() + + # Make sure git actually sees the patches have been reverted. + [[ -d "$SRC/.git" ]] && (cd "$SRC" && git update-index -q --refresh) +} + +validate_patches() { + check_unsupported_patches + apply_patches + revert_patches +} + +do_init() { + # We're not yet smart enough to handle anything other than in-tree + # builds in pwd. + [[ ! "$SRC" -ef "$SCRIPT_DIR/../.." ]] && die "please run from the kernel= root directory" + [[ ! "$OBJ" -ef "$SCRIPT_DIR/../.." ]] && die "please run from the kernel= root directory" + + (( SHORT_CIRCUIT <=3D 1 )) && rm -rf "$TMP_DIR" + mkdir -p "$TMP_DIR" + + APPLIED_PATCHES=3D() + + [[ -x "$FIX_PATCH_LINES" ]] || die "can't find fix-patch-lines" + + validate_config + set_module_name + set_kernelversion +} + +# Refresh the patch hunk headers, specifically the line numbers and counts. +refresh_patch() { + local patch=3D"$1" + local tmpdir=3D"$PATCH_TMP_DIR" + local files=3D() + + rm -rf "$tmpdir" + mkdir -p "$tmpdir/a" + mkdir -p "$tmpdir/b" + + # Find all source files affected by the patch + grep0 -E '^(--- |\+\+\+ )[^ /]+' "$patch" | + sed -E 's/(--- |\+\+\+ )[^ /]+\///' | + sort | uniq | mapfile -t files + + # Copy orig source files to 'a' + ( cd "$SRC" && echo "${files[@]}" | xargs cp --parents --target-directory= =3D"$tmpdir/a" ) + + # Copy patched source files to 'b' + apply_patch "$patch" --recount + ( cd "$SRC" && echo "${files[@]}" | xargs cp --parents --target-directory= =3D"$tmpdir/b" ) + revert_patch "$patch" --recount + + # Diff 'a' and 'b' to make a clean patch + ( cd "$tmpdir" && git diff --no-index --no-prefix a b > "$patch" ) || true +} + +# Copy the patches to a temporary directory, fix their lines so as not to +# affect the __LINE__ macro for otherwise unchanged functions further down= the +# file, and update $PATCHES to point to the fixed patches. +fix_patches() { + local idx + local i + + rm -f "$TMP_DIR"/*.patch + + idx=3D0001 + for i in "${!PATCHES[@]}"; do + local old_patch=3D"${PATCHES[$i]}" + local tmp_patch=3D"$TMP_DIR/tmp.patch" + local patch=3D"${PATCHES[$i]}" + local new_patch + + new_patch=3D"$TMP_DIR/$idx-fixed-$(basename "$patch")" + + cp -f "$old_patch" "$tmp_patch" + refresh_patch "$tmp_patch" + "$FIX_PATCH_LINES" "$tmp_patch" > "$new_patch" + refresh_patch "$new_patch" + + PATCHES[i]=3D"$new_patch" + + rm -f "$tmp_patch" + idx=3D$(printf "%04d" $(( 10#$idx + 1 ))) + done +} + +build_kernel() { + local log=3D"$TMP_DIR/build.log" + local objtool_args=3D() + local cmd=3D() + + objtool_args=3D("--checksum") + [[ -v OBJTOOL_ARGS ]] && objtool_args+=3D("${OBJTOOL_ARGS}") + + cmd=3D("make") + + # When a patch to a kernel module references a newly created unexported + # symbol which lives in vmlinux or another kernel module, the patched + # kernel build fails with the following error: + # + # ERROR: modpost: "klp_string" [fs/xfs/xfs.ko] undefined! + # + # The undefined symbols are working as designed in that case. They get + # resolved later when the livepatch module build link pulls all the + # disparate objects together into the same kernel module. + # + # It would be good to have a way to tell modpost to skip checking for + # undefined symbols altogether. For now, just convert the error to a + # warning with KBUILD_MODPOST_WARN, and grep out the warning to avoid + # confusing the user. + # + cmd+=3D("KBUILD_MODPOST_WARN=3D1") + + cmd+=3D("$VERBOSE") + cmd+=3D("-j$CPUS") + cmd+=3D("KCFLAGS=3D-ffunction-sections -fdata-sections") + cmd+=3D("OBJTOOL_ARGS=3D${objtool_args[*]}") + cmd+=3D("vmlinux") + cmd+=3D("modules") + + ( + cd "$SRC" + "${cmd[@]}" \ + > >(tee -a "$log") \ + 2> >(tee -a "$log" | grep0 -v "modpost.*undefined!" >&2) + ) +} + +find_objects() { + local opts=3D("$@") + + # Find root-level vmlinux.o and non-root-level .ko files, + # excluding klp-tmp/ and .git/ + find "$OBJ" \( -path "$TMP_DIR" -o -path "$OBJ/.git" -o -regex "$OBJ/[^/]= [^/]*\.ko" \) -prune -o \ + -type f "${opts[@]}" \ + \( -name "*.ko" -o -path "$OBJ/vmlinux.o" \) \ + -printf '%P\n' +} + +# Copy all objects (.o archives) to $ORIG_DIR +copy_orig_objects() { + + rm -rf "$ORIG_DIR" + mkdir -p "$ORIG_DIR" + + ( + cd "$OBJ" + find_objects \ + | sed 's/\.ko$/.o/' \ + | xargs cp --parents --target-directory=3D"$ORIG_DIR" + ) + + mv -f "$TMP_DIR/build.log" "$ORIG_DIR" + touch "$TIMESTAMP" +} + +# Copy all changed objects to $PATCHED_DIR +copy_patched_objects() { + local found + local files=3D() + local opts=3D() + + rm -rf "$PATCHED_DIR" + mkdir -p "$PATCHED_DIR" + + # Note this doesn't work with some configs, thus the 'cmp' below. + opts=3D("-newer") + opts+=3D("$TIMESTAMP") + + find_objects "${opts[@]}" | mapfile -t files + + xtrace_save "processing all objects" + for _file in "${files[@]}"; do + local rel_file=3D"${_file/.ko/.o}" + local file=3D"$OBJ/$rel_file" + local orig_file=3D"$ORIG_DIR/$rel_file" + local patched_file=3D"$PATCHED_DIR/$rel_file" + + [[ ! -f "$file" ]] && die "missing $(basename "$file") for $_file" + + cmp -s "$orig_file" "$file" && continue + + mkdir -p "$(dirname "$patched_file")" + cp -f "$file" "$patched_file" + found=3D1 + done + xtrace_restore + + [[ -n "$found" ]] || die "no changes detected" + + mv -f "$TMP_DIR/build.log" "$PATCHED_DIR" +} + +# Diff changed objects, writing output object to $DIFF_DIR +diff_objects() { + local log=3D"$KLP_DIFF_LOG" + local files=3D() + + rm -rf "$DIFF_DIR" + mkdir -p "$DIFF_DIR" + + find "$PATCHED_DIR" -type f -name "*.o" | mapfile -t files + [[ ${#files[@]} -eq 0 ]] && die "no changes detected" + + # Diff all changed objects + for file in "${files[@]}"; do + local rel_file=3D"${file#"$PATCHED_DIR"/}" + local orig_file=3D"$rel_file" + local patched_file=3D"$PATCHED_DIR/$rel_file" + local out_file=3D"$DIFF_DIR/$rel_file" + local cmd=3D() + + mkdir -p "$(dirname "$out_file")" + + cmd=3D("$SRC/tools/objtool/objtool") + cmd+=3D("klp") + cmd+=3D("diff") + cmd+=3D("$orig_file") + cmd+=3D("$patched_file") + cmd+=3D("$out_file") + + ( + cd "$ORIG_DIR" + "${cmd[@]}" \ + > >(tee -a "$log") \ + 2> >(tee -a "$log" >&2) \ + || die "objtool klp diff failed" + ) + done +} + +# Build and post-process livepatch module in $KMOD_DIR +build_patch_module() { + local makefile=3D"$KMOD_DIR/Kbuild" + local log=3D"$KMOD_DIR/build.log" + local cflags=3D() + local files=3D() + local cmd=3D() + + rm -rf "$KMOD_DIR" + mkdir -p "$KMOD_DIR" + + cp -f "$SRC/scripts/livepatch/init.c" "$KMOD_DIR" + + echo "obj-m :=3D $NAME.o" > "$makefile" + echo -n "$NAME-y :=3D init.o" >> "$makefile" + + find "$DIFF_DIR" -type f -name "*.o" | mapfile -t files + [[ ${#files[@]} -eq 0 ]] && die "no changes detected" + + for file in "${files[@]}"; do + local rel_file=3D"${file#"$DIFF_DIR"/}" + local kmod_file=3D"$KMOD_DIR/$rel_file" + local cmd_file + + mkdir -p "$(dirname "$kmod_file")" + cp -f "$file" "$kmod_file" + + # Tell kbuild this is a prebuilt object + cp -f "$file" "${kmod_file}_shipped" + + echo -n " $rel_file" >> "$makefile" + + cmd_file=3D"$ORIG_DIR/$(dirname "$rel_file")/.$(basename "$rel_file").cm= d" + [[ -e "$cmd_file" ]] && cp -f "$cmd_file" "$(dirname "$kmod_file")" + done + + echo >> "$makefile" + + cflags=3D("-ffunction-sections") + cflags+=3D("-fdata-sections") + [[ $REPLACE -eq 0 ]] && cflags+=3D("-DKLP_NO_REPLACE") + + cmd=3D("make") + cmd+=3D("$VERBOSE") + cmd+=3D("-j$CPUS") + cmd+=3D("--directory=3D.") + cmd+=3D("M=3D$KMOD_DIR") + cmd+=3D("KCFLAGS=3D${cflags[*]}") + + # Build a "normal" kernel module with init.c and the diffed objects + ( + cd "$SRC" + "${cmd[@]}" \ + > >(tee -a "$log") \ + 2> >(tee -a "$log" >&2) + ) + + # Save off the intermediate binary for debugging + cp -f "$KMOD_DIR/$NAME.ko" "$KMOD_DIR/$NAME.ko.orig" + + # Fix (and work around) linker wreckage for klp syms / relocs + "$SRC/tools/objtool/objtool" klp post-link "$KMOD_DIR/$NAME.ko" || die "o= bjtool klp post-link failed" + + cp -f "$KMOD_DIR/$NAME.ko" "$OUTFILE" +} + + +##########################################################################= ###### + +process_args "$@" +do_init + +if (( SHORT_CIRCUIT <=3D 1 )); then + status "Building original kernel" + validate_patches + build_kernel + status "Copying original object files" + copy_orig_objects +fi + +if (( SHORT_CIRCUIT <=3D 2 )); then + status "Fixing patches" + fix_patches + apply_patches + status "Building patched kernel" + build_kernel + revert_patches + status "Copying patched object files" + copy_patched_objects +fi + +if (( SHORT_CIRCUIT <=3D 3 )); then + status "Diffing objects" + diff_objects +fi + +if (( SHORT_CIRCUIT <=3D 4 )); then + status "Building patch module: $OUTFILE" + build_patch_module +fi + +status "SUCCESS" --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 645F429ACE7; Fri, 9 May 2025 20:18:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821907; cv=none; b=Q/URXEzWLmDZ9xyrfjUb0leXwm9RLMU7vuVUJCdedJ8IVLdK8j+WZjPW0QsbT1QRZfc7ijfKmpEp7cmui4cwBMYDRU7TYZoqlctLuQaSxABwVjXzcSv3Y3G25ZGep2I8hrmDbbhArvI0NAH3BAFmI+TDu4f+NsSCt+5rTe2OVkk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821907; c=relaxed/simple; bh=ljV5bbNA0/17MC5i4FU8MNYIoVsgg5cRUxmLhI5HQRk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=T7ZtOqS3SR9dTPZuZDjntn0io+CwGgbjsK0YqbGO7lYwf2tajHOFXbVkWvf4nHEA6SLlHVZmus0T8D3BC9Skn+XSKOD09YVTGI7M52lV5CfBedK51doX1tIV0vqJW60FqPdLxN7CwCH0FlI66fu6IZ2/+HhMD+YAfp8fUEYjPfg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Ugik8eIG; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Ugik8eIG" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BA82BC4CEF0; Fri, 9 May 2025 20:18:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821907; bh=ljV5bbNA0/17MC5i4FU8MNYIoVsgg5cRUxmLhI5HQRk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ugik8eIG9SiuFoULrpiPA6HiSQIU5S+zZ39CrDqKo8R04BwEB789vJEGi8guzlH+Z Z+s5bmgBAhxpj395wZYS0aVdMZr2+w4kwOeROXt9tnrWVIYn/qmxFnjJ7dL9ZTtAUm 4/79F7MQLOTREj8dikoY/Og8Tg+8XyKaYje9mMMxJ6f6ycX95ZQZGU4wnMz0sRZk32 LwicUAjWTBcn1pyUQHLenmh5FUSY1UDYVO7RX6pnxTua/i3DW64XJM4tOzrt0Z4mEG 7dhrFMVlGaKkE2Ok2+op/vYQb6J7lHjnKK8bErW85pXOOMAIntCMY6d2/lVLIOvkUj 3k/SfDEkkhNGA== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 60/62] livepatch/klp-build: Add --debug option to show cloning decisions Date: Fri, 9 May 2025 13:17:24 -0700 Message-ID: <8dbc3602712d9f0481023895c37f9ed7ee44a735.1746821544.git.jpoimboe@kernel.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a --debug option which gets passed to "objtool klp diff" to enable debug output related to cloning decisions. Signed-off-by: Josh Poimboeuf --- scripts/livepatch/klp-build | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build index ebbece6f6b8d..08ef903d4090 100755 --- a/scripts/livepatch/klp-build +++ b/scripts/livepatch/klp-build @@ -21,7 +21,7 @@ set -o nounset # This helps keep execution in pipes so pipefail+errexit can catch errors. shopt -s lastpipe =20 -unset SKIP_CLEANUP XTRACE +unset DEBUG_CLONE SKIP_CLEANUP XTRACE REPLACE=3D1 SHORT_CIRCUIT=3D0 shopt -o xtrace | grep -q 'on' && XTRACE=3D1 @@ -120,6 +120,7 @@ Options: -v, --verbose Pass V=3D1 to kernel/module builds =20 Advanced Options: + -D, --debug Show symbol/reloc cloning decisions -S, --short-circuit=3DSTEP Start at build step (requires prior --keep-t= mp) 1|orig Build original kernel (default) 2|patched Build patched kernel @@ -140,8 +141,8 @@ process_args() { local long local args =20 - short=3D"ho:vS:T" - long=3D"help,output:,no-replace,verbose,short-circuit:,keep-tmp" + short=3D"ho:vDS:T" + long=3D"help,output:,no-replace,verbose,debug,short-circuit:,keep-tmp" =20 args=3D$(getopt --options "$short" --longoptions "$long" -- "$@") || { echo; usage; exit @@ -170,6 +171,11 @@ process_args() { VERBOSE=3D"V=3D1" shift ;; + -D | --debug) + DEBUG_CLONE=3D1 + keep_tmp=3D1 + shift + ;; -S | --short-circuit) [[ ! -d "$TMP_DIR" ]] && die "--short-circuit requires preserved klp-t= mp dir" keep_tmp=3D1 @@ -559,6 +565,7 @@ copy_patched_objects() { diff_objects() { local log=3D"$KLP_DIFF_LOG" local files=3D() + local opts=3D() =20 rm -rf "$DIFF_DIR" mkdir -p "$DIFF_DIR" @@ -566,6 +573,8 @@ diff_objects() { find "$PATCHED_DIR" -type f -name "*.o" | mapfile -t files [[ ${#files[@]} -eq 0 ]] && die "no changes detected" =20 + [[ -v DEBUG_CLONE ]] && opts=3D("--debug") + # Diff all changed objects for file in "${files[@]}"; do local rel_file=3D"${file#"$PATCHED_DIR"/}" @@ -579,6 +588,7 @@ diff_objects() { cmd=3D("$SRC/tools/objtool/objtool") cmd+=3D("klp") cmd+=3D("diff") + (( ${#opts[@]} > 0 )) && cmd+=3D("${opts[@]}") cmd+=3D("$orig_file") cmd+=3D("$patched_file") cmd+=3D("$out_file") --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7E9B429B20F; Fri, 9 May 2025 20:18:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821908; cv=none; b=ufSfkPFGuTHhhi0AH3ThCuTRydSkQ0KM9C5gsw5RJvfKM2uhjrkQOzomvCOOhxakzYX7ckIBhh/ozBCJBqleQ35G5DnsNThNgkJNYjA2T7SUKYXpYLR+G/yQS+0/TV4uSkbgsMZvHbCOqxYdutvznZ44VW4LoYlIGATTj8C6DHs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821908; c=relaxed/simple; bh=FNBWxK1Fm8BYB6Bj9vaGxYWsDefzu7nRRCD7N3z6kXY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Hl8cJg4e5DrJEZmsmMFIDD0unu2DaXyEe652JIFbLZeZD8td08P32ER9gTLa710K5PPigyI1DLpQQKijg14RZ6iEYmEm+ho2b4rdWVaH5aHN1r5t+EBhJviuz+eBK5CIv3kUuVhdSLzGK28OBAU2X6pgvWTQ+mnbOJBnUgw2nk0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=CmJ9IcVA; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="CmJ9IcVA" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6F739C4CEE4; Fri, 9 May 2025 20:18:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821908; bh=FNBWxK1Fm8BYB6Bj9vaGxYWsDefzu7nRRCD7N3z6kXY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CmJ9IcVAH+vd5cgWUX90l4VCRuN5bDvMg+seyX0HJuThju0nzTtdEo0fqbi8bHhtb YWStlkbVRRyxLx994PIR+NOPRUphgT9FRZDDm6xj22vFvGA+8Cc727HJAhfnSeRmC9 CDwxYS79duG8uBse6NBcE3AQ+WiVtCQHQjqIFXM3W93/L6+xYXZ2Enr/+jaip/qGyo 6QYmdpzH2aGWuOy1SY00bJaNSKShVeHBciq/oANcvXc8pZAKJx/7fjUNSQBtM8PNKT 7nzxjZq4ViyxNLcoY5L2nmDTXJpKhWyKiErVn1mBABmDONDJrgane9jeEofm2FuTxg 9Y2usqoNwAPkQ== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 61/62] livepatch/klp-build: Add --show-first-changed option to show function divergence Date: Fri, 9 May 2025 13:17:25 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a --show-first-changed option to identify where changed functions begin to diverge: - Parse 'objtool klp diff' output to find changed functions. - Run objtool again on each object with --debug-checksum=3D. - Diff the per-instruction checksum debug output to locate the first differing instruction. This can be useful for quickly determining where and why a function changed. Signed-off-by: Josh Poimboeuf --- scripts/livepatch/klp-build | 82 +++++++++++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 4 deletions(-) diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build index 08ef903d4090..f7d88726ed4f 100755 --- a/scripts/livepatch/klp-build +++ b/scripts/livepatch/klp-build @@ -21,7 +21,7 @@ set -o nounset # This helps keep execution in pipes so pipefail+errexit can catch errors. shopt -s lastpipe =20 -unset DEBUG_CLONE SKIP_CLEANUP XTRACE +unset DEBUG_CLONE DIFF_CHECKSUM SKIP_CLEANUP XTRACE REPLACE=3D1 SHORT_CIRCUIT=3D0 shopt -o xtrace | grep -q 'on' && XTRACE=3D1 @@ -115,6 +115,7 @@ Usage: $SCRIPT [OPTIONS] PATCH_FILE(s) Generate a livepatch module. =20 Options: + -f, --show-first-changed Show address of first changed instruction -o, --output Output file [default: livepatch-.ko] --no-replace Disable livepatch atomic replace -v, --verbose Pass V=3D1 to kernel/module builds @@ -141,8 +142,8 @@ process_args() { local long local args =20 - short=3D"ho:vDS:T" - long=3D"help,output:,no-replace,verbose,debug,short-circuit:,keep-tmp" + short=3D"hfo:vDS:T" + long=3D"help,show-first-changed,output:,no-replace,verbose,debug,short-ci= rcuit:,keep-tmp" =20 args=3D$(getopt --options "$short" --longoptions "$long" -- "$@") || { echo; usage; exit @@ -155,6 +156,10 @@ process_args() { usage exit 0 ;; + -f | --show-first-changed) + DIFF_CHECKSUM=3D1 + shift + ;; -o | --output) [[ "$2" !=3D *.ko ]] && die "output filename should end with .ko" OUTFILE=3D"$2" @@ -581,6 +586,7 @@ diff_objects() { local orig_file=3D"$rel_file" local patched_file=3D"$PATCHED_DIR/$rel_file" local out_file=3D"$DIFF_DIR/$rel_file" + local filter=3D() local cmd=3D() =20 mkdir -p "$(dirname "$out_file")" @@ -593,16 +599,80 @@ diff_objects() { cmd+=3D("$patched_file") cmd+=3D("$out_file") =20 + if [[ -v DIFF_CHECKSUM ]]; then + filter=3D("grep0") + filter+=3D("-Ev") + filter+=3D("DEBUG: .*checksum: ") + else + filter=3D("cat") + fi + ( cd "$ORIG_DIR" "${cmd[@]}" \ > >(tee -a "$log") \ - 2> >(tee -a "$log" >&2) \ + 2> >(tee -a "$log" | "${filter[@]}" >&2) \ || die "objtool klp diff failed" ) done } =20 +# For each changed object, run objtool with --debug-checksum to get the +# per-instruction checksums, and then diff those to find the first changed +# instruction for each function. +diff_checksums() { + local orig_log=3D"$ORIG_DIR/checksum.log" + local patched_log=3D"$PATCHED_DIR/checksum.log" + local -A funcs + local cmd=3D() + local line + local file + local func + + gawk '/\.o: changed function: / { + sub(/:$/, "", $1) + print $1, $NF + }' "$KLP_DIFF_LOG" | mapfile -t lines + + for line in "${lines[@]}"; do + read -r file func <<< "$line" + if [[ ! -v funcs["$file"] ]]; then + funcs["$file"]=3D"$func" + else + funcs["$file"]+=3D" $func" + fi + done + + cmd=3D("$SRC/tools/objtool/objtool") + cmd+=3D("--checksum") + cmd+=3D("--link") + cmd+=3D("--dry-run") + + for file in "${!funcs[@]}"; do + local opt=3D"--debug-checksum=3D${funcs[$file]// /,}" + + ( + cd "$ORIG_DIR" + "${cmd[@]}" "$opt" "$file" &> "$orig_log" \ + || ( cat "$orig_log" >&2; die "objtool --debug-checksum failed" ) + + cd "$PATCHED_DIR" + "${cmd[@]}" "$opt" "$file" &> "$patched_log" \ + || ( cat "$patched_log" >&2; die "objtool --debug-checksum failed" ) + ) + + for func in ${funcs[$file]}; do + diff <( grep0 -E "^DEBUG: .*checksum: $func " "$orig_log" | sed "s|$= ORIG_DIR/||") \ + <( grep0 -E "^DEBUG: .*checksum: $func " "$patched_log" | sed "s|$= PATCHED_DIR/||") \ + | gawk '/^< DEBUG: / { + gsub(/:/, "") + printf "%s: %s: %s\n", $3, $5, $6 + exit + }' || true + done + done +} + # Build and post-process livepatch module in $KMOD_DIR build_patch_module() { local makefile=3D"$KMOD_DIR/Kbuild" @@ -697,6 +767,10 @@ fi if (( SHORT_CIRCUIT <=3D 3 )); then status "Diffing objects" diff_objects + if [[ -v DIFF_CHECKSUM ]]; then + status "Finding first changed instructions" + diff_checksums + fi fi =20 if (( SHORT_CIRCUIT <=3D 4 )); then --=20 2.49.0 From nobody Tue Dec 16 10:00:04 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3896029B232; Fri, 9 May 2025 20:18:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821909; cv=none; b=AZ50MP66KBjrMs3f2tesLiVxqNwS2hda/LwksUyaZP2BJoRJjkKBeEvHKE+0XlhDcGhme935UgBLDMHEcJ/bgGtIyfLhugjkkWLokpRMf2n/6FTiMbtFi3TqBd9a/cCwXDLM/ebfrPp+55RQ27czrKcS67Rq1y6ES7y+7Ntyx9k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746821909; c=relaxed/simple; bh=vEnwKBFgMDnerydIawqZPcGrp8qCIphckzzU5Fp2jB8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=i5QcB42fzTfw9tvs5ar9ZFDLAnRJo4JkKFEhxI4EGzKav4JXjKAfT9sjhdvI4iZ11GIJfLWeIQLhWI/SYzMKc6GKnWistXB6P6XnE2XeYi8oEYDSEsLrmGX2oIWvkpmd0GLC2rwJTmA7y6Y1xj0H87IMpU+MGQcWXBvcLBswHIg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tHL3nFw7; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="tHL3nFw7" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 24293C4CEEF; Fri, 9 May 2025 20:18:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746821908; bh=vEnwKBFgMDnerydIawqZPcGrp8qCIphckzzU5Fp2jB8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tHL3nFw75Wj0azM2AY2o9njmQ758w+MeqxVob1iJeyM5JC6VEhdrO/wilGUoaP5To QtQnfGR7KiMEo7U4Sq0VEWZnY1J+tPyVEEI9jkHatKDtuNpDJaePxBDBecHqEi67Xg 1JzDD9twy+yZwEjI5+1irDxrWZ52WZ+7mkPqvNQDW8KBmacO8QZ/MNJQovAXwGJEum kLt9EMKCH5tRlzNlquUYs8hxHcvuXrHBH65b7C2JNSc0jMjy/122z1SJAIo6HcRrp5 cC0gIec9nP81w3hKS079UcpnmgqlOtbGzDP6KFWcmJ5RNnook9d29Ipz6DVTNHRrnE FVVbV/i0/4GLg== From: Josh Poimboeuf To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Petr Mladek , Miroslav Benes , Joe Lawrence , live-patching@vger.kernel.org, Song Liu , laokz , Jiri Kosina , Marcos Paulo de Souza , Weinan Liu , Fazla Mehrab , Chen Zhongjin , Puranjay Mohan Subject: [PATCH v2 62/62] livepatch: Introduce source code helpers for livepatch modules Date: Fri, 9 May 2025 13:17:26 -0700 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add some helper macros which can be used by livepatch source .patch files to register callbacks or patch syscalls. Signed-off-by: Josh Poimboeuf --- include/linux/livepatch_helpers.h | 68 +++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 include/linux/livepatch_helpers.h diff --git a/include/linux/livepatch_helpers.h b/include/linux/livepatch_he= lpers.h new file mode 100644 index 000000000000..09f4a2d53fd7 --- /dev/null +++ b/include/linux/livepatch_helpers.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_LIVEPATCH_HELPERS_H +#define _LINUX_LIVEPATCH_HELPERS_H + +/* + * Interfaces for use by livepatch patches + */ + +#include +#include + +#ifdef MODULE +#define KLP_OBJNAME __KBUILD_MODNAME +#else +#define KLP_OBJNAME vmlinux +#endif + +/* Livepatch callback registration */ + +#define KLP_CALLBACK_PTRS ".discard.klp_callback_ptrs" + +#define KLP_PRE_PATCH_CALLBACK(func) \ + klp_pre_patch_t __used __section(KLP_CALLBACK_PTRS) \ + __PASTE(__KLP_PRE_PATCH_PREFIX, KLP_OBJNAME) =3D func + +#define KLP_POST_PATCH_CALLBACK(func) \ + klp_post_patch_t __used __section(KLP_CALLBACK_PTRS) \ + __PASTE(__KLP_POST_PATCH_PREFIX, KLP_OBJNAME) =3D func + +#define KLP_PRE_UNPATCH_CALLBACK(func) \ + klp_pre_unpatch_t __used __section(KLP_CALLBACK_PTRS) \ + __PASTE(__KLP_PRE_UNPATCH_PREFIX, KLP_OBJNAME) =3D func + +#define KLP_POST_UNPATCH_CALLBACK(func) \ + klp_post_unpatch_t __used __section(KLP_CALLBACK_PTRS) \ + __PASTE(__KLP_POST_UNPATCH_PREFIX, KLP_OBJNAME) =3D func + +/* Syscall patching */ + +#define KLP_SYSCALL_DEFINE1(name, ...) KLP_SYSCALL_DEFINEx(1, _##name, __V= A_ARGS__) +#define KLP_SYSCALL_DEFINE2(name, ...) KLP_SYSCALL_DEFINEx(2, _##name, __V= A_ARGS__) +#define KLP_SYSCALL_DEFINE3(name, ...) KLP_SYSCALL_DEFINEx(3, _##name, __V= A_ARGS__) +#define KLP_SYSCALL_DEFINE4(name, ...) KLP_SYSCALL_DEFINEx(4, _##name, __V= A_ARGS__) +#define KLP_SYSCALL_DEFINE5(name, ...) KLP_SYSCALL_DEFINEx(5, _##name, __V= A_ARGS__) +#define KLP_SYSCALL_DEFINE6(name, ...) KLP_SYSCALL_DEFINEx(6, _##name, __V= A_ARGS__) + +#define KLP_SYSCALL_DEFINEx(x, sname, ...) \ + __KLP_SYSCALL_DEFINEx(x, sname, __VA_ARGS__) + +#ifdef CONFIG_X86_64 +// TODO move this to arch/x86/include/asm/syscall_wrapper.h and share code +#define __KLP_SYSCALL_DEFINEx(x, name, ...) \ + static long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ + static inline long __klp_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ + __X64_SYS_STUBx(x, name, __VA_ARGS__) \ + __IA32_SYS_STUBx(x, name, __VA_ARGS__) \ + static long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \ + { \ + long ret =3D __klp_do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__));\ + __MAP(x,__SC_TEST,__VA_ARGS__); \ + __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \ + return ret; \ + } \ + static inline long __klp_do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) + +#endif + +#endif /* _LINUX_LIVEPATCH_HELPERS_H */ --=20 2.49.0