* [PATCH v2 00/12] objtool/arm64: Port klp-build to arm64
@ 2026-03-17 22:51 Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 01/12] arm64: Annotate intra-function calls Josh Poimboeuf
` (12 more replies)
0 siblings, 13 replies; 16+ messages in thread
From: Josh Poimboeuf @ 2026-03-17 22:51 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Song Liu, Catalin Marinas, Will Deacon, linux-arm-kernel,
Mark Rutland, Nathan Chancellor, Nicolas Schier, Herbert Xu
v2:
- patches 1-2 were merged, rebase on tip/master
- improve commit message for "objtool: Extricate checksum calculation from validate_branch()"
- add review tags
v1: https://lore.kernel.org/cover.1772681234.git.jpoimboe@kernel.org
Port objtool and the klp-build tooling (for building livepatch modules)
to arm64.
Note this doesn't bring all the objtool bells and whistles to arm64, nor
any of the CFG reverse engineering. This only adds the bare minimum
needed for 'objtool --checksum'.
And note that objtool still doesn't get enabled at all for normal arm64
kernel builds, so this doesn't affect any users other than those running
klp-build directly.
Josh Poimboeuf (12):
arm64: Annotate intra-function calls
arm64: head: Move boot header to .head.data
arm64: Fix EFI linking with -fdata-sections
crypto: arm64: Move data to .rodata
objtool: Extricate checksum calculation from validate_branch()
objtool: Allow setting --mnop without --mcount
kbuild: Only run objtool if there is at least one command
objtool: Ignore jumps to the end of the function for non-CFG arches
objtool: Allow empty alternatives
objtool: Reuse consecutive string references
objtool: Introduce objtool for arm64
klp-build: Support cross-compilation
arch/arm64/Kconfig | 2 +
arch/arm64/kernel/entry.S | 2 +
arch/arm64/kernel/head.S | 2 +-
arch/arm64/kernel/proton-pack.c | 12 +-
arch/arm64/kernel/vmlinux.lds.S | 2 +-
arch/x86/boot/startup/Makefile | 2 +-
include/asm-generic/vmlinux.lds.h | 2 +-
include/linux/init.h | 1 +
lib/crypto/arm64/sha2-armv8.pl | 11 +-
scripts/Makefile.build | 4 +-
scripts/Makefile.lib | 46 +++----
scripts/Makefile.vmlinux_o | 15 +--
scripts/livepatch/klp-build | 11 +-
tools/objtool/Makefile | 4 +
tools/objtool/arch/arm64/Build | 2 +
tools/objtool/arch/arm64/decode.c | 116 ++++++++++++++++++
.../arch/arm64/include/arch/cfi_regs.h | 11 ++
tools/objtool/arch/arm64/include/arch/elf.h | 13 ++
.../objtool/arch/arm64/include/arch/special.h | 21 ++++
tools/objtool/arch/arm64/special.c | 21 ++++
tools/objtool/builtin-check.c | 5 -
tools/objtool/check.c | 83 +++++++++----
tools/objtool/elf.c | 9 +-
tools/objtool/include/objtool/checksum.h | 6 +-
24 files changed, 321 insertions(+), 82 deletions(-)
create mode 100644 tools/objtool/arch/arm64/Build
create mode 100644 tools/objtool/arch/arm64/decode.c
create mode 100644 tools/objtool/arch/arm64/include/arch/cfi_regs.h
create mode 100644 tools/objtool/arch/arm64/include/arch/elf.h
create mode 100644 tools/objtool/arch/arm64/include/arch/special.h
create mode 100644 tools/objtool/arch/arm64/special.c
--
2.53.0
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v2 01/12] arm64: Annotate intra-function calls
2026-03-17 22:51 [PATCH v2 00/12] objtool/arm64: Port klp-build to arm64 Josh Poimboeuf
@ 2026-03-17 22:51 ` Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 02/12] arm64: head: Move boot header to .head.data Josh Poimboeuf
` (11 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Josh Poimboeuf @ 2026-03-17 22:51 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Song Liu, Catalin Marinas, Will Deacon, linux-arm-kernel,
Mark Rutland, Nathan Chancellor, Nicolas Schier, Herbert Xu
In preparation for enabling objtool on arm64, annotate intra-function
calls.
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
arch/arm64/kernel/entry.S | 2 ++
arch/arm64/kernel/proton-pack.c | 12 +++++++-----
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index f8018b5c1f9a..cf808bb2abc0 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -10,6 +10,7 @@
#include <linux/arm-smccc.h>
#include <linux/init.h>
#include <linux/linkage.h>
+#include <linux/annotate.h>
#include <asm/alternative.h>
#include <asm/assembler.h>
@@ -707,6 +708,7 @@ alternative_else_nop_endif
* entry onto the return stack and using a RET instruction to
* enter the full-fat kernel vectors.
*/
+ ANNOTATE_INTRA_FUNCTION_CALL
bl 2f
b .
2:
diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c
index b3801f532b10..b63887a1b823 100644
--- a/arch/arm64/kernel/proton-pack.c
+++ b/arch/arm64/kernel/proton-pack.c
@@ -24,6 +24,7 @@
#include <linux/nospec.h>
#include <linux/prctl.h>
#include <linux/sched/task_stack.h>
+#include <linux/annotate.h>
#include <asm/debug-monitors.h>
#include <asm/insn.h>
@@ -245,11 +246,12 @@ static noinstr void qcom_link_stack_sanitisation(void)
{
u64 tmp;
- asm volatile("mov %0, x30 \n"
- ".rept 16 \n"
- "bl . + 4 \n"
- ".endr \n"
- "mov x30, %0 \n"
+ asm volatile("mov %0, x30 \n"
+ ".rept 16 \n"
+ ANNOTATE_INTRA_FUNCTION_CALL " \n"
+ "bl . + 4 \n"
+ ".endr \n"
+ "mov x30, %0 \n"
: "=&r" (tmp));
}
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 02/12] arm64: head: Move boot header to .head.data
2026-03-17 22:51 [PATCH v2 00/12] objtool/arm64: Port klp-build to arm64 Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 01/12] arm64: Annotate intra-function calls Josh Poimboeuf
@ 2026-03-17 22:51 ` Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 03/12] arm64: Fix EFI linking with -fdata-sections Josh Poimboeuf
` (10 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Josh Poimboeuf @ 2026-03-17 22:51 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Song Liu, Catalin Marinas, Will Deacon, linux-arm-kernel,
Mark Rutland, Nathan Chancellor, Nicolas Schier, Herbert Xu
The arm64 boot header is mostly data. Move it to a data section to
prevent objtool and other tools from trying to disassemble it. The
final linked result is the same.
Acked-by: Song Liu <song@kernel.or
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
arch/arm64/kernel/head.S | 2 +-
include/asm-generic/vmlinux.lds.h | 2 +-
include/linux/init.h | 1 +
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 87a822e5c4ca..0681c6e50859 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -54,7 +54,7 @@
* that are useful before the MMU is enabled. The allocations are described
* in the entry routines.
*/
- __HEAD
+ __HEADDATA
/*
* DO NOT MODIFY. Image header expected by Linux boot-loaders.
*/
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 1e1580febe4b..f82f170a97eb 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -663,7 +663,7 @@
__static_call_text_end = .;
/* Section used for early init (in .S files) */
-#define HEAD_TEXT KEEP(*(.head.text))
+#define HEAD_TEXT KEEP(*(.head.data .head.text))
#define HEAD_TEXT_SECTION \
.head.text : AT(ADDR(.head.text) - LOAD_OFFSET) { \
diff --git a/include/linux/init.h b/include/linux/init.h
index 40331923b9f4..91e16f3205e2 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -90,6 +90,7 @@
/* For assembly routines */
#define __HEAD .section ".head.text","ax"
+#define __HEADDATA .section ".head.data","aw"
#define __INIT .section ".init.text","ax"
#define __FINIT .previous
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 03/12] arm64: Fix EFI linking with -fdata-sections
2026-03-17 22:51 [PATCH v2 00/12] objtool/arm64: Port klp-build to arm64 Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 01/12] arm64: Annotate intra-function calls Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 02/12] arm64: head: Move boot header to .head.data Josh Poimboeuf
@ 2026-03-17 22:51 ` Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 04/12] crypto: arm64: Move data to .rodata Josh Poimboeuf
` (9 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Josh Poimboeuf @ 2026-03-17 22:51 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Song Liu, Catalin Marinas, Will Deacon, linux-arm-kernel,
Mark Rutland, Nathan Chancellor, Nicolas Schier, Herbert Xu
When building with func-fdata-sections, the .init.bss section gets split
up into a bunch of .init.bss.<var> sections. Make sure they get linked
into .init.data.
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
arch/arm64/kernel/vmlinux.lds.S | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 2964aad0362e..f825e6a26918 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -269,7 +269,7 @@ SECTIONS
INIT_CALLS
CON_INITCALL
INIT_RAM_FS
- *(.init.altinstructions .init.bss) /* from the EFI stub */
+ *(.init.altinstructions .init.bss .init.bss.*) /* from the EFI stub */
}
.exit.data : {
EXIT_DATA
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 04/12] crypto: arm64: Move data to .rodata
2026-03-17 22:51 [PATCH v2 00/12] objtool/arm64: Port klp-build to arm64 Josh Poimboeuf
` (2 preceding siblings ...)
2026-03-17 22:51 ` [PATCH v2 03/12] arm64: Fix EFI linking with -fdata-sections Josh Poimboeuf
@ 2026-03-17 22:51 ` Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 05/12] objtool: Extricate checksum calculation from validate_branch() Josh Poimboeuf
` (8 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Josh Poimboeuf @ 2026-03-17 22:51 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Song Liu, Catalin Marinas, Will Deacon, linux-arm-kernel,
Mark Rutland, Nathan Chancellor, Nicolas Schier, Herbert Xu
Data embedded in .text pollutes i-cache and confuses objtool and other
tools that try to disassemble it. Move it to .rodata.
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
lib/crypto/arm64/sha2-armv8.pl | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/lib/crypto/arm64/sha2-armv8.pl b/lib/crypto/arm64/sha2-armv8.pl
index 35ec9ae99fe1..8cd86768bf5c 100644
--- a/lib/crypto/arm64/sha2-armv8.pl
+++ b/lib/crypto/arm64/sha2-armv8.pl
@@ -237,7 +237,8 @@ $code.=<<___;
ldp $E,$F,[$ctx,#4*$SZ]
add $num,$inp,$num,lsl#`log(16*$SZ)/log(2)` // end of input
ldp $G,$H,[$ctx,#6*$SZ]
- adr $Ktbl,.LK$BITS
+ adrp $Ktbl,.LK$BITS
+ add $Ktbl,$Ktbl,:lo12:.LK$BITS
stp $ctx,$num,[x29,#96]
.Loop:
@@ -286,6 +287,7 @@ $code.=<<___;
ret
.size $func,.-$func
+.pushsection .rodata
.align 6
.type .LK$BITS,%object
.LK$BITS:
@@ -365,6 +367,7 @@ $code.=<<___;
#endif
.asciz "SHA$BITS block transform for ARMv8, CRYPTOGAMS by <appro\@openssl.org>"
.align 2
+.popsection
___
if ($SZ==4) {
@@ -385,7 +388,8 @@ sha256_block_armv8:
add x29,sp,#0
ld1.32 {$ABCD,$EFGH},[$ctx]
- adr $Ktbl,.LK256
+ adrp $Ktbl,.LK256
+ add $Ktbl,$Ktbl,:lo12:.LK256
.Loop_hw:
ld1 {@MSG[0]-@MSG[3]},[$inp],#64
@@ -648,7 +652,8 @@ sha256_block_neon:
mov x29, sp
sub sp,sp,#16*4
- adr $Ktbl,.LK256
+ adrp $Ktbl,.LK256
+ add $Ktbl,$Ktbl,:lo12:.LK256
add $num,$inp,$num,lsl#6 // len to point at the end of inp
ld1.8 {@X[0]},[$inp], #16
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 05/12] objtool: Extricate checksum calculation from validate_branch()
2026-03-17 22:51 [PATCH v2 00/12] objtool/arm64: Port klp-build to arm64 Josh Poimboeuf
` (3 preceding siblings ...)
2026-03-17 22:51 ` [PATCH v2 04/12] crypto: arm64: Move data to .rodata Josh Poimboeuf
@ 2026-03-17 22:51 ` Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 06/12] objtool: Allow setting --mnop without --mcount Josh Poimboeuf
` (7 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Josh Poimboeuf @ 2026-03-17 22:51 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Song Liu, Catalin Marinas, Will Deacon, linux-arm-kernel,
Mark Rutland, Nathan Chancellor, Nicolas Schier, Herbert Xu
In preparation for porting the checksum code to other arches, make its
functionality independent from the CFG reverse engineering code.
Now that it's no longer called by validate_insn(),
checksum_update_insn() has to manually iterate the alternatives.
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/check.c | 71 +++++++++++++++++-------
tools/objtool/include/objtool/checksum.h | 6 +-
2 files changed, 53 insertions(+), 24 deletions(-)
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 2301fb7ff3c8..d428d63b29c6 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -2633,8 +2633,7 @@ static bool validate_branch_enabled(void)
{
return opts.stackval ||
opts.orc ||
- opts.uaccess ||
- opts.checksum;
+ opts.uaccess;
}
static int decode_sections(struct objtool_file *file)
@@ -3663,6 +3662,7 @@ static bool skip_alt_group(struct instruction *insn)
return alt_insn->type == INSN_CLAC || alt_insn->type == INSN_STAC;
}
+#ifdef BUILD_KLP
static int checksum_debug_init(struct objtool_file *file)
{
char *dup, *s;
@@ -3705,9 +3705,30 @@ static void checksum_update_insn(struct objtool_file *file, struct symbol *func,
struct instruction *insn)
{
struct reloc *reloc = insn_reloc(file, insn);
+ struct alternative *alt;
unsigned long offset;
struct symbol *sym;
+ for (alt = insn->alts; alt; alt = alt->next) {
+ struct alt_group *alt_group = alt->insn->alt_group;
+
+ checksum_update(func, insn, &alt->type, sizeof(alt->type));
+
+ if (alt_group && alt_group->orig_group) {
+ struct instruction *alt_insn;
+
+ checksum_update(func, insn, &alt_group->feature, sizeof(alt_group->feature));
+
+ for (alt_insn = alt->insn; alt_insn; alt_insn = next_insn_same_sec(file, alt_insn)) {
+ checksum_update_insn(file, func, alt_insn);
+ if (alt_insn == alt_group->last_insn)
+ break;
+ }
+ } else {
+ checksum_update(func, insn, &alt->insn->offset, sizeof(alt->insn->offset));
+ }
+ }
+
if (insn->fake)
return;
@@ -3716,9 +3737,11 @@ static void checksum_update_insn(struct objtool_file *file, struct symbol *func,
if (!reloc) {
struct symbol *call_dest = insn_call_dest(insn);
- if (call_dest)
+ if (call_dest) {
+ /* intra-TU call without reloc */
checksum_update(func, insn, call_dest->demangled_name,
strlen(call_dest->demangled_name));
+ }
return;
}
@@ -3745,6 +3768,29 @@ static void checksum_update_insn(struct objtool_file *file, struct symbol *func,
checksum_update(func, insn, &offset, sizeof(offset));
}
+static int calculate_checksums(struct objtool_file *file)
+{
+ struct instruction *insn;
+ struct symbol *func;
+
+ if (checksum_debug_init(file))
+ return -1;
+
+ for_each_sym(file->elf, func) {
+ if (!is_func_sym(func))
+ continue;
+
+ checksum_init(func);
+
+ func_for_each_insn(file, func, insn)
+ checksum_update_insn(file, func, insn);
+
+ checksum_finish(func);
+ }
+ return 0;
+}
+#endif /* BUILD_KLP */
+
static int validate_branch(struct objtool_file *file, struct symbol *func,
struct instruction *insn, struct insn_state state);
static int do_validate_branch(struct objtool_file *file, struct symbol *func,
@@ -4026,9 +4072,6 @@ static int do_validate_branch(struct objtool_file *file, struct symbol *func,
insn->trace = 0;
next_insn = next_insn_to_validate(file, insn);
- if (opts.checksum && func && insn->sec)
- checksum_update_insn(file, func, insn);
-
if (func && insn_func(insn) && func != insn_func(insn)->pfunc) {
/* Ignore KCFI type preambles, which always fall through */
if (is_prefix_func(func))
@@ -4094,9 +4137,6 @@ static int validate_unwind_hint(struct objtool_file *file,
struct symbol *func = insn_func(insn);
int ret;
- if (opts.checksum)
- checksum_init(func);
-
ret = validate_branch(file, func, insn, *state);
if (ret)
BT_INSN(insn, "<=== (hint)");
@@ -4539,9 +4579,6 @@ static int validate_symbol(struct objtool_file *file, struct section *sec,
func = insn_func(insn);
- if (opts.checksum)
- checksum_init(func);
-
if (opts.trace && !fnmatch(opts.trace, sym->name, 0)) {
trace_enable();
TRACE("%s: validation begin\n", sym->name);
@@ -4554,9 +4591,6 @@ static int validate_symbol(struct objtool_file *file, struct section *sec,
TRACE("%s: validation %s\n\n", sym->name, ret ? "failed" : "end");
trace_disable();
- if (opts.checksum)
- checksum_finish(func);
-
return ret;
}
@@ -5011,10 +5045,6 @@ int check(struct objtool_file *file)
cfi_hash_add(&init_cfi);
cfi_hash_add(&func_cfi);
- ret = checksum_debug_init(file);
- if (ret)
- goto out;
-
ret = decode_sections(file);
if (ret)
goto out;
@@ -5105,6 +5135,9 @@ int check(struct objtool_file *file)
warnings += check_abs_references(file);
if (opts.checksum) {
+ ret = calculate_checksums(file);
+ if (ret)
+ goto out;
ret = create_sym_checksum_section(file);
if (ret)
goto out;
diff --git a/tools/objtool/include/objtool/checksum.h b/tools/objtool/include/objtool/checksum.h
index 7fe21608722a..36a17688c716 100644
--- a/tools/objtool/include/objtool/checksum.h
+++ b/tools/objtool/include/objtool/checksum.h
@@ -32,11 +32,7 @@ static inline void checksum_finish(struct symbol *func)
#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) {}
+static inline int calculate_checksums(struct objtool_file *file) { return -ENOSYS; }
#endif /* !BUILD_KLP */
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 06/12] objtool: Allow setting --mnop without --mcount
2026-03-17 22:51 [PATCH v2 00/12] objtool/arm64: Port klp-build to arm64 Josh Poimboeuf
` (4 preceding siblings ...)
2026-03-17 22:51 ` [PATCH v2 05/12] objtool: Extricate checksum calculation from validate_branch() Josh Poimboeuf
@ 2026-03-17 22:51 ` Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 07/12] kbuild: Only run objtool if there is at least one command Josh Poimboeuf
` (6 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Josh Poimboeuf @ 2026-03-17 22:51 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Song Liu, Catalin Marinas, Will Deacon, linux-arm-kernel,
Mark Rutland, Nathan Chancellor, Nicolas Schier, Herbert Xu
Instead of returning an error for --mnop without --mcount, just silently
ignore it. This will help simplify kbuild's handling of objtool args.
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/builtin-check.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
index b780df513715..f528a58aca74 100644
--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -145,11 +145,6 @@ int cmd_parse_options(int argc, const char **argv, const char * const usage[])
static bool opts_valid(void)
{
- if (opts.mnop && !opts.mcount) {
- ERROR("--mnop requires --mcount");
- return false;
- }
-
if (opts.noinstr && !opts.link) {
ERROR("--noinstr requires --link");
return false;
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 07/12] kbuild: Only run objtool if there is at least one command
2026-03-17 22:51 [PATCH v2 00/12] objtool/arm64: Port klp-build to arm64 Josh Poimboeuf
` (5 preceding siblings ...)
2026-03-17 22:51 ` [PATCH v2 06/12] objtool: Allow setting --mnop without --mcount Josh Poimboeuf
@ 2026-03-17 22:51 ` Josh Poimboeuf
2026-03-18 19:54 ` Nicolas Schier
2026-03-17 22:51 ` [PATCH v2 08/12] objtool: Ignore jumps to the end of the function for non-CFG arches Josh Poimboeuf
` (5 subsequent siblings)
12 siblings, 1 reply; 16+ messages in thread
From: Josh Poimboeuf @ 2026-03-17 22:51 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Song Liu, Catalin Marinas, Will Deacon, linux-arm-kernel,
Mark Rutland, Nathan Chancellor, Nicolas Schier, Herbert Xu
Split the objtool args into commands and options, such that if no
commands have been enabled, objtool doesn't run.
This is in preparation in enabling objtool and klp-build for arm64.
Reviewed-by: Nathan Chancellor <nathan@kernel.org>
Tested-by: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
arch/x86/boot/startup/Makefile | 2 +-
scripts/Makefile.build | 4 +--
scripts/Makefile.lib | 46 ++++++++++++++++++----------------
scripts/Makefile.vmlinux_o | 15 ++++-------
4 files changed, 33 insertions(+), 34 deletions(-)
diff --git a/arch/x86/boot/startup/Makefile b/arch/x86/boot/startup/Makefile
index 5e499cfb29b5..a08297829fc6 100644
--- a/arch/x86/boot/startup/Makefile
+++ b/arch/x86/boot/startup/Makefile
@@ -36,7 +36,7 @@ $(patsubst %.o,$(obj)/%.o,$(lib-y)): OBJECT_FILES_NON_STANDARD := y
# relocations, even if other objtool actions are being deferred.
#
$(pi-objs): objtool-enabled = 1
-$(pi-objs): objtool-args = $(if $(delay-objtool),--dry-run,$(objtool-args-y)) --noabs
+$(pi-objs): objtool-args = $(if $(delay-objtool),--dry-run,$(objtool-cmds-y) $(objtool-opts-y)) --noabs
#
# Confine the startup code by prefixing all symbols with __pi_ (for position
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 3652b85be545..8a1bdfdb2fdb 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -277,7 +277,7 @@ endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
is-standard-object = $(if $(filter-out y%, $(OBJECT_FILES_NON_STANDARD_$(target-stem).o)$(OBJECT_FILES_NON_STANDARD)n),$(is-kernel-object))
ifdef CONFIG_OBJTOOL
-$(obj)/%.o: private objtool-enabled = $(if $(is-standard-object),$(if $(delay-objtool),$(is-single-obj-m),y))
+$(obj)/%.o: private objtool-enabled = $(if $(is-standard-object),$(if $(objtool-cmds-y),$(if $(delay-objtool),$(is-single-obj-m),y)))
endif
ifneq ($(findstring 1, $(KBUILD_EXTRA_WARN)),)
@@ -501,7 +501,7 @@ define rule_ld_multi_m
$(call cmd,gen_objtooldep)
endef
-$(multi-obj-m): private objtool-enabled := $(delay-objtool)
+$(multi-obj-m): private objtool-enabled := $(if $(objtool-cmds-y),$(delay-objtool))
$(multi-obj-m): private part-of-module := y
$(multi-obj-m): %.o: %.mod FORCE
$(call if_changed_rule,ld_multi_m)
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 0718e39cedda..40a462581666 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -183,27 +183,31 @@ ifdef CONFIG_OBJTOOL
objtool := $(objtree)/tools/objtool/objtool
-objtool-args-$(CONFIG_HAVE_JUMP_LABEL_HACK) += --hacks=jump_label
-objtool-args-$(CONFIG_HAVE_NOINSTR_HACK) += --hacks=noinstr
-objtool-args-$(CONFIG_MITIGATION_CALL_DEPTH_TRACKING) += --hacks=skylake
-objtool-args-$(CONFIG_X86_KERNEL_IBT) += --ibt
-objtool-args-$(CONFIG_FINEIBT) += --cfi
-objtool-args-$(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL) += --mcount
-ifdef CONFIG_FTRACE_MCOUNT_USE_OBJTOOL
-objtool-args-$(CONFIG_HAVE_OBJTOOL_NOP_MCOUNT) += --mnop
-endif
-objtool-args-$(CONFIG_UNWINDER_ORC) += --orc
-objtool-args-$(CONFIG_MITIGATION_RETPOLINE) += --retpoline
-objtool-args-$(CONFIG_MITIGATION_RETHUNK) += --rethunk
-objtool-args-$(CONFIG_MITIGATION_SLS) += --sls
-objtool-args-$(CONFIG_STACK_VALIDATION) += --stackval
-objtool-args-$(CONFIG_HAVE_STATIC_CALL_INLINE) += --static-call
-objtool-args-$(CONFIG_HAVE_UACCESS_VALIDATION) += --uaccess
-objtool-args-$(or $(CONFIG_GCOV_KERNEL),$(CONFIG_KCOV)) += --no-unreachable
-objtool-args-$(CONFIG_PREFIX_SYMBOLS) += --prefix=$(CONFIG_FUNCTION_PADDING_BYTES)
-objtool-args-$(CONFIG_OBJTOOL_WERROR) += --werror
+# objtool commands
+objtool-cmds-$(CONFIG_HAVE_JUMP_LABEL_HACK) += --hacks=jump_label
+objtool-cmds-$(CONFIG_HAVE_NOINSTR_HACK) += --hacks=noinstr
+objtool-cmds-$(CONFIG_MITIGATION_CALL_DEPTH_TRACKING) += --hacks=skylake
+objtool-cmds-$(CONFIG_X86_KERNEL_IBT) += --ibt
+objtool-cmds-$(CONFIG_FINEIBT) += --cfi
+objtool-cmds-$(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL) += --mcount
+objtool-cmds-$(CONFIG_UNWINDER_ORC) += --orc
+objtool-cmds-$(CONFIG_MITIGATION_RETPOLINE) += --retpoline
+objtool-cmds-$(CONFIG_MITIGATION_RETHUNK) += --rethunk
+objtool-cmds-$(CONFIG_MITIGATION_SLS) += --sls
+objtool-cmds-$(CONFIG_STACK_VALIDATION) += --stackval
+objtool-cmds-$(CONFIG_HAVE_STATIC_CALL_INLINE) += --static-call
+objtool-cmds-$(CONFIG_HAVE_UACCESS_VALIDATION) += --uaccess
+objtool-cmds-$(CONFIG_PREFIX_SYMBOLS) += --prefix=$(CONFIG_FUNCTION_PADDING_BYTES)
+objtool-cmds-y += $(OBJTOOL_ARGS)
-objtool-args = $(objtool-args-y) \
+# objtool options
+ifdef CONFIG_FTRACE_MCOUNT_USE_OBJTOOL
+objtool-opts-$(CONFIG_HAVE_OBJTOOL_NOP_MCOUNT) += --mnop
+endif
+objtool-opts-$(or $(CONFIG_GCOV_KERNEL),$(CONFIG_KCOV)) += --no-unreachable
+objtool-opts-$(CONFIG_OBJTOOL_WERROR) += --werror
+
+objtool-args = $(objtool-cmds-y) $(objtool-opts-y) \
$(if $(delay-objtool), --link) \
$(if $(part-of-module), --module)
@@ -212,7 +216,7 @@ delay-objtool := $(or $(CONFIG_LTO_CLANG),$(CONFIG_X86_KERNEL_IBT),$(CONFIG_KLP_
cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool-args) $@)
cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(objtool))' ; } >> $(dot-target).cmd)
-objtool-enabled := y
+objtool-enabled = $(if $(objtool-cmds-y),y)
endif # CONFIG_OBJTOOL
diff --git a/scripts/Makefile.vmlinux_o b/scripts/Makefile.vmlinux_o
index 527352c222ff..09af33203bd8 100644
--- a/scripts/Makefile.vmlinux_o
+++ b/scripts/Makefile.vmlinux_o
@@ -36,18 +36,13 @@ endif
# For !delay-objtool + CONFIG_NOINSTR_VALIDATION, it runs on both translation
# units and vmlinux.o, with the latter only used for noinstr/unret validation.
-objtool-enabled := $(or $(delay-objtool),$(CONFIG_NOINSTR_VALIDATION))
-
-ifeq ($(delay-objtool),y)
-vmlinux-objtool-args-y += $(objtool-args-y)
-else
-vmlinux-objtool-args-$(CONFIG_OBJTOOL_WERROR) += --werror
+ifneq ($(delay-objtool),y)
+objtool-cmds-y =
+objtool-opts-y += --link
endif
-vmlinux-objtool-args-$(CONFIG_NOINSTR_VALIDATION) += --noinstr \
- $(if $(or $(CONFIG_MITIGATION_UNRET_ENTRY),$(CONFIG_MITIGATION_SRSO)), --unret)
-
-objtool-args = $(vmlinux-objtool-args-y) --link
+objtool-cmds-$(CONFIG_NOINSTR_VALIDATION) += --noinstr \
+ $(if $(or $(CONFIG_MITIGATION_UNRET_ENTRY),$(CONFIG_MITIGATION_SRSO)), --unret)
# Link of vmlinux.o used for section mismatch analysis
# ---------------------------------------------------------------------------
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 08/12] objtool: Ignore jumps to the end of the function for non-CFG arches
2026-03-17 22:51 [PATCH v2 00/12] objtool/arm64: Port klp-build to arm64 Josh Poimboeuf
` (6 preceding siblings ...)
2026-03-17 22:51 ` [PATCH v2 07/12] kbuild: Only run objtool if there is at least one command Josh Poimboeuf
@ 2026-03-17 22:51 ` Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 09/12] objtool: Allow empty alternatives Josh Poimboeuf
` (4 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Josh Poimboeuf @ 2026-03-17 22:51 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Song Liu, Catalin Marinas, Will Deacon, linux-arm-kernel,
Mark Rutland, Nathan Chancellor, Nicolas Schier, Herbert Xu
Sometimes Clang arm64 code jumps to the end of the function for UB.
No need to make that an error, arm64 doesn't reverse engineer the CFG
anyway.
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/check.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index d428d63b29c6..6e33a29bd3ed 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1630,10 +1630,12 @@ static int add_jump_destinations(struct objtool_file *file)
/*
* GCOV/KCOV dead code can jump to the end of
* the function/section.
+ *
+ * Clang on arm64 also does this sometimes for
+ * undefined behavior.
*/
- if (file->ignore_unreachables && func &&
- dest_sec == insn->sec &&
- dest_off == func->offset + func->len)
+ if ((file->ignore_unreachables || (!opts.stackval && !opts.orc)) &&
+ func && dest_sec == insn->sec && dest_off == func->offset + func->len)
continue;
ERROR_INSN(insn, "can't find jump dest instruction at %s",
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 09/12] objtool: Allow empty alternatives
2026-03-17 22:51 [PATCH v2 00/12] objtool/arm64: Port klp-build to arm64 Josh Poimboeuf
` (7 preceding siblings ...)
2026-03-17 22:51 ` [PATCH v2 08/12] objtool: Ignore jumps to the end of the function for non-CFG arches Josh Poimboeuf
@ 2026-03-17 22:51 ` Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 10/12] objtool: Reuse consecutive string references Josh Poimboeuf
` (3 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Josh Poimboeuf @ 2026-03-17 22:51 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Song Liu, Catalin Marinas, Will Deacon, linux-arm-kernel,
Mark Rutland, Nathan Chancellor, Nicolas Schier, Herbert Xu
arm64 can have empty alternatives, which are effectively no-ops. Ignore
them.
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/check.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 6e33a29bd3ed..7297fb87f876 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1994,10 +1994,8 @@ static int add_special_section_alts(struct objtool_file *file)
}
if (special_alt->group) {
- if (!special_alt->orig_len) {
- ERROR_INSN(orig_insn, "empty alternative entry");
+ if (!special_alt->orig_len)
continue;
- }
if (handle_group_alt(file, special_alt, orig_insn, &new_insn))
return -1;
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 10/12] objtool: Reuse consecutive string references
2026-03-17 22:51 [PATCH v2 00/12] objtool/arm64: Port klp-build to arm64 Josh Poimboeuf
` (8 preceding siblings ...)
2026-03-17 22:51 ` [PATCH v2 09/12] objtool: Allow empty alternatives Josh Poimboeuf
@ 2026-03-17 22:51 ` Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 11/12] objtool: Introduce objtool for arm64 Josh Poimboeuf
` (2 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Josh Poimboeuf @ 2026-03-17 22:51 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Song Liu, Catalin Marinas, Will Deacon, linux-arm-kernel,
Mark Rutland, Nathan Chancellor, Nicolas Schier, Herbert Xu
For duplicate strings, elf_add_string() just blindly adds duplicates.
That can be a problem for arm64 which often uses two consecutive
instructions (and corresponding relocations) to put an address into a
register, like:
d8: 90000001 adrp x1, 0 <meminfo_proc_show> d8: R_AARCH64_ADR_PREL_PG_HI21 .rodata.meminfo_proc_show.str1.8
dc: 91000021 add x1, x1, #0x0 dc: R_AARCH64_ADD_ABS_LO12_NC .rodata.meminfo_proc_show.str1.8
Referencing two different string addresses in the adrp+add pair can
result in a corrupt string addresses. Detect such consecutive reuses
and force them to use the same string.
Acked-by: Song Liu <song@kernel.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
tools/objtool/elf.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index b911abe3a15e..5ccae2c937dc 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -1374,6 +1374,8 @@ struct elf *elf_create_file(GElf_Ehdr *ehdr, const char *name)
unsigned int elf_add_string(struct elf *elf, struct section *strtab, const char *str)
{
+ static unsigned int last_off;
+ static const char *last_str;
unsigned int offset;
if (!strtab)
@@ -1382,17 +1384,22 @@ unsigned int elf_add_string(struct elf *elf, struct section *strtab, const char
ERROR("can't find .strtab section");
return -1;
}
-
if (!strtab->sh.sh_addralign) {
ERROR("'%s': invalid sh_addralign", strtab->name);
return -1;
}
+ if (last_str && !strcmp(last_str, str))
+ return last_off;
+
offset = ALIGN(sec_size(strtab), strtab->sh.sh_addralign);
if (!elf_add_data(elf, strtab, str, strlen(str) + 1))
return -1;
+ last_str = str;
+ last_off = offset;
+
return offset;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 11/12] objtool: Introduce objtool for arm64
2026-03-17 22:51 [PATCH v2 00/12] objtool/arm64: Port klp-build to arm64 Josh Poimboeuf
` (9 preceding siblings ...)
2026-03-17 22:51 ` [PATCH v2 10/12] objtool: Reuse consecutive string references Josh Poimboeuf
@ 2026-03-17 22:51 ` Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 12/12] klp-build: Support cross-compilation Josh Poimboeuf
2026-03-19 4:13 ` [PATCH v2 00/12] objtool/arm64: Port klp-build to arm64 Josh Poimboeuf
12 siblings, 0 replies; 16+ messages in thread
From: Josh Poimboeuf @ 2026-03-17 22:51 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Song Liu, Catalin Marinas, Will Deacon, linux-arm-kernel,
Mark Rutland, Nathan Chancellor, Nicolas Schier, Herbert Xu
Add basic support for arm64 on objtool. Only --checksum is currently
supported.
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
arch/arm64/Kconfig | 2 +
tools/objtool/Makefile | 4 +
tools/objtool/arch/arm64/Build | 2 +
tools/objtool/arch/arm64/decode.c | 116 ++++++++++++++++++
.../arch/arm64/include/arch/cfi_regs.h | 11 ++
tools/objtool/arch/arm64/include/arch/elf.h | 13 ++
.../objtool/arch/arm64/include/arch/special.h | 21 ++++
tools/objtool/arch/arm64/special.c | 21 ++++
8 files changed, 190 insertions(+)
create mode 100644 tools/objtool/arch/arm64/Build
create mode 100644 tools/objtool/arch/arm64/decode.c
create mode 100644 tools/objtool/arch/arm64/include/arch/cfi_regs.h
create mode 100644 tools/objtool/arch/arm64/include/arch/elf.h
create mode 100644 tools/objtool/arch/arm64/include/arch/special.h
create mode 100644 tools/objtool/arch/arm64/special.c
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 38dba5f7e4d2..354aa80c5b4b 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -236,9 +236,11 @@ config ARM64
select HAVE_HW_BREAKPOINT if PERF_EVENTS
select HAVE_IOREMAP_PROT
select HAVE_IRQ_TIME_ACCOUNTING
+ select HAVE_KLP_BUILD
select HAVE_LIVEPATCH
select HAVE_MOD_ARCH_SPECIFIC
select HAVE_NMI
+ select HAVE_OBJTOOL
select HAVE_PERF_EVENTS
select HAVE_PERF_EVENTS_NMI if ARM64_PSEUDO_NMI
select HAVE_PERF_REGS
diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
index b71d1886022e..66b04172b79a 100644
--- a/tools/objtool/Makefile
+++ b/tools/objtool/Makefile
@@ -11,6 +11,10 @@ ifeq ($(SRCARCH),loongarch)
BUILD_ORC := y
endif
+ifeq ($(SRCARCH),arm64)
+ ARCH_HAS_KLP := y
+endif
+
ifeq ($(ARCH_HAS_KLP),y)
HAVE_XXHASH = $(shell printf "$(pound)include <xxhash.h>\nXXH3_state_t *state;int main() {}" | \
$(HOSTCC) $(HOSTCFLAGS) -xc - -o /dev/null -lxxhash 2> /dev/null && echo y || echo n)
diff --git a/tools/objtool/arch/arm64/Build b/tools/objtool/arch/arm64/Build
new file mode 100644
index 000000000000..d24d5636a5b8
--- /dev/null
+++ b/tools/objtool/arch/arm64/Build
@@ -0,0 +1,2 @@
+objtool-y += decode.o
+objtool-y += special.o
diff --git a/tools/objtool/arch/arm64/decode.c b/tools/objtool/arch/arm64/decode.c
new file mode 100644
index 000000000000..ee93c096243f
--- /dev/null
+++ b/tools/objtool/arch/arm64/decode.c
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <objtool/check.h>
+#include <objtool/disas.h>
+#include <objtool/elf.h>
+#include <objtool/arch.h>
+#include <objtool/warn.h>
+#include <objtool/builtin.h>
+
+const char *arch_reg_name[CFI_NUM_REGS] = {};
+
+int arch_ftrace_match(const char *name)
+{
+ return 0;
+}
+
+s64 arch_insn_adjusted_addend(struct instruction *insn, struct reloc *reloc)
+{
+ return reloc_addend(reloc);
+}
+
+bool arch_callee_saved_reg(unsigned char reg)
+{
+ return false;
+}
+
+int arch_decode_hint_reg(u8 sp_reg, int *base)
+{
+ exit(-1);
+}
+
+const char *arch_nop_insn(int len)
+{
+ exit(-1);
+}
+
+const char *arch_ret_insn(int len)
+{
+ exit(-1);
+}
+
+int arch_decode_instruction(struct objtool_file *file, const struct section *sec,
+ unsigned long offset, unsigned int maxlen,
+ struct instruction *insn)
+{
+ u32 i = *((u32 *)(sec->data->d_buf + offset));
+
+ insn->len = 4;
+
+ /*
+ * These are the bare minimum needed for static branch detection and
+ * checksum calculations.
+ */
+ if (i == 0xd503201f || i == 0x2a1f03f7) {
+ /* For static branches */
+ insn->type = INSN_NOP;
+ } else if ((i & 0xfc000000) == 0x14000000) {
+ /* For static branches and intra-TU sibling calls */
+ insn->type = INSN_JUMP_UNCONDITIONAL;
+ insn->immediate = sign_extend64(i & 0x03ffffff, 25);
+ } else if ((i & 0xfc000000) == 0x94000000) {
+ /* For intra-TU calls */
+ insn->type = INSN_CALL;
+ insn->immediate = sign_extend64(i & 0x03ffffff, 25);
+ } else if ((i & 0xff000000) == 0x54000000) {
+ /* For intra-TU conditional sibling calls */
+ insn->type = INSN_JUMP_CONDITIONAL;
+ insn->immediate = sign_extend64((i & 0xffffe0) >> 5, 18);
+ } else {
+ insn->type = INSN_OTHER;
+ }
+
+ return 0;
+}
+
+u64 arch_adjusted_addend(struct reloc *reloc)
+{
+ return reloc_addend(reloc);
+}
+
+unsigned long arch_jump_destination(struct instruction *insn)
+{
+ return insn->offset + (insn->immediate << 2);
+}
+
+bool arch_pc_relative_reloc(struct reloc *reloc)
+{
+ return false;
+}
+
+void arch_initial_func_cfi_state(struct cfi_init_state *state)
+{
+ state->cfa.base = CFI_UNDEFINED;
+}
+
+unsigned int arch_reloc_size(struct reloc *reloc)
+{
+ switch (reloc_type(reloc)) {
+ case R_AARCH64_ABS64:
+ case R_AARCH64_PREL64:
+ return 8;
+ default:
+ return 4;
+ }
+}
+
+#ifdef DISAS
+int arch_disas_info_init(struct disassemble_info *dinfo)
+{
+ return disas_info_init(dinfo, bfd_arch_aarch64,
+ bfd_mach_arm_unknown, bfd_mach_aarch64,
+ NULL);
+}
+#endif /* DISAS */
diff --git a/tools/objtool/arch/arm64/include/arch/cfi_regs.h b/tools/objtool/arch/arm64/include/arch/cfi_regs.h
new file mode 100644
index 000000000000..49c81cbb6646
--- /dev/null
+++ b/tools/objtool/arch/arm64/include/arch/cfi_regs.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef _OBJTOOL_ARCH_CFI_REGS_H
+#define _OBJTOOL_ARCH_CFI_REGS_H
+
+/* These aren't actually used for arm64 */
+#define CFI_BP 0
+#define CFI_SP 0
+#define CFI_RA 0
+#define CFI_NUM_REGS 2
+
+#endif /* _OBJTOOL_ARCH_CFI_REGS_H */
diff --git a/tools/objtool/arch/arm64/include/arch/elf.h b/tools/objtool/arch/arm64/include/arch/elf.h
new file mode 100644
index 000000000000..80a1bc479930
--- /dev/null
+++ b/tools/objtool/arch/arm64/include/arch/elf.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef _OBJTOOL_ARCH_ELF_H
+#define _OBJTOOL_ARCH_ELF_H
+
+#define R_NONE R_AARCH64_NONE
+#define R_ABS64 R_AARCH64_ABS64
+#define R_ABS32 R_AARCH64_ABS32
+#define R_DATA32 R_AARCH64_PREL32
+#define R_DATA64 R_AARCH64_PREL64
+#define R_TEXT32 R_AARCH64_PREL32
+#define R_TEXT64 R_AARCH64_PREL64
+
+#endif /* _OBJTOOL_ARCH_ELF_H */
diff --git a/tools/objtool/arch/arm64/include/arch/special.h b/tools/objtool/arch/arm64/include/arch/special.h
new file mode 100644
index 000000000000..8ae804a83ea4
--- /dev/null
+++ b/tools/objtool/arch/arm64/include/arch/special.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef _OBJTOOL_ARCH_SPECIAL_H
+#define _OBJTOOL_ARCH_SPECIAL_H
+
+#define EX_ENTRY_SIZE 12
+#define EX_ORIG_OFFSET 0
+#define EX_NEW_OFFSET 4
+
+#define JUMP_ENTRY_SIZE 16
+#define JUMP_ORIG_OFFSET 0
+#define JUMP_NEW_OFFSET 4
+#define JUMP_KEY_OFFSET 8
+
+#define ALT_ENTRY_SIZE 12
+#define ALT_ORIG_OFFSET 0
+#define ALT_NEW_OFFSET 4
+#define ALT_FEATURE_OFFSET 8
+#define ALT_ORIG_LEN_OFFSET 10
+#define ALT_NEW_LEN_OFFSET 11
+
+#endif /* _OBJTOOL_ARCH_SPECIAL_H */
diff --git a/tools/objtool/arch/arm64/special.c b/tools/objtool/arch/arm64/special.c
new file mode 100644
index 000000000000..3c2b83d94939
--- /dev/null
+++ b/tools/objtool/arch/arm64/special.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include <objtool/special.h>
+
+bool arch_support_alt_relocation(struct special_alt *special_alt,
+ struct instruction *insn,
+ struct reloc *reloc)
+{
+ return false;
+}
+
+struct reloc *arch_find_switch_table(struct objtool_file *file,
+ struct instruction *insn,
+ unsigned long *table_size)
+{
+ return NULL;
+}
+
+const char *arch_cpu_feature_name(int feature_number)
+{
+ return NULL;
+}
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 12/12] klp-build: Support cross-compilation
2026-03-17 22:51 [PATCH v2 00/12] objtool/arm64: Port klp-build to arm64 Josh Poimboeuf
` (10 preceding siblings ...)
2026-03-17 22:51 ` [PATCH v2 11/12] objtool: Introduce objtool for arm64 Josh Poimboeuf
@ 2026-03-17 22:51 ` Josh Poimboeuf
2026-03-19 4:13 ` [PATCH v2 00/12] objtool/arm64: Port klp-build to arm64 Josh Poimboeuf
12 siblings, 0 replies; 16+ messages in thread
From: Josh Poimboeuf @ 2026-03-17 22:51 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Song Liu, Catalin Marinas, Will Deacon, linux-arm-kernel,
Mark Rutland, Nathan Chancellor, Nicolas Schier, Herbert Xu
Add support for cross-compilation. The user must export ARCH, and
either CROSS_COMPILE or LLVM as needed.
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
---
scripts/livepatch/klp-build | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/scripts/livepatch/klp-build b/scripts/livepatch/klp-build
index 809e198a561d..b6c057e2120f 100755
--- a/scripts/livepatch/klp-build
+++ b/scripts/livepatch/klp-build
@@ -404,6 +404,14 @@ validate_patches() {
revert_patches
}
+cross_compile_init() {
+ if [[ -v LLVM ]]; then
+ OBJCOPY=llvm-objcopy
+ else
+ OBJCOPY="${CROSS_COMPILE:-}objcopy"
+ fi
+}
+
do_init() {
# We're not yet smart enough to handle anything other than in-tree
# builds in pwd.
@@ -420,6 +428,7 @@ do_init() {
validate_config
set_module_name
set_kernelversion
+ cross_compile_init
}
# Refresh the patch hunk headers, specifically the line numbers and counts.
@@ -783,7 +792,7 @@ build_patch_module() {
cp -f "$kmod_file" "$kmod_file.orig"
# Work around issue where slight .config change makes corrupt BTF
- objcopy --remove-section=.BTF "$kmod_file"
+ "$OBJCOPY" --remove-section=.BTF "$kmod_file"
# Fix (and work around) linker wreckage for klp syms / relocs
"$SRC/tools/objtool/objtool" klp post-link "$kmod_file" || die "objtool klp post-link failed"
--
2.53.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v2 07/12] kbuild: Only run objtool if there is at least one command
2026-03-17 22:51 ` [PATCH v2 07/12] kbuild: Only run objtool if there is at least one command Josh Poimboeuf
@ 2026-03-18 19:54 ` Nicolas Schier
2026-03-19 0:49 ` Josh Poimboeuf
0 siblings, 1 reply; 16+ messages in thread
From: Nicolas Schier @ 2026-03-18 19:54 UTC (permalink / raw)
To: Josh Poimboeuf
Cc: x86, linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Song Liu, Catalin Marinas, Will Deacon, linux-arm-kernel,
Mark Rutland, Nathan Chancellor, Herbert Xu
On Tue, Mar 17, 2026 at 03:51:07PM -0700, Josh Poimboeuf wrote:
> Split the objtool args into commands and options, such that if no
> commands have been enabled, objtool doesn't run.
>
> This is in preparation in enabling objtool and klp-build for arm64.
>
> Reviewed-by: Nathan Chancellor <nathan@kernel.org>
> Tested-by: Nathan Chancellor <nathan@kernel.org>
> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
> ---
> arch/x86/boot/startup/Makefile | 2 +-
> scripts/Makefile.build | 4 +--
> scripts/Makefile.lib | 46 ++++++++++++++++++----------------
> scripts/Makefile.vmlinux_o | 15 ++++-------
> 4 files changed, 33 insertions(+), 34 deletions(-)
>
[...]
> diff --git a/scripts/Makefile.build b/scripts/Makefile.build
> index 3652b85be545..8a1bdfdb2fdb 100644
> --- a/scripts/Makefile.build
> +++ b/scripts/Makefile.build
> @@ -277,7 +277,7 @@ endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
> is-standard-object = $(if $(filter-out y%, $(OBJECT_FILES_NON_STANDARD_$(target-stem).o)$(OBJECT_FILES_NON_STANDARD)n),$(is-kernel-object))
>
> ifdef CONFIG_OBJTOOL
> -$(obj)/%.o: private objtool-enabled = $(if $(is-standard-object),$(if $(delay-objtool),$(is-single-obj-m),y))
> +$(obj)/%.o: private objtool-enabled = $(if $(is-standard-object),$(if $(objtool-cmds-y),$(if $(delay-objtool),$(is-single-obj-m),y)))
Please use $(and a,b,c) instead of multiple nested $(if $(a),$(if
$(b),$(c)); as the last variable (is-single-obj-m) is 'y' or empty, the final 'y' can be
left-out:
$(obj)/%.o: private objtool-enabled = $(and $(is-standard-object),$(objtool-cmds-y),$(delay-objtool),$(is-single-obj-m))
> endif
>
> ifneq ($(findstring 1, $(KBUILD_EXTRA_WARN)),)
> @@ -501,7 +501,7 @@ define rule_ld_multi_m
> $(call cmd,gen_objtooldep)
> endef
>
> -$(multi-obj-m): private objtool-enabled := $(delay-objtool)
> +$(multi-obj-m): private objtool-enabled := $(if $(objtool-cmds-y),$(delay-objtool))
Could be changed to $(and), too; but personally I think the $(if) is
easier to parse at once.
Reviewed-by: Nicolas Schier <nsc@kernel.org>
--
Nicolas
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 07/12] kbuild: Only run objtool if there is at least one command
2026-03-18 19:54 ` Nicolas Schier
@ 2026-03-19 0:49 ` Josh Poimboeuf
0 siblings, 0 replies; 16+ messages in thread
From: Josh Poimboeuf @ 2026-03-19 0:49 UTC (permalink / raw)
To: Nicolas Schier
Cc: x86, linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Song Liu, Catalin Marinas, Will Deacon, linux-arm-kernel,
Mark Rutland, Nathan Chancellor, Herbert Xu
On Wed, Mar 18, 2026 at 08:54:31PM +0100, Nicolas Schier wrote:
> On Tue, Mar 17, 2026 at 03:51:07PM -0700, Josh Poimboeuf wrote:
> > Split the objtool args into commands and options, such that if no
> > commands have been enabled, objtool doesn't run.
> >
> > This is in preparation in enabling objtool and klp-build for arm64.
> >
> > Reviewed-by: Nathan Chancellor <nathan@kernel.org>
> > Tested-by: Nathan Chancellor <nathan@kernel.org>
> > Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
> > ---
> > arch/x86/boot/startup/Makefile | 2 +-
> > scripts/Makefile.build | 4 +--
> > scripts/Makefile.lib | 46 ++++++++++++++++++----------------
> > scripts/Makefile.vmlinux_o | 15 ++++-------
> > 4 files changed, 33 insertions(+), 34 deletions(-)
> >
> [...]
> > diff --git a/scripts/Makefile.build b/scripts/Makefile.build
> > index 3652b85be545..8a1bdfdb2fdb 100644
> > --- a/scripts/Makefile.build
> > +++ b/scripts/Makefile.build
> > @@ -277,7 +277,7 @@ endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
> > is-standard-object = $(if $(filter-out y%, $(OBJECT_FILES_NON_STANDARD_$(target-stem).o)$(OBJECT_FILES_NON_STANDARD)n),$(is-kernel-object))
> >
> > ifdef CONFIG_OBJTOOL
> > -$(obj)/%.o: private objtool-enabled = $(if $(is-standard-object),$(if $(delay-objtool),$(is-single-obj-m),y))
> > +$(obj)/%.o: private objtool-enabled = $(if $(is-standard-object),$(if $(objtool-cmds-y),$(if $(delay-objtool),$(is-single-obj-m),y)))
>
> Please use $(and a,b,c) instead of multiple nested $(if $(a),$(if
> $(b),$(c)); as the last variable (is-single-obj-m) is 'y' or empty, the final 'y' can be
> left-out:
>
> $(obj)/%.o: private objtool-enabled = $(and $(is-standard-object),$(objtool-cmds-y),$(delay-objtool),$(is-single-obj-m))
I believe that would break the !delay-objtool case. The logic needs to
be something like:
if (is-standard-object && objtool-cmds-y) {
if (delay-objtool) {
// for delay-objtool, only enable objtool for single-object modules
$(is-single-obj-m)
} else {
// for !delay-objtool, always enable objtool
y
}
}
so maybe something like this?
$(obj)/%.o: private objtool-enabled = $(and $(is-standard-object),$(objtool-cmds-y),$(if $(delay-objtool),$(is-single-obj-m),y))
--
Josh
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 00/12] objtool/arm64: Port klp-build to arm64
2026-03-17 22:51 [PATCH v2 00/12] objtool/arm64: Port klp-build to arm64 Josh Poimboeuf
` (11 preceding siblings ...)
2026-03-17 22:51 ` [PATCH v2 12/12] klp-build: Support cross-compilation Josh Poimboeuf
@ 2026-03-19 4:13 ` Josh Poimboeuf
12 siblings, 0 replies; 16+ messages in thread
From: Josh Poimboeuf @ 2026-03-19 4:13 UTC (permalink / raw)
To: x86
Cc: linux-kernel, live-patching, Peter Zijlstra, Joe Lawrence,
Song Liu, Catalin Marinas, Will Deacon, linux-arm-kernel,
Mark Rutland, Nathan Chancellor, Nicolas Schier, Herbert Xu
On Tue, Mar 17, 2026 at 03:51:00PM -0700, Josh Poimboeuf wrote:
> v2:
> - patches 1-2 were merged, rebase on tip/master
> - improve commit message for "objtool: Extricate checksum calculation from validate_branch()"
> - add review tags
>
> v1: https://lore.kernel.org/cover.1772681234.git.jpoimboe@kernel.org
>
> Port objtool and the klp-build tooling (for building livepatch modules)
> to arm64.
>
> Note this doesn't bring all the objtool bells and whistles to arm64, nor
> any of the CFG reverse engineering. This only adds the bare minimum
> needed for 'objtool --checksum'.
>
> And note that objtool still doesn't get enabled at all for normal arm64
> kernel builds, so this doesn't affect any users other than those running
> klp-build directly.
The Sashiko AI thing found some bugs, so it might be wise to hold off on
any review or testing of this until I get v3 out.
--
Josh
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2026-03-19 4:13 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-17 22:51 [PATCH v2 00/12] objtool/arm64: Port klp-build to arm64 Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 01/12] arm64: Annotate intra-function calls Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 02/12] arm64: head: Move boot header to .head.data Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 03/12] arm64: Fix EFI linking with -fdata-sections Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 04/12] crypto: arm64: Move data to .rodata Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 05/12] objtool: Extricate checksum calculation from validate_branch() Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 06/12] objtool: Allow setting --mnop without --mcount Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 07/12] kbuild: Only run objtool if there is at least one command Josh Poimboeuf
2026-03-18 19:54 ` Nicolas Schier
2026-03-19 0:49 ` Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 08/12] objtool: Ignore jumps to the end of the function for non-CFG arches Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 09/12] objtool: Allow empty alternatives Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 10/12] objtool: Reuse consecutive string references Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 11/12] objtool: Introduce objtool for arm64 Josh Poimboeuf
2026-03-17 22:51 ` [PATCH v2 12/12] klp-build: Support cross-compilation Josh Poimboeuf
2026-03-19 4:13 ` [PATCH v2 00/12] objtool/arm64: Port klp-build to arm64 Josh Poimboeuf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox