* [PATCH 6.6 044/175] scripts/sorttable: Remove unused macro defines
[not found] <20260702155115.766838875@linuxfoundation.org>
@ 2026-07-02 16:19 ` Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 045/175] scripts/sorttable: Remove unused write functions Greg Kroah-Hartman
` (19 subsequent siblings)
20 siblings, 0 replies; 21+ messages in thread
From: Greg Kroah-Hartman @ 2026-07-02 16:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, bpf, Masami Hiramatsu, Mark Rutland,
Mathieu Desnoyers, Andrew Morton, Peter Zijlstra, Linus Torvalds,
Masahiro Yamada, Nathan Chancellor, Nicolas Schier, Zheng Yejian,
Martin Kelly, Christophe Leroy, Josh Poimboeuf,
Steven Rostedt (Google), Andrey Grodzovsky
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 28b24394c6e9a3166fcb4480cba054562526657c ]
The code of sorttable.h was copied from the recordmcount.h which defined
a bunch of Elf MACROs so that they could be used between 32bit and 64bit
functions. But there's several MACROs that sorttable.h does not use but
was copied over. Remove them to clean up the code.
Cc: bpf <bpf@vger.kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: Zheng Yejian <zhengyejian1@huawei.com>
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Link: https://lore.kernel.org/20250105162344.128870118@goodmis.org
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
scripts/sorttable.h | 27 ---------------------------
1 file changed, 27 deletions(-)
--- a/scripts/sorttable.h
+++ b/scripts/sorttable.h
@@ -27,19 +27,10 @@
#undef Elf_Ehdr
#undef Elf_Shdr
#undef Elf_Rel
-#undef Elf_Rela
#undef Elf_Sym
-#undef ELF_R_SYM
-#undef Elf_r_sym
-#undef ELF_R_INFO
-#undef Elf_r_info
-#undef ELF_ST_BIND
#undef ELF_ST_TYPE
-#undef fn_ELF_R_SYM
-#undef fn_ELF_R_INFO
#undef uint_t
#undef _r
-#undef _w
#ifdef SORTTABLE_64
# define extable_ent_size 16
@@ -52,19 +43,10 @@
# define Elf_Ehdr Elf64_Ehdr
# define Elf_Shdr Elf64_Shdr
# define Elf_Rel Elf64_Rel
-# define Elf_Rela Elf64_Rela
# define Elf_Sym Elf64_Sym
-# define ELF_R_SYM ELF64_R_SYM
-# define Elf_r_sym Elf64_r_sym
-# define ELF_R_INFO ELF64_R_INFO
-# define Elf_r_info Elf64_r_info
-# define ELF_ST_BIND ELF64_ST_BIND
# define ELF_ST_TYPE ELF64_ST_TYPE
-# define fn_ELF_R_SYM fn_ELF64_R_SYM
-# define fn_ELF_R_INFO fn_ELF64_R_INFO
# define uint_t uint64_t
# define _r r8
-# define _w w8
#else
# define extable_ent_size 8
# define compare_extable compare_extable_32
@@ -76,19 +58,10 @@
# define Elf_Ehdr Elf32_Ehdr
# define Elf_Shdr Elf32_Shdr
# define Elf_Rel Elf32_Rel
-# define Elf_Rela Elf32_Rela
# define Elf_Sym Elf32_Sym
-# define ELF_R_SYM ELF32_R_SYM
-# define Elf_r_sym Elf32_r_sym
-# define ELF_R_INFO ELF32_R_INFO
-# define Elf_r_info Elf32_r_info
-# define ELF_ST_BIND ELF32_ST_BIND
# define ELF_ST_TYPE ELF32_ST_TYPE
-# define fn_ELF_R_SYM fn_ELF32_R_SYM
-# define fn_ELF_R_INFO fn_ELF32_R_INFO
# define uint_t uint32_t
# define _r r
-# define _w w
#endif
#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 6.6 045/175] scripts/sorttable: Remove unused write functions
[not found] <20260702155115.766838875@linuxfoundation.org>
2026-07-02 16:19 ` [PATCH 6.6 044/175] scripts/sorttable: Remove unused macro defines Greg Kroah-Hartman
@ 2026-07-02 16:19 ` Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 046/175] scripts/sorttable: Remove unneeded Elf_Rel Greg Kroah-Hartman
` (18 subsequent siblings)
20 siblings, 0 replies; 21+ messages in thread
From: Greg Kroah-Hartman @ 2026-07-02 16:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, bpf, Masami Hiramatsu, Mark Rutland,
Mathieu Desnoyers, Andrew Morton, Peter Zijlstra, Linus Torvalds,
Masahiro Yamada, Nathan Chancellor, Nicolas Schier, Zheng Yejian,
Martin Kelly, Christophe Leroy, Josh Poimboeuf,
Steven Rostedt (Google), Andrey Grodzovsky
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 4f48a28b37d594dab38092514a42ae9f4b781553 ]
The code of sorttable.h was copied from the recordmcount.h which defined
various write functions for different sizes (2, 4, 8 byte lengths). But
sorttable only uses the 4 byte writes. Remove the extra versions as they
are not used.
Cc: bpf <bpf@vger.kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: Zheng Yejian <zhengyejian1@huawei.com>
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Link: https://lore.kernel.org/20250105162344.314385504@goodmis.org
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
scripts/sorttable.c | 26 --------------------------
1 file changed, 26 deletions(-)
--- a/scripts/sorttable.c
+++ b/scripts/sorttable.c
@@ -68,8 +68,6 @@ static uint32_t (*r)(const uint32_t *);
static uint16_t (*r2)(const uint16_t *);
static uint64_t (*r8)(const uint64_t *);
static void (*w)(uint32_t, uint32_t *);
-static void (*w2)(uint16_t, uint16_t *);
-static void (*w8)(uint64_t, uint64_t *);
typedef void (*table_sort_t)(char *, int);
/*
@@ -146,31 +144,11 @@ static void wbe(uint32_t val, uint32_t *
put_unaligned_be32(val, x);
}
-static void w2be(uint16_t val, uint16_t *x)
-{
- put_unaligned_be16(val, x);
-}
-
-static void w8be(uint64_t val, uint64_t *x)
-{
- put_unaligned_be64(val, x);
-}
-
static void wle(uint32_t val, uint32_t *x)
{
put_unaligned_le32(val, x);
}
-static void w2le(uint16_t val, uint16_t *x)
-{
- put_unaligned_le16(val, x);
-}
-
-static void w8le(uint64_t val, uint64_t *x)
-{
- put_unaligned_le64(val, x);
-}
-
/*
* Move reserved section indices SHN_LORESERVE..SHN_HIRESERVE out of
* the way to -256..-1, to avoid conflicting with real section
@@ -277,16 +255,12 @@ static int do_file(char const *const fna
r2 = r2le;
r8 = r8le;
w = wle;
- w2 = w2le;
- w8 = w8le;
break;
case ELFDATA2MSB:
r = rbe;
r2 = r2be;
r8 = r8be;
w = wbe;
- w2 = w2be;
- w8 = w8be;
break;
default:
fprintf(stderr, "unrecognized ELF data encoding %d: %s\n",
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 6.6 046/175] scripts/sorttable: Remove unneeded Elf_Rel
[not found] <20260702155115.766838875@linuxfoundation.org>
2026-07-02 16:19 ` [PATCH 6.6 044/175] scripts/sorttable: Remove unused macro defines Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 045/175] scripts/sorttable: Remove unused write functions Greg Kroah-Hartman
@ 2026-07-02 16:19 ` Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 047/175] scripts/sorttable: Have the ORC code use the _r() functions to read Greg Kroah-Hartman
` (17 subsequent siblings)
20 siblings, 0 replies; 21+ messages in thread
From: Greg Kroah-Hartman @ 2026-07-02 16:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, bpf, Masami Hiramatsu, Mark Rutland,
Mathieu Desnoyers, Andrew Morton, Peter Zijlstra, Linus Torvalds,
Masahiro Yamada, Nathan Chancellor, Nicolas Schier, Zheng Yejian,
Martin Kelly, Christophe Leroy, Josh Poimboeuf,
Steven Rostedt (Google), Andrey Grodzovsky
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 6f2c2f93a190467cebd6ebd03feb49514fead5ca ]
The code had references to initialize the Elf_Rel relocation tables, but
it was never used. Remove it.
Cc: bpf <bpf@vger.kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: Zheng Yejian <zhengyejian1@huawei.com>
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Link: https://lore.kernel.org/20250105162344.515342233@goodmis.org
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
scripts/sorttable.h | 23 ++---------------------
1 file changed, 2 insertions(+), 21 deletions(-)
--- a/scripts/sorttable.h
+++ b/scripts/sorttable.h
@@ -26,7 +26,6 @@
#undef Elf_Addr
#undef Elf_Ehdr
#undef Elf_Shdr
-#undef Elf_Rel
#undef Elf_Sym
#undef ELF_ST_TYPE
#undef uint_t
@@ -42,7 +41,6 @@
# define Elf_Addr Elf64_Addr
# define Elf_Ehdr Elf64_Ehdr
# define Elf_Shdr Elf64_Shdr
-# define Elf_Rel Elf64_Rel
# define Elf_Sym Elf64_Sym
# define ELF_ST_TYPE ELF64_ST_TYPE
# define uint_t uint64_t
@@ -57,7 +55,6 @@
# define Elf_Addr Elf32_Addr
# define Elf_Ehdr Elf32_Ehdr
# define Elf_Shdr Elf32_Shdr
-# define Elf_Rel Elf32_Rel
# define Elf_Sym Elf32_Sym
# define ELF_ST_TYPE ELF32_ST_TYPE
# define uint_t uint32_t
@@ -248,14 +245,10 @@ static int do_sort(Elf_Ehdr *ehdr,
Elf32_Word *symtab_shndx = NULL;
Elf_Sym *sort_needed_sym = NULL;
Elf_Shdr *sort_needed_sec;
- Elf_Rel *relocs = NULL;
- int relocs_size = 0;
uint32_t *sort_needed_loc;
const char *secstrings;
const char *strtab;
char *extab_image;
- int extab_index = 0;
- int i;
int idx;
unsigned int shnum;
unsigned int shstrndx;
@@ -279,23 +272,15 @@ static int do_sort(Elf_Ehdr *ehdr,
if (shnum == SHN_UNDEF)
shnum = _r(&shdr[0].sh_size);
- for (i = 0, s = shdr; s < shdr + shnum; i++, s++) {
+ for (s = shdr; s < shdr + shnum; s++) {
idx = r(&s->sh_name);
- if (!strcmp(secstrings + idx, "__ex_table")) {
+ if (!strcmp(secstrings + idx, "__ex_table"))
extab_sec = s;
- extab_index = i;
- }
if (!strcmp(secstrings + idx, ".symtab"))
symtab_sec = s;
if (!strcmp(secstrings + idx, ".strtab"))
strtab_sec = s;
- if ((r(&s->sh_type) == SHT_REL ||
- r(&s->sh_type) == SHT_RELA) &&
- r(&s->sh_info) == extab_index) {
- relocs = (void *)ehdr + _r(&s->sh_offset);
- relocs_size = _r(&s->sh_size);
- }
if (r(&s->sh_type) == SHT_SYMTAB_SHNDX)
symtab_shndx = (Elf32_Word *)((const char *)ehdr +
_r(&s->sh_offset));
@@ -397,10 +382,6 @@ static int do_sort(Elf_Ehdr *ehdr,
extable_ent_size, compare_extable);
}
- /* If there were relocations, we no longer need them. */
- if (relocs)
- memset(relocs, 0, relocs_size);
-
/* find the flag main_extable_sort_needed */
for (sym = (void *)ehdr + _r(&symtab_sec->sh_offset);
sym < sym + _r(&symtab_sec->sh_size) / sizeof(Elf_Sym);
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 6.6 047/175] scripts/sorttable: Have the ORC code use the _r() functions to read
[not found] <20260702155115.766838875@linuxfoundation.org>
` (2 preceding siblings ...)
2026-07-02 16:19 ` [PATCH 6.6 046/175] scripts/sorttable: Remove unneeded Elf_Rel Greg Kroah-Hartman
@ 2026-07-02 16:19 ` Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 048/175] scripts/sorttable: Make compare_extable() into two functions Greg Kroah-Hartman
` (16 subsequent siblings)
20 siblings, 0 replies; 21+ messages in thread
From: Greg Kroah-Hartman @ 2026-07-02 16:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, bpf, Masami Hiramatsu, Mark Rutland,
Mathieu Desnoyers, Andrew Morton, Peter Zijlstra, Linus Torvalds,
Masahiro Yamada, Nathan Chancellor, Nicolas Schier, Zheng Yejian,
Martin Kelly, Christophe Leroy, Josh Poimboeuf,
Steven Rostedt (Google), Andrey Grodzovsky
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 66990c003306c240d570b3ba274ec4f68cf18c91 ]
The ORC code reads the section information directly from the file. This
currently works because the default read function is for 64bit little
endian machines. But if for some reason that ever changes, this will
break. Instead of having a surprise breakage, use the _r() functions that
will read the values from the file properly.
Cc: bpf <bpf@vger.kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: Zheng Yejian <zhengyejian1@huawei.com>
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Link: https://lore.kernel.org/20250105162344.721480386@goodmis.org
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
scripts/sorttable.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/scripts/sorttable.h
+++ b/scripts/sorttable.h
@@ -299,14 +299,14 @@ static int do_sort(Elf_Ehdr *ehdr,
#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
/* locate the ORC unwind tables */
if (!strcmp(secstrings + idx, ".orc_unwind_ip")) {
- orc_ip_size = s->sh_size;
+ orc_ip_size = _r(&s->sh_size);
g_orc_ip_table = (int *)((void *)ehdr +
- s->sh_offset);
+ _r(&s->sh_offset));
}
if (!strcmp(secstrings + idx, ".orc_unwind")) {
- orc_size = s->sh_size;
+ orc_size = _r(&s->sh_size);
g_orc_table = (struct orc_entry *)((void *)ehdr +
- s->sh_offset);
+ _r(&s->sh_offset));
}
#endif
} /* for loop */
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 6.6 048/175] scripts/sorttable: Make compare_extable() into two functions
[not found] <20260702155115.766838875@linuxfoundation.org>
` (3 preceding siblings ...)
2026-07-02 16:19 ` [PATCH 6.6 047/175] scripts/sorttable: Have the ORC code use the _r() functions to read Greg Kroah-Hartman
@ 2026-07-02 16:19 ` Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 049/175] scripts/sorttable: Convert Elf_Ehdr to union Greg Kroah-Hartman
` (15 subsequent siblings)
20 siblings, 0 replies; 21+ messages in thread
From: Greg Kroah-Hartman @ 2026-07-02 16:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, bpf, Masami Hiramatsu, Mark Rutland,
Mathieu Desnoyers, Andrew Morton, Peter Zijlstra, Linus Torvalds,
Masahiro Yamada, Nathan Chancellor, Nicolas Schier, Zheng Yejian,
Martin Kelly, Christophe Leroy, Josh Poimboeuf,
Steven Rostedt (Google), Andrey Grodzovsky
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 7ffc0d0819f438779ed592e2e2e3576f43ce14f0 ]
Instead of having the compare_extable() part of the sorttable.h header
where it get's defined twice, since it is a very simple function, just
define it twice in sorttable.c, and then it can use the proper read
functions for the word size and endianess and the Elf_Addr macro can be
removed from sorttable.h.
Also add a micro optimization. Instead of:
if (a < b)
return -1;
if (a > b)
return 1;
return 0;
That can be shorten to:
if (a < b)
return -1;
return a > b;
Cc: bpf <bpf@vger.kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: Zheng Yejian <zhengyejian1@huawei.com>
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Link: https://lore.kernel.org/20250105162344.945299671@goodmis.org
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
scripts/sorttable.c | 20 ++++++++++++++++++++
scripts/sorttable.h | 14 --------------
2 files changed, 20 insertions(+), 14 deletions(-)
--- a/scripts/sorttable.c
+++ b/scripts/sorttable.c
@@ -173,6 +173,26 @@ static inline unsigned int get_secindex(
return r(&symtab_shndx_start[sym_offs]);
}
+static int compare_extable_32(const void *a, const void *b)
+{
+ Elf32_Addr av = r(a);
+ Elf32_Addr bv = r(b);
+
+ if (av < bv)
+ return -1;
+ return av > bv;
+}
+
+static int compare_extable_64(const void *a, const void *b)
+{
+ Elf64_Addr av = r8(a);
+ Elf64_Addr bv = r8(b);
+
+ if (av < bv)
+ return -1;
+ return av > bv;
+}
+
/* 32 bit and 64 bit are very similar */
#include "sorttable.h"
#define SORTTABLE_64
--- a/scripts/sorttable.h
+++ b/scripts/sorttable.h
@@ -23,7 +23,6 @@
#undef sort_mcount_loc
#undef elf_mcount_loc
#undef do_sort
-#undef Elf_Addr
#undef Elf_Ehdr
#undef Elf_Shdr
#undef Elf_Sym
@@ -38,7 +37,6 @@
# define sort_mcount_loc sort_mcount_loc_64
# define elf_mcount_loc elf_mcount_loc_64
# define do_sort do_sort_64
-# define Elf_Addr Elf64_Addr
# define Elf_Ehdr Elf64_Ehdr
# define Elf_Shdr Elf64_Shdr
# define Elf_Sym Elf64_Sym
@@ -52,7 +50,6 @@
# define sort_mcount_loc sort_mcount_loc_32
# define elf_mcount_loc elf_mcount_loc_32
# define do_sort do_sort_32
-# define Elf_Addr Elf32_Addr
# define Elf_Ehdr Elf32_Ehdr
# define Elf_Shdr Elf32_Shdr
# define Elf_Sym Elf32_Sym
@@ -160,17 +157,6 @@ static void *sort_orctable(void *arg)
}
#endif
-static int compare_extable(const void *a, const void *b)
-{
- Elf_Addr av = _r(a);
- Elf_Addr bv = _r(b);
-
- if (av < bv)
- return -1;
- if (av > bv)
- return 1;
- return 0;
-}
#ifdef MCOUNT_SORT_ENABLED
pthread_t mcount_sort_thread;
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 6.6 049/175] scripts/sorttable: Convert Elf_Ehdr to union
[not found] <20260702155115.766838875@linuxfoundation.org>
` (4 preceding siblings ...)
2026-07-02 16:19 ` [PATCH 6.6 048/175] scripts/sorttable: Make compare_extable() into two functions Greg Kroah-Hartman
@ 2026-07-02 16:19 ` Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 050/175] scripts/sorttable: Replace Elf_Shdr Macro with a union Greg Kroah-Hartman
` (14 subsequent siblings)
20 siblings, 0 replies; 21+ messages in thread
From: Greg Kroah-Hartman @ 2026-07-02 16:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, bpf, Masami Hiramatsu, Mark Rutland,
Mathieu Desnoyers, Andrew Morton, Peter Zijlstra, Linus Torvalds,
Masahiro Yamada, Nathan Chancellor, Nicolas Schier, Zheng Yejian,
Martin Kelly, Christophe Leroy, Josh Poimboeuf,
Steven Rostedt (Google), Andrey Grodzovsky
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 157fb5b3cfd2cb5950314f926a76e567fc1921c5 ]
In order to remove the double #include of sorttable.h for 64 and 32 bit
to create duplicate functions for both, replace the Elf_Ehdr macro with a
union that defines both Elf64_Ehdr and Elf32_Ehdr, with field e64 for the
64bit version, and e32 for the 32bit version.
Then a macro etype can be used instead to get to the proper value.
This will eventually be replaced with just single functions that can
handle both 32bit and 64bit ELF parsing.
Cc: bpf <bpf@vger.kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: Zheng Yejian <zhengyejian1@huawei.com>
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Link: https://lore.kernel.org/20250105162345.148224465@goodmis.org
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
scripts/sorttable.c | 36 ++++++++++++++++++++----------------
scripts/sorttable.h | 12 ++++++------
2 files changed, 26 insertions(+), 22 deletions(-)
--- a/scripts/sorttable.c
+++ b/scripts/sorttable.c
@@ -64,6 +64,11 @@
#define EM_LOONGARCH 258
#endif
+typedef union {
+ Elf32_Ehdr e32;
+ Elf64_Ehdr e64;
+} Elf_Ehdr;
+
static uint32_t (*r)(const uint32_t *);
static uint16_t (*r2)(const uint16_t *);
static uint64_t (*r8)(const uint64_t *);
@@ -266,10 +271,10 @@ static void sort_relative_table_with_dat
static int do_file(char const *const fname, void *addr)
{
int rc = -1;
- Elf32_Ehdr *ehdr = addr;
+ Elf_Ehdr *ehdr = addr;
table_sort_t custom_sort = NULL;
- switch (ehdr->e_ident[EI_DATA]) {
+ switch (ehdr->e32.e_ident[EI_DATA]) {
case ELFDATA2LSB:
r = rle;
r2 = r2le;
@@ -284,18 +289,18 @@ static int do_file(char const *const fna
break;
default:
fprintf(stderr, "unrecognized ELF data encoding %d: %s\n",
- ehdr->e_ident[EI_DATA], fname);
+ ehdr->e32.e_ident[EI_DATA], fname);
return -1;
}
- if (memcmp(ELFMAG, ehdr->e_ident, SELFMAG) != 0 ||
- (r2(&ehdr->e_type) != ET_EXEC && r2(&ehdr->e_type) != ET_DYN) ||
- ehdr->e_ident[EI_VERSION] != EV_CURRENT) {
+ if (memcmp(ELFMAG, ehdr->e32.e_ident, SELFMAG) != 0 ||
+ (r2(&ehdr->e32.e_type) != ET_EXEC && r2(&ehdr->e32.e_type) != ET_DYN) ||
+ ehdr->e32.e_ident[EI_VERSION] != EV_CURRENT) {
fprintf(stderr, "unrecognized ET_EXEC/ET_DYN file %s\n", fname);
return -1;
}
- switch (r2(&ehdr->e_machine)) {
+ switch (r2(&ehdr->e32.e_machine)) {
case EM_386:
case EM_AARCH64:
case EM_LOONGARCH:
@@ -318,14 +323,14 @@ static int do_file(char const *const fna
break;
default:
fprintf(stderr, "unrecognized e_machine %d %s\n",
- r2(&ehdr->e_machine), fname);
+ r2(&ehdr->e32.e_machine), fname);
return -1;
}
- switch (ehdr->e_ident[EI_CLASS]) {
+ switch (ehdr->e32.e_ident[EI_CLASS]) {
case ELFCLASS32:
- if (r2(&ehdr->e_ehsize) != sizeof(Elf32_Ehdr) ||
- r2(&ehdr->e_shentsize) != sizeof(Elf32_Shdr)) {
+ if (r2(&ehdr->e32.e_ehsize) != sizeof(Elf32_Ehdr) ||
+ r2(&ehdr->e32.e_shentsize) != sizeof(Elf32_Shdr)) {
fprintf(stderr,
"unrecognized ET_EXEC/ET_DYN file: %s\n", fname);
break;
@@ -334,20 +339,19 @@ static int do_file(char const *const fna
break;
case ELFCLASS64:
{
- Elf64_Ehdr *const ghdr = (Elf64_Ehdr *)ehdr;
- if (r2(&ghdr->e_ehsize) != sizeof(Elf64_Ehdr) ||
- r2(&ghdr->e_shentsize) != sizeof(Elf64_Shdr)) {
+ if (r2(&ehdr->e64.e_ehsize) != sizeof(Elf64_Ehdr) ||
+ r2(&ehdr->e64.e_shentsize) != sizeof(Elf64_Shdr)) {
fprintf(stderr,
"unrecognized ET_EXEC/ET_DYN file: %s\n",
fname);
break;
}
- rc = do_sort_64(ghdr, fname, custom_sort);
+ rc = do_sort_64(ehdr, fname, custom_sort);
}
break;
default:
fprintf(stderr, "unrecognized ELF class %d %s\n",
- ehdr->e_ident[EI_CLASS], fname);
+ ehdr->e32.e_ident[EI_CLASS], fname);
break;
}
--- a/scripts/sorttable.h
+++ b/scripts/sorttable.h
@@ -23,12 +23,12 @@
#undef sort_mcount_loc
#undef elf_mcount_loc
#undef do_sort
-#undef Elf_Ehdr
#undef Elf_Shdr
#undef Elf_Sym
#undef ELF_ST_TYPE
#undef uint_t
#undef _r
+#undef etype
#ifdef SORTTABLE_64
# define extable_ent_size 16
@@ -37,12 +37,12 @@
# define sort_mcount_loc sort_mcount_loc_64
# define elf_mcount_loc elf_mcount_loc_64
# define do_sort do_sort_64
-# define Elf_Ehdr Elf64_Ehdr
# define Elf_Shdr Elf64_Shdr
# define Elf_Sym Elf64_Sym
# define ELF_ST_TYPE ELF64_ST_TYPE
# define uint_t uint64_t
# define _r r8
+# define etype e64
#else
# define extable_ent_size 8
# define compare_extable compare_extable_32
@@ -50,12 +50,12 @@
# define sort_mcount_loc sort_mcount_loc_32
# define elf_mcount_loc elf_mcount_loc_32
# define do_sort do_sort_32
-# define Elf_Ehdr Elf32_Ehdr
# define Elf_Shdr Elf32_Shdr
# define Elf_Sym Elf32_Sym
# define ELF_ST_TYPE ELF32_ST_TYPE
# define uint_t uint32_t
# define _r r
+# define etype e32
#endif
#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
@@ -222,7 +222,7 @@ static int do_sort(Elf_Ehdr *ehdr,
table_sort_t custom_sort)
{
int rc = -1;
- Elf_Shdr *s, *shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->e_shoff));
+ Elf_Shdr *s, *shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->etype.e_shoff));
Elf_Shdr *strtab_sec = NULL;
Elf_Shdr *symtab_sec = NULL;
Elf_Shdr *extab_sec = NULL;
@@ -249,12 +249,12 @@ static int do_sort(Elf_Ehdr *ehdr,
unsigned int orc_num_entries = 0;
#endif
- shstrndx = r2(&ehdr->e_shstrndx);
+ shstrndx = r2(&ehdr->etype.e_shstrndx);
if (shstrndx == SHN_XINDEX)
shstrndx = r(&shdr[0].sh_link);
secstrings = (const char *)ehdr + _r(&shdr[shstrndx].sh_offset);
- shnum = r2(&ehdr->e_shnum);
+ shnum = r2(&ehdr->etype.e_shnum);
if (shnum == SHN_UNDEF)
shnum = _r(&shdr[0].sh_size);
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 6.6 050/175] scripts/sorttable: Replace Elf_Shdr Macro with a union
[not found] <20260702155115.766838875@linuxfoundation.org>
` (5 preceding siblings ...)
2026-07-02 16:19 ` [PATCH 6.6 049/175] scripts/sorttable: Convert Elf_Ehdr to union Greg Kroah-Hartman
@ 2026-07-02 16:19 ` Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 051/175] scripts/sorttable: Convert Elf_Sym MACRO over to " Greg Kroah-Hartman
` (13 subsequent siblings)
20 siblings, 0 replies; 21+ messages in thread
From: Greg Kroah-Hartman @ 2026-07-02 16:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, bpf, Masami Hiramatsu, Mark Rutland,
Mathieu Desnoyers, Andrew Morton, Peter Zijlstra, Linus Torvalds,
Masahiro Yamada, Nathan Chancellor, Nicolas Schier, Zheng Yejian,
Martin Kelly, Christophe Leroy, Josh Poimboeuf,
Steven Rostedt (Google), Andrey Grodzovsky
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 545f6cf8f4c9a268e0bab2637f1d279679befdbf ]
In order to remove the double #include of sorttable.h for 64 and 32 bit
to create duplicate functions for both, replace the Elf_Shdr macro with a
union that defines both Elf64_Shdr and Elf32_Shdr, with field e64 for the
64bit version, and e32 for the 32bit version.
It can then use the macro etype to get the proper value.
This will eventually be replaced with just single functions that can
handle both 32bit and 64bit ELF parsing.
Cc: bpf <bpf@vger.kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: Zheng Yejian <zhengyejian1@huawei.com>
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Link: https://lore.kernel.org/20250105162345.339462681@goodmis.org
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
scripts/sorttable.c | 10 +++++++
scripts/sorttable.h | 74 ++++++++++++++++++++++++++++------------------------
2 files changed, 51 insertions(+), 33 deletions(-)
--- a/scripts/sorttable.c
+++ b/scripts/sorttable.c
@@ -69,6 +69,11 @@ typedef union {
Elf64_Ehdr e64;
} Elf_Ehdr;
+typedef union {
+ Elf32_Shdr e32;
+ Elf64_Shdr e64;
+} Elf_Shdr;
+
static uint32_t (*r)(const uint32_t *);
static uint16_t (*r2)(const uint16_t *);
static uint64_t (*r8)(const uint64_t *);
@@ -198,6 +203,11 @@ static int compare_extable_64(const void
return av > bv;
}
+static inline void *get_index(void *start, int entsize, int index)
+{
+ return start + (entsize * index);
+}
+
/* 32 bit and 64 bit are very similar */
#include "sorttable.h"
#define SORTTABLE_64
--- a/scripts/sorttable.h
+++ b/scripts/sorttable.h
@@ -23,7 +23,6 @@
#undef sort_mcount_loc
#undef elf_mcount_loc
#undef do_sort
-#undef Elf_Shdr
#undef Elf_Sym
#undef ELF_ST_TYPE
#undef uint_t
@@ -37,7 +36,6 @@
# define sort_mcount_loc sort_mcount_loc_64
# define elf_mcount_loc elf_mcount_loc_64
# define do_sort do_sort_64
-# define Elf_Shdr Elf64_Shdr
# define Elf_Sym Elf64_Sym
# define ELF_ST_TYPE ELF64_ST_TYPE
# define uint_t uint64_t
@@ -50,7 +48,6 @@
# define sort_mcount_loc sort_mcount_loc_32
# define elf_mcount_loc elf_mcount_loc_32
# define do_sort do_sort_32
-# define Elf_Shdr Elf32_Shdr
# define Elf_Sym Elf32_Sym
# define ELF_ST_TYPE ELF32_ST_TYPE
# define uint_t uint32_t
@@ -171,8 +168,8 @@ struct elf_mcount_loc {
static void *sort_mcount_loc(void *arg)
{
struct elf_mcount_loc *emloc = (struct elf_mcount_loc *)arg;
- uint_t offset = emloc->start_mcount_loc - _r(&(emloc->init_data_sec)->sh_addr)
- + _r(&(emloc->init_data_sec)->sh_offset);
+ uint_t offset = emloc->start_mcount_loc - _r(&(emloc->init_data_sec)->etype.sh_addr)
+ + _r(&(emloc->init_data_sec)->etype.sh_offset);
uint_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
unsigned char *start_loc = (void *)emloc->ehdr + offset;
@@ -222,10 +219,11 @@ static int do_sort(Elf_Ehdr *ehdr,
table_sort_t custom_sort)
{
int rc = -1;
- Elf_Shdr *s, *shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->etype.e_shoff));
+ Elf_Shdr *shdr_start;
Elf_Shdr *strtab_sec = NULL;
Elf_Shdr *symtab_sec = NULL;
Elf_Shdr *extab_sec = NULL;
+ Elf_Shdr *string_sec;
Elf_Sym *sym;
const Elf_Sym *symtab;
Elf32_Word *symtab_shndx = NULL;
@@ -235,7 +233,10 @@ static int do_sort(Elf_Ehdr *ehdr,
const char *secstrings;
const char *strtab;
char *extab_image;
+ int sort_need_index;
+ int shentsize;
int idx;
+ int i;
unsigned int shnum;
unsigned int shstrndx;
#ifdef MCOUNT_SORT_ENABLED
@@ -249,34 +250,40 @@ static int do_sort(Elf_Ehdr *ehdr,
unsigned int orc_num_entries = 0;
#endif
+ shdr_start = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->etype.e_shoff));
+ shentsize = r2(&ehdr->etype.e_shentsize);
+
shstrndx = r2(&ehdr->etype.e_shstrndx);
if (shstrndx == SHN_XINDEX)
- shstrndx = r(&shdr[0].sh_link);
- secstrings = (const char *)ehdr + _r(&shdr[shstrndx].sh_offset);
+ shstrndx = r(&shdr_start->etype.sh_link);
+ string_sec = get_index(shdr_start, shentsize, shstrndx);
+ secstrings = (const char *)ehdr + _r(&string_sec->etype.sh_offset);
shnum = r2(&ehdr->etype.e_shnum);
if (shnum == SHN_UNDEF)
- shnum = _r(&shdr[0].sh_size);
+ shnum = _r(&shdr_start->etype.sh_size);
+
+ for (i = 0; i < shnum; i++) {
+ Elf_Shdr *shdr = get_index(shdr_start, shentsize, i);
- for (s = shdr; s < shdr + shnum; s++) {
- idx = r(&s->sh_name);
+ idx = r(&shdr->etype.sh_name);
if (!strcmp(secstrings + idx, "__ex_table"))
- extab_sec = s;
+ extab_sec = shdr;
if (!strcmp(secstrings + idx, ".symtab"))
- symtab_sec = s;
+ symtab_sec = shdr;
if (!strcmp(secstrings + idx, ".strtab"))
- strtab_sec = s;
+ strtab_sec = shdr;
- if (r(&s->sh_type) == SHT_SYMTAB_SHNDX)
+ if (r(&shdr->etype.sh_type) == SHT_SYMTAB_SHNDX)
symtab_shndx = (Elf32_Word *)((const char *)ehdr +
- _r(&s->sh_offset));
+ _r(&shdr->etype.sh_offset));
#ifdef MCOUNT_SORT_ENABLED
/* locate the .init.data section in vmlinux */
if (!strcmp(secstrings + idx, ".init.data")) {
get_mcount_loc(&_start_mcount_loc, &_stop_mcount_loc);
mstruct.ehdr = ehdr;
- mstruct.init_data_sec = s;
+ mstruct.init_data_sec = shdr;
mstruct.start_mcount_loc = _start_mcount_loc;
mstruct.stop_mcount_loc = _stop_mcount_loc;
}
@@ -285,14 +292,14 @@ static int do_sort(Elf_Ehdr *ehdr,
#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
/* locate the ORC unwind tables */
if (!strcmp(secstrings + idx, ".orc_unwind_ip")) {
- orc_ip_size = _r(&s->sh_size);
+ orc_ip_size = _r(&shdr->etype.sh_size);
g_orc_ip_table = (int *)((void *)ehdr +
- _r(&s->sh_offset));
+ _r(&shdr->etype.sh_offset));
}
if (!strcmp(secstrings + idx, ".orc_unwind")) {
- orc_size = _r(&s->sh_size);
+ orc_size = _r(&shdr->etype.sh_size);
g_orc_table = (struct orc_entry *)((void *)ehdr +
- _r(&s->sh_offset));
+ _r(&shdr->etype.sh_offset));
}
#endif
} /* for loop */
@@ -355,22 +362,22 @@ static int do_sort(Elf_Ehdr *ehdr,
goto out;
}
- extab_image = (void *)ehdr + _r(&extab_sec->sh_offset);
- strtab = (const char *)ehdr + _r(&strtab_sec->sh_offset);
+ extab_image = (void *)ehdr + _r(&extab_sec->etype.sh_offset);
+ strtab = (const char *)ehdr + _r(&strtab_sec->etype.sh_offset);
symtab = (const Elf_Sym *)((const char *)ehdr +
- _r(&symtab_sec->sh_offset));
+ _r(&symtab_sec->etype.sh_offset));
if (custom_sort) {
- custom_sort(extab_image, _r(&extab_sec->sh_size));
+ custom_sort(extab_image, _r(&extab_sec->etype.sh_size));
} else {
- int num_entries = _r(&extab_sec->sh_size) / extable_ent_size;
+ int num_entries = _r(&extab_sec->etype.sh_size) / extable_ent_size;
qsort(extab_image, num_entries,
extable_ent_size, compare_extable);
}
/* find the flag main_extable_sort_needed */
- for (sym = (void *)ehdr + _r(&symtab_sec->sh_offset);
- sym < sym + _r(&symtab_sec->sh_size) / sizeof(Elf_Sym);
+ for (sym = (void *)ehdr + _r(&symtab_sec->etype.sh_offset);
+ sym < sym + _r(&symtab_sec->etype.sh_size) / sizeof(Elf_Sym);
sym++) {
if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
continue;
@@ -388,13 +395,14 @@ static int do_sort(Elf_Ehdr *ehdr,
goto out;
}
- sort_needed_sec = &shdr[get_secindex(r2(&sym->st_shndx),
- sort_needed_sym - symtab,
- symtab_shndx)];
+ sort_need_index = get_secindex(r2(&sym->st_shndx),
+ sort_needed_sym - symtab,
+ symtab_shndx);
+ sort_needed_sec = get_index(shdr_start, shentsize, sort_need_index);
sort_needed_loc = (void *)ehdr +
- _r(&sort_needed_sec->sh_offset) +
+ _r(&sort_needed_sec->etype.sh_offset) +
_r(&sort_needed_sym->st_value) -
- _r(&sort_needed_sec->sh_addr);
+ _r(&sort_needed_sec->etype.sh_addr);
/* extable has been sorted, clear the flag */
w(0, sort_needed_loc);
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 6.6 051/175] scripts/sorttable: Convert Elf_Sym MACRO over to a union
[not found] <20260702155115.766838875@linuxfoundation.org>
` (6 preceding siblings ...)
2026-07-02 16:19 ` [PATCH 6.6 050/175] scripts/sorttable: Replace Elf_Shdr Macro with a union Greg Kroah-Hartman
@ 2026-07-02 16:19 ` Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 052/175] scripts/sorttable: Add helper functions for Elf_Ehdr Greg Kroah-Hartman
` (12 subsequent siblings)
20 siblings, 0 replies; 21+ messages in thread
From: Greg Kroah-Hartman @ 2026-07-02 16:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, bpf, Masami Hiramatsu, Mark Rutland,
Mathieu Desnoyers, Andrew Morton, Peter Zijlstra, Linus Torvalds,
Masahiro Yamada, Nathan Chancellor, Nicolas Schier, Zheng Yejian,
Martin Kelly, Christophe Leroy, Josh Poimboeuf,
Steven Rostedt (Google), Andrey Grodzovsky
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 200d015e73b4da69bcd8212a7c58695452b12bad ]
In order to remove the double #include of sorttable.h for 64 and 32 bit
to create duplicate functions for both, replace the Elf_Sym macro with a
union that defines both Elf64_Sym and Elf32_Sym, with field e64 for the
64bit version, and e32 for the 32bit version.
It can then use the macro etype to get the proper value.
This will eventually be replaced with just single functions that can
handle both 32bit and 64bit ELF parsing.
Cc: bpf <bpf@vger.kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: Zheng Yejian <zhengyejian1@huawei.com>
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Link: https://lore.kernel.org/20250105162345.528626969@goodmis.org
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
scripts/sorttable.c | 5 +++++
scripts/sorttable.h | 25 ++++++++++++++-----------
2 files changed, 19 insertions(+), 11 deletions(-)
--- a/scripts/sorttable.c
+++ b/scripts/sorttable.c
@@ -74,6 +74,11 @@ typedef union {
Elf64_Shdr e64;
} Elf_Shdr;
+typedef union {
+ Elf32_Sym e32;
+ Elf64_Sym e64;
+} Elf_Sym;
+
static uint32_t (*r)(const uint32_t *);
static uint16_t (*r2)(const uint16_t *);
static uint64_t (*r8)(const uint64_t *);
--- a/scripts/sorttable.h
+++ b/scripts/sorttable.h
@@ -23,7 +23,6 @@
#undef sort_mcount_loc
#undef elf_mcount_loc
#undef do_sort
-#undef Elf_Sym
#undef ELF_ST_TYPE
#undef uint_t
#undef _r
@@ -36,7 +35,6 @@
# define sort_mcount_loc sort_mcount_loc_64
# define elf_mcount_loc elf_mcount_loc_64
# define do_sort do_sort_64
-# define Elf_Sym Elf64_Sym
# define ELF_ST_TYPE ELF64_ST_TYPE
# define uint_t uint64_t
# define _r r8
@@ -48,7 +46,6 @@
# define sort_mcount_loc sort_mcount_loc_32
# define elf_mcount_loc elf_mcount_loc_32
# define do_sort do_sort_32
-# define Elf_Sym Elf32_Sym
# define ELF_ST_TYPE ELF32_ST_TYPE
# define uint_t uint32_t
# define _r r
@@ -230,10 +227,13 @@ static int do_sort(Elf_Ehdr *ehdr,
Elf_Sym *sort_needed_sym = NULL;
Elf_Shdr *sort_needed_sec;
uint32_t *sort_needed_loc;
+ void *sym_start;
+ void *sym_end;
const char *secstrings;
const char *strtab;
char *extab_image;
int sort_need_index;
+ int symentsize;
int shentsize;
int idx;
int i;
@@ -376,12 +376,15 @@ static int do_sort(Elf_Ehdr *ehdr,
}
/* find the flag main_extable_sort_needed */
- for (sym = (void *)ehdr + _r(&symtab_sec->etype.sh_offset);
- sym < sym + _r(&symtab_sec->etype.sh_size) / sizeof(Elf_Sym);
- sym++) {
- if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
+ sym_start = (void *)ehdr + _r(&symtab_sec->etype.sh_offset);
+ sym_end = sym_start + _r(&symtab_sec->etype.sh_size);
+ symentsize = _r(&symtab_sec->etype.sh_entsize);
+
+ for (sym = sym_start; (void *)sym + symentsize < sym_end;
+ sym = (void *)sym + symentsize) {
+ if (ELF_ST_TYPE(sym->etype.st_info) != STT_OBJECT)
continue;
- if (!strcmp(strtab + r(&sym->st_name),
+ if (!strcmp(strtab + r(&sym->etype.st_name),
"main_extable_sort_needed")) {
sort_needed_sym = sym;
break;
@@ -395,13 +398,13 @@ static int do_sort(Elf_Ehdr *ehdr,
goto out;
}
- sort_need_index = get_secindex(r2(&sym->st_shndx),
- sort_needed_sym - symtab,
+ sort_need_index = get_secindex(r2(&sym->etype.st_shndx),
+ ((void *)sort_needed_sym - (void *)symtab) / symentsize,
symtab_shndx);
sort_needed_sec = get_index(shdr_start, shentsize, sort_need_index);
sort_needed_loc = (void *)ehdr +
_r(&sort_needed_sec->etype.sh_offset) +
- _r(&sort_needed_sym->st_value) -
+ _r(&sort_needed_sym->etype.st_value) -
_r(&sort_needed_sec->etype.sh_addr);
/* extable has been sorted, clear the flag */
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 6.6 052/175] scripts/sorttable: Add helper functions for Elf_Ehdr
[not found] <20260702155115.766838875@linuxfoundation.org>
` (7 preceding siblings ...)
2026-07-02 16:19 ` [PATCH 6.6 051/175] scripts/sorttable: Convert Elf_Sym MACRO over to " Greg Kroah-Hartman
@ 2026-07-02 16:19 ` Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 053/175] scripts/sorttable: Add helper functions for Elf_Shdr Greg Kroah-Hartman
` (11 subsequent siblings)
20 siblings, 0 replies; 21+ messages in thread
From: Greg Kroah-Hartman @ 2026-07-02 16:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, bpf, Masami Hiramatsu, Mark Rutland,
Mathieu Desnoyers, Andrew Morton, Peter Zijlstra, Linus Torvalds,
Masahiro Yamada, Nathan Chancellor, Nicolas Schier, Zheng Yejian,
Martin Kelly, Christophe Leroy, Josh Poimboeuf,
Steven Rostedt (Google), Andrey Grodzovsky
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 1dfb59a228dde59ad7d99b2fa2104e90004995c7 ]
In order to remove the double #include of sorttable.h for 64 and 32 bit
to create duplicate functions, add helper functions for Elf_Ehdr. This
will create a function pointer for each helper that will get assigned to
the appropriate function to handle either the 64bit or 32bit version.
This also moves the _r()/r() wrappers for the Elf_Ehdr references that
handle endian and size differences between the different architectures,
into the helper function and out of the open code which is more error
prone.
Cc: bpf <bpf@vger.kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: Zheng Yejian <zhengyejian1@huawei.com>
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Link: https://lore.kernel.org/20250105162345.736369526@goodmis.org
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
scripts/sorttable.c | 25 +++++++++++++++++++++++++
scripts/sorttable.h | 20 ++++++++++++++++----
2 files changed, 41 insertions(+), 4 deletions(-)
--- a/scripts/sorttable.c
+++ b/scripts/sorttable.c
@@ -85,6 +85,31 @@ static uint64_t (*r8)(const uint64_t *);
static void (*w)(uint32_t, uint32_t *);
typedef void (*table_sort_t)(char *, int);
+static uint64_t ehdr64_shoff(Elf_Ehdr *ehdr)
+{
+ return r8(&ehdr->e64.e_shoff);
+}
+
+static uint64_t ehdr32_shoff(Elf_Ehdr *ehdr)
+{
+ return r(&ehdr->e32.e_shoff);
+}
+
+#define EHDR_HALF(fn_name) \
+static uint16_t ehdr64_##fn_name(Elf_Ehdr *ehdr) \
+{ \
+ return r2(&ehdr->e64.e_##fn_name); \
+} \
+ \
+static uint16_t ehdr32_##fn_name(Elf_Ehdr *ehdr) \
+{ \
+ return r2(&ehdr->e32.e_##fn_name); \
+}
+
+EHDR_HALF(shentsize)
+EHDR_HALF(shstrndx)
+EHDR_HALF(shnum)
+
/*
* Get the whole file as a programming convenience in order to avoid
* malloc+lseek+read+free of many pieces. If successful, then mmap
--- a/scripts/sorttable.h
+++ b/scripts/sorttable.h
@@ -27,6 +27,10 @@
#undef uint_t
#undef _r
#undef etype
+#undef ehdr_shoff
+#undef ehdr_shentsize
+#undef ehdr_shstrndx
+#undef ehdr_shnum
#ifdef SORTTABLE_64
# define extable_ent_size 16
@@ -39,6 +43,10 @@
# define uint_t uint64_t
# define _r r8
# define etype e64
+# define ehdr_shoff ehdr64_shoff
+# define ehdr_shentsize ehdr64_shentsize
+# define ehdr_shstrndx ehdr64_shstrndx
+# define ehdr_shnum ehdr64_shnum
#else
# define extable_ent_size 8
# define compare_extable compare_extable_32
@@ -50,6 +58,10 @@
# define uint_t uint32_t
# define _r r
# define etype e32
+# define ehdr_shoff ehdr32_shoff
+# define ehdr_shentsize ehdr32_shentsize
+# define ehdr_shstrndx ehdr32_shstrndx
+# define ehdr_shnum ehdr32_shnum
#endif
#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
@@ -250,16 +262,16 @@ static int do_sort(Elf_Ehdr *ehdr,
unsigned int orc_num_entries = 0;
#endif
- shdr_start = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->etype.e_shoff));
- shentsize = r2(&ehdr->etype.e_shentsize);
+ shdr_start = (Elf_Shdr *)((char *)ehdr + ehdr_shoff(ehdr));
+ shentsize = ehdr_shentsize(ehdr);
- shstrndx = r2(&ehdr->etype.e_shstrndx);
+ shstrndx = ehdr_shstrndx(ehdr);
if (shstrndx == SHN_XINDEX)
shstrndx = r(&shdr_start->etype.sh_link);
string_sec = get_index(shdr_start, shentsize, shstrndx);
secstrings = (const char *)ehdr + _r(&string_sec->etype.sh_offset);
- shnum = r2(&ehdr->etype.e_shnum);
+ shnum = ehdr_shnum(ehdr);
if (shnum == SHN_UNDEF)
shnum = _r(&shdr_start->etype.sh_size);
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 6.6 053/175] scripts/sorttable: Add helper functions for Elf_Shdr
[not found] <20260702155115.766838875@linuxfoundation.org>
` (8 preceding siblings ...)
2026-07-02 16:19 ` [PATCH 6.6 052/175] scripts/sorttable: Add helper functions for Elf_Ehdr Greg Kroah-Hartman
@ 2026-07-02 16:19 ` Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 054/175] scripts/sorttable: Add helper functions for Elf_Sym Greg Kroah-Hartman
` (10 subsequent siblings)
20 siblings, 0 replies; 21+ messages in thread
From: Greg Kroah-Hartman @ 2026-07-02 16:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, bpf, Masami Hiramatsu, Mark Rutland,
Mathieu Desnoyers, Andrew Morton, Peter Zijlstra, Linus Torvalds,
Masahiro Yamada, Nathan Chancellor, Nicolas Schier, Zheng Yejian,
Martin Kelly, Christophe Leroy, Josh Poimboeuf,
Steven Rostedt (Google), Andrey Grodzovsky
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 67afb7f504400e5b4e5ff895459fbb3eb63d4450 ]
In order to remove the double #include of sorttable.h for 64 and 32 bit
to create duplicate functions, add helper functions for Elf_Shdr. This
will create a function pointer for each helper that will get assigned to
the appropriate function to handle either the 64bit or 32bit version.
This also moves the _r()/r() wrappers for the Elf_Shdr references that
handle endian and size differences between the different architectures,
into the helper function and out of the open code which is more error
prone.
Cc: bpf <bpf@vger.kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: Zheng Yejian <zhengyejian1@huawei.com>
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Link: https://lore.kernel.org/20250105162345.940924221@goodmis.org
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
scripts/sorttable.c | 42 +++++++++++++++++++++++++++++++++
scripts/sorttable.h | 66 +++++++++++++++++++++++++++++++++-------------------
2 files changed, 85 insertions(+), 23 deletions(-)
--- a/scripts/sorttable.c
+++ b/scripts/sorttable.c
@@ -110,6 +110,48 @@ EHDR_HALF(shentsize)
EHDR_HALF(shstrndx)
EHDR_HALF(shnum)
+#define SHDR_WORD(fn_name) \
+static uint32_t shdr64_##fn_name(Elf_Shdr *shdr) \
+{ \
+ return r(&shdr->e64.sh_##fn_name); \
+} \
+ \
+static uint32_t shdr32_##fn_name(Elf_Shdr *shdr) \
+{ \
+ return r(&shdr->e32.sh_##fn_name); \
+}
+
+#define SHDR_ADDR(fn_name) \
+static uint64_t shdr64_##fn_name(Elf_Shdr *shdr) \
+{ \
+ return r8(&shdr->e64.sh_##fn_name); \
+} \
+ \
+static uint64_t shdr32_##fn_name(Elf_Shdr *shdr) \
+{ \
+ return r(&shdr->e32.sh_##fn_name); \
+}
+
+#define SHDR_WORD(fn_name) \
+static uint32_t shdr64_##fn_name(Elf_Shdr *shdr) \
+{ \
+ return r(&shdr->e64.sh_##fn_name); \
+} \
+ \
+static uint32_t shdr32_##fn_name(Elf_Shdr *shdr) \
+{ \
+ return r(&shdr->e32.sh_##fn_name); \
+}
+
+SHDR_ADDR(addr)
+SHDR_ADDR(offset)
+SHDR_ADDR(size)
+SHDR_ADDR(entsize)
+
+SHDR_WORD(link)
+SHDR_WORD(name)
+SHDR_WORD(type)
+
/*
* Get the whole file as a programming convenience in order to avoid
* malloc+lseek+read+free of many pieces. If successful, then mmap
--- a/scripts/sorttable.h
+++ b/scripts/sorttable.h
@@ -31,6 +31,13 @@
#undef ehdr_shentsize
#undef ehdr_shstrndx
#undef ehdr_shnum
+#undef shdr_addr
+#undef shdr_offset
+#undef shdr_link
+#undef shdr_size
+#undef shdr_name
+#undef shdr_type
+#undef shdr_entsize
#ifdef SORTTABLE_64
# define extable_ent_size 16
@@ -47,6 +54,13 @@
# define ehdr_shentsize ehdr64_shentsize
# define ehdr_shstrndx ehdr64_shstrndx
# define ehdr_shnum ehdr64_shnum
+# define shdr_addr shdr64_addr
+# define shdr_offset shdr64_offset
+# define shdr_link shdr64_link
+# define shdr_size shdr64_size
+# define shdr_name shdr64_name
+# define shdr_type shdr64_type
+# define shdr_entsize shdr64_entsize
#else
# define extable_ent_size 8
# define compare_extable compare_extable_32
@@ -62,6 +76,13 @@
# define ehdr_shentsize ehdr32_shentsize
# define ehdr_shstrndx ehdr32_shstrndx
# define ehdr_shnum ehdr32_shnum
+# define shdr_addr shdr32_addr
+# define shdr_offset shdr32_offset
+# define shdr_link shdr32_link
+# define shdr_size shdr32_size
+# define shdr_name shdr32_name
+# define shdr_type shdr32_type
+# define shdr_entsize shdr32_entsize
#endif
#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
@@ -177,8 +198,8 @@ struct elf_mcount_loc {
static void *sort_mcount_loc(void *arg)
{
struct elf_mcount_loc *emloc = (struct elf_mcount_loc *)arg;
- uint_t offset = emloc->start_mcount_loc - _r(&(emloc->init_data_sec)->etype.sh_addr)
- + _r(&(emloc->init_data_sec)->etype.sh_offset);
+ uint_t offset = emloc->start_mcount_loc - shdr_addr(emloc->init_data_sec)
+ + shdr_offset(emloc->init_data_sec);
uint_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
unsigned char *start_loc = (void *)emloc->ehdr + offset;
@@ -267,18 +288,18 @@ static int do_sort(Elf_Ehdr *ehdr,
shstrndx = ehdr_shstrndx(ehdr);
if (shstrndx == SHN_XINDEX)
- shstrndx = r(&shdr_start->etype.sh_link);
+ shstrndx = shdr_link(shdr_start);
string_sec = get_index(shdr_start, shentsize, shstrndx);
- secstrings = (const char *)ehdr + _r(&string_sec->etype.sh_offset);
+ secstrings = (const char *)ehdr + shdr_offset(string_sec);
shnum = ehdr_shnum(ehdr);
if (shnum == SHN_UNDEF)
- shnum = _r(&shdr_start->etype.sh_size);
+ shnum = shdr_size(shdr_start);
for (i = 0; i < shnum; i++) {
Elf_Shdr *shdr = get_index(shdr_start, shentsize, i);
- idx = r(&shdr->etype.sh_name);
+ idx = shdr_name(shdr);
if (!strcmp(secstrings + idx, "__ex_table"))
extab_sec = shdr;
if (!strcmp(secstrings + idx, ".symtab"))
@@ -286,9 +307,9 @@ static int do_sort(Elf_Ehdr *ehdr,
if (!strcmp(secstrings + idx, ".strtab"))
strtab_sec = shdr;
- if (r(&shdr->etype.sh_type) == SHT_SYMTAB_SHNDX)
+ if (shdr_type(shdr) == SHT_SYMTAB_SHNDX)
symtab_shndx = (Elf32_Word *)((const char *)ehdr +
- _r(&shdr->etype.sh_offset));
+ shdr_offset(shdr));
#ifdef MCOUNT_SORT_ENABLED
/* locate the .init.data section in vmlinux */
@@ -304,14 +325,14 @@ static int do_sort(Elf_Ehdr *ehdr,
#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
/* locate the ORC unwind tables */
if (!strcmp(secstrings + idx, ".orc_unwind_ip")) {
- orc_ip_size = _r(&shdr->etype.sh_size);
+ orc_ip_size = shdr_size(shdr);
g_orc_ip_table = (int *)((void *)ehdr +
- _r(&shdr->etype.sh_offset));
+ shdr_offset(shdr));
}
if (!strcmp(secstrings + idx, ".orc_unwind")) {
- orc_size = _r(&shdr->etype.sh_size);
+ orc_size = shdr_size(shdr);
g_orc_table = (struct orc_entry *)((void *)ehdr +
- _r(&shdr->etype.sh_offset));
+ shdr_offset(shdr));
}
#endif
} /* for loop */
@@ -374,23 +395,22 @@ static int do_sort(Elf_Ehdr *ehdr,
goto out;
}
- extab_image = (void *)ehdr + _r(&extab_sec->etype.sh_offset);
- strtab = (const char *)ehdr + _r(&strtab_sec->etype.sh_offset);
- symtab = (const Elf_Sym *)((const char *)ehdr +
- _r(&symtab_sec->etype.sh_offset));
+ extab_image = (void *)ehdr + shdr_offset(extab_sec);
+ strtab = (const char *)ehdr + shdr_offset(strtab_sec);
+ symtab = (const Elf_Sym *)((const char *)ehdr + shdr_offset(symtab_sec));
if (custom_sort) {
- custom_sort(extab_image, _r(&extab_sec->etype.sh_size));
+ custom_sort(extab_image, shdr_size(extab_sec));
} else {
- int num_entries = _r(&extab_sec->etype.sh_size) / extable_ent_size;
+ int num_entries = shdr_size(extab_sec) / extable_ent_size;
qsort(extab_image, num_entries,
extable_ent_size, compare_extable);
}
/* find the flag main_extable_sort_needed */
- sym_start = (void *)ehdr + _r(&symtab_sec->etype.sh_offset);
- sym_end = sym_start + _r(&symtab_sec->etype.sh_size);
- symentsize = _r(&symtab_sec->etype.sh_entsize);
+ sym_start = (void *)ehdr + shdr_offset(symtab_sec);
+ sym_end = sym_start + shdr_size(symtab_sec);
+ symentsize = shdr_entsize(symtab_sec);
for (sym = sym_start; (void *)sym + symentsize < sym_end;
sym = (void *)sym + symentsize) {
@@ -415,9 +435,9 @@ static int do_sort(Elf_Ehdr *ehdr,
symtab_shndx);
sort_needed_sec = get_index(shdr_start, shentsize, sort_need_index);
sort_needed_loc = (void *)ehdr +
- _r(&sort_needed_sec->etype.sh_offset) +
+ shdr_offset(sort_needed_sec) +
_r(&sort_needed_sym->etype.st_value) -
- _r(&sort_needed_sec->etype.sh_addr);
+ shdr_addr(sort_needed_sec);
/* extable has been sorted, clear the flag */
w(0, sort_needed_loc);
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 6.6 054/175] scripts/sorttable: Add helper functions for Elf_Sym
[not found] <20260702155115.766838875@linuxfoundation.org>
` (9 preceding siblings ...)
2026-07-02 16:19 ` [PATCH 6.6 053/175] scripts/sorttable: Add helper functions for Elf_Shdr Greg Kroah-Hartman
@ 2026-07-02 16:19 ` Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 055/175] scripts/sorttable: Use uint64_t for mcount sorting Greg Kroah-Hartman
` (9 subsequent siblings)
20 siblings, 0 replies; 21+ messages in thread
From: Greg Kroah-Hartman @ 2026-07-02 16:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, bpf, Masami Hiramatsu, Mark Rutland,
Mathieu Desnoyers, Andrew Morton, Peter Zijlstra, Linus Torvalds,
Masahiro Yamada, Nathan Chancellor, Nicolas Schier, Zheng Yejian,
Martin Kelly, Christophe Leroy, Josh Poimboeuf,
Steven Rostedt (Google), Andrey Grodzovsky
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 17bed33ac12f011f4695059960e1b1d6457229a7 ]
In order to remove the double #include of sorttable.h for 64 and 32 bit
to create duplicate functions, add helper functions for Elf_Sym. This
will create a function pointer for each helper that will get assigned to
the appropriate function to handle either the 64bit or 32bit version.
This also removes the last references of etype and _r() macros from the
sorttable.h file as their references are now just defined in the
appropriate architecture version of the helper functions. All read
functions now exist in the helper functions which makes it easier to
maintain, as the helper functions define the necessary architecture sizes.
Cc: bpf <bpf@vger.kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: Zheng Yejian <zhengyejian1@huawei.com>
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Link: https://lore.kernel.org/20250105162346.185740651@goodmis.org
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
scripts/sorttable.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
scripts/sorttable.h | 30 ++++++++++++++++--------------
2 files changed, 63 insertions(+), 14 deletions(-)
--- a/scripts/sorttable.c
+++ b/scripts/sorttable.c
@@ -152,6 +152,53 @@ SHDR_WORD(link)
SHDR_WORD(name)
SHDR_WORD(type)
+#define SYM_ADDR(fn_name) \
+static uint64_t sym64_##fn_name(Elf_Sym *sym) \
+{ \
+ return r8(&sym->e64.st_##fn_name); \
+} \
+ \
+static uint64_t sym32_##fn_name(Elf_Sym *sym) \
+{ \
+ return r(&sym->e32.st_##fn_name); \
+}
+
+#define SYM_WORD(fn_name) \
+static uint32_t sym64_##fn_name(Elf_Sym *sym) \
+{ \
+ return r(&sym->e64.st_##fn_name); \
+} \
+ \
+static uint32_t sym32_##fn_name(Elf_Sym *sym) \
+{ \
+ return r(&sym->e32.st_##fn_name); \
+}
+
+#define SYM_HALF(fn_name) \
+static uint16_t sym64_##fn_name(Elf_Sym *sym) \
+{ \
+ return r2(&sym->e64.st_##fn_name); \
+} \
+ \
+static uint16_t sym32_##fn_name(Elf_Sym *sym) \
+{ \
+ return r2(&sym->e32.st_##fn_name); \
+}
+
+static uint8_t sym64_type(Elf_Sym *sym)
+{
+ return ELF64_ST_TYPE(sym->e64.st_info);
+}
+
+static uint8_t sym32_type(Elf_Sym *sym)
+{
+ return ELF32_ST_TYPE(sym->e32.st_info);
+}
+
+SYM_ADDR(value)
+SYM_WORD(name)
+SYM_HALF(shndx)
+
/*
* Get the whole file as a programming convenience in order to avoid
* malloc+lseek+read+free of many pieces. If successful, then mmap
--- a/scripts/sorttable.h
+++ b/scripts/sorttable.h
@@ -23,10 +23,7 @@
#undef sort_mcount_loc
#undef elf_mcount_loc
#undef do_sort
-#undef ELF_ST_TYPE
#undef uint_t
-#undef _r
-#undef etype
#undef ehdr_shoff
#undef ehdr_shentsize
#undef ehdr_shstrndx
@@ -38,6 +35,10 @@
#undef shdr_name
#undef shdr_type
#undef shdr_entsize
+#undef sym_type
+#undef sym_name
+#undef sym_value
+#undef sym_shndx
#ifdef SORTTABLE_64
# define extable_ent_size 16
@@ -46,10 +47,7 @@
# define sort_mcount_loc sort_mcount_loc_64
# define elf_mcount_loc elf_mcount_loc_64
# define do_sort do_sort_64
-# define ELF_ST_TYPE ELF64_ST_TYPE
# define uint_t uint64_t
-# define _r r8
-# define etype e64
# define ehdr_shoff ehdr64_shoff
# define ehdr_shentsize ehdr64_shentsize
# define ehdr_shstrndx ehdr64_shstrndx
@@ -61,6 +59,10 @@
# define shdr_name shdr64_name
# define shdr_type shdr64_type
# define shdr_entsize shdr64_entsize
+# define sym_type sym64_type
+# define sym_name sym64_name
+# define sym_value sym64_value
+# define sym_shndx sym64_shndx
#else
# define extable_ent_size 8
# define compare_extable compare_extable_32
@@ -68,10 +70,7 @@
# define sort_mcount_loc sort_mcount_loc_32
# define elf_mcount_loc elf_mcount_loc_32
# define do_sort do_sort_32
-# define ELF_ST_TYPE ELF32_ST_TYPE
# define uint_t uint32_t
-# define _r r
-# define etype e32
# define ehdr_shoff ehdr32_shoff
# define ehdr_shentsize ehdr32_shentsize
# define ehdr_shstrndx ehdr32_shstrndx
@@ -83,6 +82,10 @@
# define shdr_name shdr32_name
# define shdr_type shdr32_type
# define shdr_entsize shdr32_entsize
+# define sym_type sym32_type
+# define sym_name sym32_name
+# define sym_value sym32_value
+# define sym_shndx sym32_shndx
#endif
#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
@@ -414,9 +417,9 @@ static int do_sort(Elf_Ehdr *ehdr,
for (sym = sym_start; (void *)sym + symentsize < sym_end;
sym = (void *)sym + symentsize) {
- if (ELF_ST_TYPE(sym->etype.st_info) != STT_OBJECT)
+ if (sym_type(sym) != STT_OBJECT)
continue;
- if (!strcmp(strtab + r(&sym->etype.st_name),
+ if (!strcmp(strtab + sym_name(sym),
"main_extable_sort_needed")) {
sort_needed_sym = sym;
break;
@@ -430,14 +433,13 @@ static int do_sort(Elf_Ehdr *ehdr,
goto out;
}
- sort_need_index = get_secindex(r2(&sym->etype.st_shndx),
+ sort_need_index = get_secindex(sym_shndx(sym),
((void *)sort_needed_sym - (void *)symtab) / symentsize,
symtab_shndx);
sort_needed_sec = get_index(shdr_start, shentsize, sort_need_index);
sort_needed_loc = (void *)ehdr +
shdr_offset(sort_needed_sec) +
- _r(&sort_needed_sym->etype.st_value) -
- shdr_addr(sort_needed_sec);
+ sym_value(sort_needed_sym) - shdr_addr(sort_needed_sec);
/* extable has been sorted, clear the flag */
w(0, sort_needed_loc);
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 6.6 055/175] scripts/sorttable: Use uint64_t for mcount sorting
[not found] <20260702155115.766838875@linuxfoundation.org>
` (10 preceding siblings ...)
2026-07-02 16:19 ` [PATCH 6.6 054/175] scripts/sorttable: Add helper functions for Elf_Sym Greg Kroah-Hartman
@ 2026-07-02 16:19 ` Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 056/175] scripts/sorttable: Move code from sorttable.h into sorttable.c Greg Kroah-Hartman
` (8 subsequent siblings)
20 siblings, 0 replies; 21+ messages in thread
From: Greg Kroah-Hartman @ 2026-07-02 16:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, bpf, Masami Hiramatsu, Mark Rutland,
Mathieu Desnoyers, Andrew Morton, Peter Zijlstra, Linus Torvalds,
Masahiro Yamada, Nathan Chancellor, Nicolas Schier, Zheng Yejian,
Martin Kelly, Christophe Leroy, Josh Poimboeuf,
Steven Rostedt (Google), Andrey Grodzovsky
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 1b649e6ab8dc9188d82c64069493afe66ca0edad ]
The mcount sorting defines uint_t to uint64_t on 64bit architectures and
uint32_t on 32bit architectures. It can work with just using uint64_t as
that will hold the values of both, and they are not used to point into the
ELF file.
sizeof(uint_t) is used for defining the size of the mcount_loc section.
Instead of using a type, define long_size and use that instead. This will
allow the header code to be moved into the C file as generic functions and
not need to include sorttable.h twice, once for 64bit and once for 32bit.
Cc: bpf <bpf@vger.kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: Zheng Yejian <zhengyejian1@huawei.com>
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Link: https://lore.kernel.org/20250105162346.373528925@goodmis.org
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
scripts/sorttable.h | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
--- a/scripts/sorttable.h
+++ b/scripts/sorttable.h
@@ -23,7 +23,6 @@
#undef sort_mcount_loc
#undef elf_mcount_loc
#undef do_sort
-#undef uint_t
#undef ehdr_shoff
#undef ehdr_shentsize
#undef ehdr_shstrndx
@@ -39,6 +38,7 @@
#undef sym_name
#undef sym_value
#undef sym_shndx
+#undef long_size
#ifdef SORTTABLE_64
# define extable_ent_size 16
@@ -47,7 +47,6 @@
# define sort_mcount_loc sort_mcount_loc_64
# define elf_mcount_loc elf_mcount_loc_64
# define do_sort do_sort_64
-# define uint_t uint64_t
# define ehdr_shoff ehdr64_shoff
# define ehdr_shentsize ehdr64_shentsize
# define ehdr_shstrndx ehdr64_shstrndx
@@ -63,6 +62,7 @@
# define sym_name sym64_name
# define sym_value sym64_value
# define sym_shndx sym64_shndx
+# define long_size 8
#else
# define extable_ent_size 8
# define compare_extable compare_extable_32
@@ -70,7 +70,6 @@
# define sort_mcount_loc sort_mcount_loc_32
# define elf_mcount_loc elf_mcount_loc_32
# define do_sort do_sort_32
-# define uint_t uint32_t
# define ehdr_shoff ehdr32_shoff
# define ehdr_shentsize ehdr32_shentsize
# define ehdr_shstrndx ehdr32_shstrndx
@@ -86,6 +85,7 @@
# define sym_name sym32_name
# define sym_value sym32_value
# define sym_shndx sym32_shndx
+# define long_size 4
#endif
#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
@@ -193,25 +193,25 @@ pthread_t mcount_sort_thread;
struct elf_mcount_loc {
Elf_Ehdr *ehdr;
Elf_Shdr *init_data_sec;
- uint_t start_mcount_loc;
- uint_t stop_mcount_loc;
+ uint64_t start_mcount_loc;
+ uint64_t stop_mcount_loc;
};
/* Sort the addresses stored between __start_mcount_loc to __stop_mcount_loc in vmlinux */
static void *sort_mcount_loc(void *arg)
{
struct elf_mcount_loc *emloc = (struct elf_mcount_loc *)arg;
- uint_t offset = emloc->start_mcount_loc - shdr_addr(emloc->init_data_sec)
+ uint64_t offset = emloc->start_mcount_loc - shdr_addr(emloc->init_data_sec)
+ shdr_offset(emloc->init_data_sec);
- uint_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
+ uint64_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
unsigned char *start_loc = (void *)emloc->ehdr + offset;
- qsort(start_loc, count/sizeof(uint_t), sizeof(uint_t), compare_extable);
+ qsort(start_loc, count/long_size, long_size, compare_extable);
return NULL;
}
/* Get the address of __start_mcount_loc and __stop_mcount_loc in System.map */
-static void get_mcount_loc(uint_t *_start, uint_t *_stop)
+static void get_mcount_loc(uint64_t *_start, uint64_t *_stop)
{
FILE *file_start, *file_stop;
char start_buff[20];
@@ -277,8 +277,8 @@ static int do_sort(Elf_Ehdr *ehdr,
unsigned int shstrndx;
#ifdef MCOUNT_SORT_ENABLED
struct elf_mcount_loc mstruct = {0};
- uint_t _start_mcount_loc = 0;
- uint_t _stop_mcount_loc = 0;
+ uint64_t _start_mcount_loc = 0;
+ uint64_t _stop_mcount_loc = 0;
#endif
#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
unsigned int orc_ip_size = 0;
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 6.6 056/175] scripts/sorttable: Move code from sorttable.h into sorttable.c
[not found] <20260702155115.766838875@linuxfoundation.org>
` (11 preceding siblings ...)
2026-07-02 16:19 ` [PATCH 6.6 055/175] scripts/sorttable: Use uint64_t for mcount sorting Greg Kroah-Hartman
@ 2026-07-02 16:19 ` Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 057/175] scripts/sorttable: Get start/stop_mcount_loc from ELF file directly Greg Kroah-Hartman
` (7 subsequent siblings)
20 siblings, 0 replies; 21+ messages in thread
From: Greg Kroah-Hartman @ 2026-07-02 16:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, bpf, Masami Hiramatsu, Mark Rutland,
Mathieu Desnoyers, Andrew Morton, Peter Zijlstra, Linus Torvalds,
Masahiro Yamada, Nathan Chancellor, Nicolas Schier, Zheng Yejian,
Martin Kelly, Christophe Leroy, Josh Poimboeuf, Stephen Rothwell,
Steven Rostedt (Google), Andrey Grodzovsky
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 58d87678a0f46c6120904b4326aaf5ebf4454c69 ]
Instead of having the main code live in a header file and included twice
with MACROs that define the Elf structures for 64 bit or 32 bit, move the
code in the C file now that the Elf structures are defined in a union that
has both. All accesses to the Elf structure fields are done through helper
function pointers. If the file being parsed if for a 64 bit architecture,
all the helper functions point to the 64 bit versions to retrieve the Elf
fields. The same is true if the architecture is 32 bit, where the function
pointers will point to the 32 bit helper functions.
Note, when the value of a field can be either 32 bit or 64 bit, a 64 bit
is always returned, as it works for the 32 bit code as well.
This makes the code easier to read and maintain, and it now all exists in
sorttable.c and sorttable.h may be removed.
Cc: bpf <bpf@vger.kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: Zheng Yejian <zhengyejian1@huawei.com>
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Link: https://lore.kernel.org/20250107223217.6f7f96a5@gandalf.local.home
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
scripts/sorttable.c | 473 +++++++++++++++++++++++++++++++++++++++++++++++++-
scripts/sorttable.h | 485 ----------------------------------------------------
2 files changed, 460 insertions(+), 498 deletions(-)
delete mode 100644 scripts/sorttable.h
--- a/scripts/sorttable.c
+++ b/scripts/sorttable.c
@@ -327,10 +327,423 @@ static inline void *get_index(void *star
return start + (entsize * index);
}
-/* 32 bit and 64 bit are very similar */
-#include "sorttable.h"
-#define SORTTABLE_64
-#include "sorttable.h"
+
+static int (*compare_extable)(const void *a, const void *b);
+static uint64_t (*ehdr_shoff)(Elf_Ehdr *ehdr);
+static uint16_t (*ehdr_shstrndx)(Elf_Ehdr *ehdr);
+static uint16_t (*ehdr_shentsize)(Elf_Ehdr *ehdr);
+static uint16_t (*ehdr_shnum)(Elf_Ehdr *ehdr);
+static uint64_t (*shdr_addr)(Elf_Shdr *shdr);
+static uint64_t (*shdr_offset)(Elf_Shdr *shdr);
+static uint64_t (*shdr_size)(Elf_Shdr *shdr);
+static uint64_t (*shdr_entsize)(Elf_Shdr *shdr);
+static uint32_t (*shdr_link)(Elf_Shdr *shdr);
+static uint32_t (*shdr_name)(Elf_Shdr *shdr);
+static uint32_t (*shdr_type)(Elf_Shdr *shdr);
+static uint8_t (*sym_type)(Elf_Sym *sym);
+static uint32_t (*sym_name)(Elf_Sym *sym);
+static uint64_t (*sym_value)(Elf_Sym *sym);
+static uint16_t (*sym_shndx)(Elf_Sym *sym);
+
+static int extable_ent_size;
+static int long_size;
+
+
+#ifdef UNWINDER_ORC_ENABLED
+/* ORC unwinder only support X86_64 */
+#include <asm/orc_types.h>
+
+#define ERRSTR_MAXSZ 256
+
+static char g_err[ERRSTR_MAXSZ];
+static int *g_orc_ip_table;
+static struct orc_entry *g_orc_table;
+
+static pthread_t orc_sort_thread;
+
+static inline unsigned long orc_ip(const int *ip)
+{
+ return (unsigned long)ip + *ip;
+}
+
+static int orc_sort_cmp(const void *_a, const void *_b)
+{
+ struct orc_entry *orc_a, *orc_b;
+ const int *a = g_orc_ip_table + *(int *)_a;
+ const int *b = g_orc_ip_table + *(int *)_b;
+ unsigned long a_val = orc_ip(a);
+ unsigned long b_val = orc_ip(b);
+
+ if (a_val > b_val)
+ return 1;
+ if (a_val < b_val)
+ return -1;
+
+ /*
+ * The "weak" section terminator entries need to always be on the left
+ * to ensure the lookup code skips them in favor of real entries.
+ * These terminator entries exist to handle any gaps created by
+ * whitelisted .o files which didn't get objtool generation.
+ */
+ orc_a = g_orc_table + (a - g_orc_ip_table);
+ orc_b = g_orc_table + (b - g_orc_ip_table);
+ if (orc_a->type == ORC_TYPE_UNDEFINED && orc_b->type == ORC_TYPE_UNDEFINED)
+ return 0;
+ return orc_a->type == ORC_TYPE_UNDEFINED ? -1 : 1;
+}
+
+static void *sort_orctable(void *arg)
+{
+ int i;
+ int *idxs = NULL;
+ int *tmp_orc_ip_table = NULL;
+ struct orc_entry *tmp_orc_table = NULL;
+ unsigned int *orc_ip_size = (unsigned int *)arg;
+ unsigned int num_entries = *orc_ip_size / sizeof(int);
+ unsigned int orc_size = num_entries * sizeof(struct orc_entry);
+
+ idxs = (int *)malloc(*orc_ip_size);
+ if (!idxs) {
+ snprintf(g_err, ERRSTR_MAXSZ, "malloc idxs: %s",
+ strerror(errno));
+ pthread_exit(g_err);
+ }
+
+ tmp_orc_ip_table = (int *)malloc(*orc_ip_size);
+ if (!tmp_orc_ip_table) {
+ snprintf(g_err, ERRSTR_MAXSZ, "malloc tmp_orc_ip_table: %s",
+ strerror(errno));
+ pthread_exit(g_err);
+ }
+
+ tmp_orc_table = (struct orc_entry *)malloc(orc_size);
+ if (!tmp_orc_table) {
+ snprintf(g_err, ERRSTR_MAXSZ, "malloc tmp_orc_table: %s",
+ strerror(errno));
+ pthread_exit(g_err);
+ }
+
+ /* initialize indices array, convert ip_table to absolute address */
+ for (i = 0; i < num_entries; i++) {
+ idxs[i] = i;
+ tmp_orc_ip_table[i] = g_orc_ip_table[i] + i * sizeof(int);
+ }
+ memcpy(tmp_orc_table, g_orc_table, orc_size);
+
+ qsort(idxs, num_entries, sizeof(int), orc_sort_cmp);
+
+ for (i = 0; i < num_entries; i++) {
+ if (idxs[i] == i)
+ continue;
+
+ /* convert back to relative address */
+ g_orc_ip_table[i] = tmp_orc_ip_table[idxs[i]] - i * sizeof(int);
+ g_orc_table[i] = tmp_orc_table[idxs[i]];
+ }
+
+ free(idxs);
+ free(tmp_orc_ip_table);
+ free(tmp_orc_table);
+ pthread_exit(NULL);
+}
+#endif
+
+#ifdef MCOUNT_SORT_ENABLED
+static pthread_t mcount_sort_thread;
+
+struct elf_mcount_loc {
+ Elf_Ehdr *ehdr;
+ Elf_Shdr *init_data_sec;
+ uint64_t start_mcount_loc;
+ uint64_t stop_mcount_loc;
+};
+
+/* Sort the addresses stored between __start_mcount_loc to __stop_mcount_loc in vmlinux */
+static void *sort_mcount_loc(void *arg)
+{
+ struct elf_mcount_loc *emloc = (struct elf_mcount_loc *)arg;
+ uint64_t offset = emloc->start_mcount_loc - shdr_addr(emloc->init_data_sec)
+ + shdr_offset(emloc->init_data_sec);
+ uint64_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
+ unsigned char *start_loc = (void *)emloc->ehdr + offset;
+
+ qsort(start_loc, count/long_size, long_size, compare_extable);
+ return NULL;
+}
+
+/* Get the address of __start_mcount_loc and __stop_mcount_loc in System.map */
+static void get_mcount_loc(uint64_t *_start, uint64_t *_stop)
+{
+ FILE *file_start, *file_stop;
+ char start_buff[20];
+ char stop_buff[20];
+ int len = 0;
+
+ file_start = popen(" grep start_mcount System.map | awk '{print $1}' ", "r");
+ if (!file_start) {
+ fprintf(stderr, "get start_mcount_loc error!");
+ return;
+ }
+
+ file_stop = popen(" grep stop_mcount System.map | awk '{print $1}' ", "r");
+ if (!file_stop) {
+ fprintf(stderr, "get stop_mcount_loc error!");
+ pclose(file_start);
+ return;
+ }
+
+ while (fgets(start_buff, sizeof(start_buff), file_start) != NULL) {
+ len = strlen(start_buff);
+ start_buff[len - 1] = '\0';
+ }
+ *_start = strtoul(start_buff, NULL, 16);
+
+ while (fgets(stop_buff, sizeof(stop_buff), file_stop) != NULL) {
+ len = strlen(stop_buff);
+ stop_buff[len - 1] = '\0';
+ }
+ *_stop = strtoul(stop_buff, NULL, 16);
+
+ pclose(file_start);
+ pclose(file_stop);
+}
+#endif
+static int do_sort(Elf_Ehdr *ehdr,
+ char const *const fname,
+ table_sort_t custom_sort)
+{
+ int rc = -1;
+ Elf_Shdr *shdr_start;
+ Elf_Shdr *strtab_sec = NULL;
+ Elf_Shdr *symtab_sec = NULL;
+ Elf_Shdr *extab_sec = NULL;
+ Elf_Shdr *string_sec;
+ Elf_Sym *sym;
+ const Elf_Sym *symtab;
+ Elf32_Word *symtab_shndx = NULL;
+ Elf_Sym *sort_needed_sym = NULL;
+ Elf_Shdr *sort_needed_sec;
+ uint32_t *sort_needed_loc;
+ void *sym_start;
+ void *sym_end;
+ const char *secstrings;
+ const char *strtab;
+ char *extab_image;
+ int sort_need_index;
+ int symentsize;
+ int shentsize;
+ int idx;
+ int i;
+ unsigned int shnum;
+ unsigned int shstrndx;
+#ifdef MCOUNT_SORT_ENABLED
+ struct elf_mcount_loc mstruct = {0};
+ uint64_t _start_mcount_loc = 0;
+ uint64_t _stop_mcount_loc = 0;
+#endif
+#ifdef UNWINDER_ORC_ENABLED
+ unsigned int orc_ip_size = 0;
+ unsigned int orc_size = 0;
+ unsigned int orc_num_entries = 0;
+#endif
+
+ shdr_start = (Elf_Shdr *)((char *)ehdr + ehdr_shoff(ehdr));
+ shentsize = ehdr_shentsize(ehdr);
+
+ shstrndx = ehdr_shstrndx(ehdr);
+ if (shstrndx == SHN_XINDEX)
+ shstrndx = shdr_link(shdr_start);
+ string_sec = get_index(shdr_start, shentsize, shstrndx);
+ secstrings = (const char *)ehdr + shdr_offset(string_sec);
+
+ shnum = ehdr_shnum(ehdr);
+ if (shnum == SHN_UNDEF)
+ shnum = shdr_size(shdr_start);
+
+ for (i = 0; i < shnum; i++) {
+ Elf_Shdr *shdr = get_index(shdr_start, shentsize, i);
+
+ idx = shdr_name(shdr);
+ if (!strcmp(secstrings + idx, "__ex_table"))
+ extab_sec = shdr;
+ if (!strcmp(secstrings + idx, ".symtab"))
+ symtab_sec = shdr;
+ if (!strcmp(secstrings + idx, ".strtab"))
+ strtab_sec = shdr;
+
+ if (shdr_type(shdr) == SHT_SYMTAB_SHNDX)
+ symtab_shndx = (Elf32_Word *)((const char *)ehdr +
+ shdr_offset(shdr));
+
+#ifdef MCOUNT_SORT_ENABLED
+ /* locate the .init.data section in vmlinux */
+ if (!strcmp(secstrings + idx, ".init.data")) {
+ get_mcount_loc(&_start_mcount_loc, &_stop_mcount_loc);
+ mstruct.ehdr = ehdr;
+ mstruct.init_data_sec = shdr;
+ mstruct.start_mcount_loc = _start_mcount_loc;
+ mstruct.stop_mcount_loc = _stop_mcount_loc;
+ }
+#endif
+
+#ifdef UNWINDER_ORC_ENABLED
+ /* locate the ORC unwind tables */
+ if (!strcmp(secstrings + idx, ".orc_unwind_ip")) {
+ orc_ip_size = shdr_size(shdr);
+ g_orc_ip_table = (int *)((void *)ehdr +
+ shdr_offset(shdr));
+ }
+ if (!strcmp(secstrings + idx, ".orc_unwind")) {
+ orc_size = shdr_size(shdr);
+ g_orc_table = (struct orc_entry *)((void *)ehdr +
+ shdr_offset(shdr));
+ }
+#endif
+ } /* for loop */
+
+#ifdef UNWINDER_ORC_ENABLED
+ if (!g_orc_ip_table || !g_orc_table) {
+ fprintf(stderr,
+ "incomplete ORC unwind tables in file: %s\n", fname);
+ goto out;
+ }
+
+ orc_num_entries = orc_ip_size / sizeof(int);
+ if (orc_ip_size % sizeof(int) != 0 ||
+ orc_size % sizeof(struct orc_entry) != 0 ||
+ orc_num_entries != orc_size / sizeof(struct orc_entry)) {
+ fprintf(stderr,
+ "inconsistent ORC unwind table entries in file: %s\n",
+ fname);
+ goto out;
+ }
+
+ /* create thread to sort ORC unwind tables concurrently */
+ if (pthread_create(&orc_sort_thread, NULL,
+ sort_orctable, &orc_ip_size)) {
+ fprintf(stderr,
+ "pthread_create orc_sort_thread failed '%s': %s\n",
+ strerror(errno), fname);
+ goto out;
+ }
+#endif
+
+#ifdef MCOUNT_SORT_ENABLED
+ if (!mstruct.init_data_sec || !_start_mcount_loc || !_stop_mcount_loc) {
+ fprintf(stderr,
+ "incomplete mcount's sort in file: %s\n",
+ fname);
+ goto out;
+ }
+
+ /* create thread to sort mcount_loc concurrently */
+ if (pthread_create(&mcount_sort_thread, NULL, &sort_mcount_loc, &mstruct)) {
+ fprintf(stderr,
+ "pthread_create mcount_sort_thread failed '%s': %s\n",
+ strerror(errno), fname);
+ goto out;
+ }
+#endif
+ if (!extab_sec) {
+ fprintf(stderr, "no __ex_table in file: %s\n", fname);
+ goto out;
+ }
+
+ if (!symtab_sec) {
+ fprintf(stderr, "no .symtab in file: %s\n", fname);
+ goto out;
+ }
+
+ if (!strtab_sec) {
+ fprintf(stderr, "no .strtab in file: %s\n", fname);
+ goto out;
+ }
+
+ extab_image = (void *)ehdr + shdr_offset(extab_sec);
+ strtab = (const char *)ehdr + shdr_offset(strtab_sec);
+ symtab = (const Elf_Sym *)((const char *)ehdr + shdr_offset(symtab_sec));
+
+ if (custom_sort) {
+ custom_sort(extab_image, shdr_size(extab_sec));
+ } else {
+ int num_entries = shdr_size(extab_sec) / extable_ent_size;
+ qsort(extab_image, num_entries,
+ extable_ent_size, compare_extable);
+ }
+
+ /* find the flag main_extable_sort_needed */
+ sym_start = (void *)ehdr + shdr_offset(symtab_sec);
+ sym_end = sym_start + shdr_size(symtab_sec);
+ symentsize = shdr_entsize(symtab_sec);
+
+ for (sym = sym_start; (void *)sym + symentsize < sym_end;
+ sym = (void *)sym + symentsize) {
+ if (sym_type(sym) != STT_OBJECT)
+ continue;
+ if (!strcmp(strtab + sym_name(sym),
+ "main_extable_sort_needed")) {
+ sort_needed_sym = sym;
+ break;
+ }
+ }
+
+ if (!sort_needed_sym) {
+ fprintf(stderr,
+ "no main_extable_sort_needed symbol in file: %s\n",
+ fname);
+ goto out;
+ }
+
+ sort_need_index = get_secindex(sym_shndx(sym),
+ ((void *)sort_needed_sym - (void *)symtab) / symentsize,
+ symtab_shndx);
+ sort_needed_sec = get_index(shdr_start, shentsize, sort_need_index);
+ sort_needed_loc = (void *)ehdr +
+ shdr_offset(sort_needed_sec) +
+ sym_value(sort_needed_sym) - shdr_addr(sort_needed_sec);
+
+ /* extable has been sorted, clear the flag */
+ w(0, sort_needed_loc);
+ rc = 0;
+
+out:
+#ifdef UNWINDER_ORC_ENABLED
+ if (orc_sort_thread) {
+ void *retval = NULL;
+ /* wait for ORC tables sort done */
+ rc = pthread_join(orc_sort_thread, &retval);
+ if (rc) {
+ fprintf(stderr,
+ "pthread_join failed '%s': %s\n",
+ strerror(errno), fname);
+ } else if (retval) {
+ rc = -1;
+ fprintf(stderr,
+ "failed to sort ORC tables '%s': %s\n",
+ (char *)retval, fname);
+ }
+ }
+#endif
+
+#ifdef MCOUNT_SORT_ENABLED
+ if (mcount_sort_thread) {
+ void *retval = NULL;
+ /* wait for mcount sort done */
+ rc = pthread_join(mcount_sort_thread, &retval);
+ if (rc) {
+ fprintf(stderr,
+ "pthread_join failed '%s': %s\n",
+ strerror(errno), fname);
+ } else if (retval) {
+ rc = -1;
+ fprintf(stderr,
+ "failed to sort mcount '%s': %s\n",
+ (char *)retval, fname);
+ }
+ }
+#endif
+ return rc;
+}
static int compare_relative_table(const void *a, const void *b)
{
@@ -399,7 +812,6 @@ static void sort_relative_table_with_dat
static int do_file(char const *const fname, void *addr)
{
- int rc = -1;
Elf_Ehdr *ehdr = addr;
table_sort_t custom_sort = NULL;
@@ -462,29 +874,64 @@ static int do_file(char const *const fna
r2(&ehdr->e32.e_shentsize) != sizeof(Elf32_Shdr)) {
fprintf(stderr,
"unrecognized ET_EXEC/ET_DYN file: %s\n", fname);
- break;
+ return -1;
}
- rc = do_sort_32(ehdr, fname, custom_sort);
+
+ compare_extable = compare_extable_32;
+ ehdr_shoff = ehdr32_shoff;
+ ehdr_shentsize = ehdr32_shentsize;
+ ehdr_shstrndx = ehdr32_shstrndx;
+ ehdr_shnum = ehdr32_shnum;
+ shdr_addr = shdr32_addr;
+ shdr_offset = shdr32_offset;
+ shdr_link = shdr32_link;
+ shdr_size = shdr32_size;
+ shdr_name = shdr32_name;
+ shdr_type = shdr32_type;
+ shdr_entsize = shdr32_entsize;
+ sym_type = sym32_type;
+ sym_name = sym32_name;
+ sym_value = sym32_value;
+ sym_shndx = sym32_shndx;
+ long_size = 4;
+ extable_ent_size = 8;
break;
case ELFCLASS64:
- {
if (r2(&ehdr->e64.e_ehsize) != sizeof(Elf64_Ehdr) ||
r2(&ehdr->e64.e_shentsize) != sizeof(Elf64_Shdr)) {
fprintf(stderr,
"unrecognized ET_EXEC/ET_DYN file: %s\n",
fname);
- break;
- }
- rc = do_sort_64(ehdr, fname, custom_sort);
+ return -1;
}
+
+ compare_extable = compare_extable_64;
+ ehdr_shoff = ehdr64_shoff;
+ ehdr_shentsize = ehdr64_shentsize;
+ ehdr_shstrndx = ehdr64_shstrndx;
+ ehdr_shnum = ehdr64_shnum;
+ shdr_addr = shdr64_addr;
+ shdr_offset = shdr64_offset;
+ shdr_link = shdr64_link;
+ shdr_size = shdr64_size;
+ shdr_name = shdr64_name;
+ shdr_type = shdr64_type;
+ shdr_entsize = shdr64_entsize;
+ sym_type = sym64_type;
+ sym_name = sym64_name;
+ sym_value = sym64_value;
+ sym_shndx = sym64_shndx;
+ long_size = 8;
+ extable_ent_size = 16;
+
break;
default:
fprintf(stderr, "unrecognized ELF class %d %s\n",
ehdr->e32.e_ident[EI_CLASS], fname);
- break;
+ return -1;
}
- return rc;
+ return do_sort(ehdr, fname, custom_sort);
}
int main(int argc, char *argv[])
--- a/scripts/sorttable.h
+++ /dev/null
@@ -1,485 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * sorttable.h
- *
- * Added ORC unwind tables sort support and other updates:
- * Copyright (C) 1999-2019 Alibaba Group Holding Limited. by:
- * Shile Zhang <shile.zhang@linux.alibaba.com>
- *
- * Copyright 2011 - 2012 Cavium, Inc.
- *
- * Some of code was taken out of arch/x86/kernel/unwind_orc.c, written by:
- * Copyright (C) 2017 Josh Poimboeuf <jpoimboe@redhat.com>
- *
- * Some of this code was taken out of recordmcount.h written by:
- *
- * Copyright 2009 John F. Reiser <jreiser@BitWagon.com>. All rights reserved.
- * Copyright 2010 Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
- */
-
-#undef extable_ent_size
-#undef compare_extable
-#undef get_mcount_loc
-#undef sort_mcount_loc
-#undef elf_mcount_loc
-#undef do_sort
-#undef ehdr_shoff
-#undef ehdr_shentsize
-#undef ehdr_shstrndx
-#undef ehdr_shnum
-#undef shdr_addr
-#undef shdr_offset
-#undef shdr_link
-#undef shdr_size
-#undef shdr_name
-#undef shdr_type
-#undef shdr_entsize
-#undef sym_type
-#undef sym_name
-#undef sym_value
-#undef sym_shndx
-#undef long_size
-
-#ifdef SORTTABLE_64
-# define extable_ent_size 16
-# define compare_extable compare_extable_64
-# define get_mcount_loc get_mcount_loc_64
-# define sort_mcount_loc sort_mcount_loc_64
-# define elf_mcount_loc elf_mcount_loc_64
-# define do_sort do_sort_64
-# define ehdr_shoff ehdr64_shoff
-# define ehdr_shentsize ehdr64_shentsize
-# define ehdr_shstrndx ehdr64_shstrndx
-# define ehdr_shnum ehdr64_shnum
-# define shdr_addr shdr64_addr
-# define shdr_offset shdr64_offset
-# define shdr_link shdr64_link
-# define shdr_size shdr64_size
-# define shdr_name shdr64_name
-# define shdr_type shdr64_type
-# define shdr_entsize shdr64_entsize
-# define sym_type sym64_type
-# define sym_name sym64_name
-# define sym_value sym64_value
-# define sym_shndx sym64_shndx
-# define long_size 8
-#else
-# define extable_ent_size 8
-# define compare_extable compare_extable_32
-# define get_mcount_loc get_mcount_loc_32
-# define sort_mcount_loc sort_mcount_loc_32
-# define elf_mcount_loc elf_mcount_loc_32
-# define do_sort do_sort_32
-# define ehdr_shoff ehdr32_shoff
-# define ehdr_shentsize ehdr32_shentsize
-# define ehdr_shstrndx ehdr32_shstrndx
-# define ehdr_shnum ehdr32_shnum
-# define shdr_addr shdr32_addr
-# define shdr_offset shdr32_offset
-# define shdr_link shdr32_link
-# define shdr_size shdr32_size
-# define shdr_name shdr32_name
-# define shdr_type shdr32_type
-# define shdr_entsize shdr32_entsize
-# define sym_type sym32_type
-# define sym_name sym32_name
-# define sym_value sym32_value
-# define sym_shndx sym32_shndx
-# define long_size 4
-#endif
-
-#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
-/* ORC unwinder only support X86_64 */
-#include <asm/orc_types.h>
-
-#define ERRSTR_MAXSZ 256
-
-char g_err[ERRSTR_MAXSZ];
-int *g_orc_ip_table;
-struct orc_entry *g_orc_table;
-
-pthread_t orc_sort_thread;
-
-static inline unsigned long orc_ip(const int *ip)
-{
- return (unsigned long)ip + *ip;
-}
-
-static int orc_sort_cmp(const void *_a, const void *_b)
-{
- struct orc_entry *orc_a, *orc_b;
- const int *a = g_orc_ip_table + *(int *)_a;
- const int *b = g_orc_ip_table + *(int *)_b;
- unsigned long a_val = orc_ip(a);
- unsigned long b_val = orc_ip(b);
-
- if (a_val > b_val)
- return 1;
- if (a_val < b_val)
- return -1;
-
- /*
- * The "weak" section terminator entries need to always be on the left
- * to ensure the lookup code skips them in favor of real entries.
- * These terminator entries exist to handle any gaps created by
- * whitelisted .o files which didn't get objtool generation.
- */
- orc_a = g_orc_table + (a - g_orc_ip_table);
- orc_b = g_orc_table + (b - g_orc_ip_table);
- if (orc_a->type == ORC_TYPE_UNDEFINED && orc_b->type == ORC_TYPE_UNDEFINED)
- return 0;
- return orc_a->type == ORC_TYPE_UNDEFINED ? -1 : 1;
-}
-
-static void *sort_orctable(void *arg)
-{
- int i;
- int *idxs = NULL;
- int *tmp_orc_ip_table = NULL;
- struct orc_entry *tmp_orc_table = NULL;
- unsigned int *orc_ip_size = (unsigned int *)arg;
- unsigned int num_entries = *orc_ip_size / sizeof(int);
- unsigned int orc_size = num_entries * sizeof(struct orc_entry);
-
- idxs = (int *)malloc(*orc_ip_size);
- if (!idxs) {
- snprintf(g_err, ERRSTR_MAXSZ, "malloc idxs: %s",
- strerror(errno));
- pthread_exit(g_err);
- }
-
- tmp_orc_ip_table = (int *)malloc(*orc_ip_size);
- if (!tmp_orc_ip_table) {
- snprintf(g_err, ERRSTR_MAXSZ, "malloc tmp_orc_ip_table: %s",
- strerror(errno));
- pthread_exit(g_err);
- }
-
- tmp_orc_table = (struct orc_entry *)malloc(orc_size);
- if (!tmp_orc_table) {
- snprintf(g_err, ERRSTR_MAXSZ, "malloc tmp_orc_table: %s",
- strerror(errno));
- pthread_exit(g_err);
- }
-
- /* initialize indices array, convert ip_table to absolute address */
- for (i = 0; i < num_entries; i++) {
- idxs[i] = i;
- tmp_orc_ip_table[i] = g_orc_ip_table[i] + i * sizeof(int);
- }
- memcpy(tmp_orc_table, g_orc_table, orc_size);
-
- qsort(idxs, num_entries, sizeof(int), orc_sort_cmp);
-
- for (i = 0; i < num_entries; i++) {
- if (idxs[i] == i)
- continue;
-
- /* convert back to relative address */
- g_orc_ip_table[i] = tmp_orc_ip_table[idxs[i]] - i * sizeof(int);
- g_orc_table[i] = tmp_orc_table[idxs[i]];
- }
-
- free(idxs);
- free(tmp_orc_ip_table);
- free(tmp_orc_table);
- pthread_exit(NULL);
-}
-#endif
-
-#ifdef MCOUNT_SORT_ENABLED
-pthread_t mcount_sort_thread;
-
-struct elf_mcount_loc {
- Elf_Ehdr *ehdr;
- Elf_Shdr *init_data_sec;
- uint64_t start_mcount_loc;
- uint64_t stop_mcount_loc;
-};
-
-/* Sort the addresses stored between __start_mcount_loc to __stop_mcount_loc in vmlinux */
-static void *sort_mcount_loc(void *arg)
-{
- struct elf_mcount_loc *emloc = (struct elf_mcount_loc *)arg;
- uint64_t offset = emloc->start_mcount_loc - shdr_addr(emloc->init_data_sec)
- + shdr_offset(emloc->init_data_sec);
- uint64_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
- unsigned char *start_loc = (void *)emloc->ehdr + offset;
-
- qsort(start_loc, count/long_size, long_size, compare_extable);
- return NULL;
-}
-
-/* Get the address of __start_mcount_loc and __stop_mcount_loc in System.map */
-static void get_mcount_loc(uint64_t *_start, uint64_t *_stop)
-{
- FILE *file_start, *file_stop;
- char start_buff[20];
- char stop_buff[20];
- int len = 0;
-
- file_start = popen(" grep start_mcount System.map | awk '{print $1}' ", "r");
- if (!file_start) {
- fprintf(stderr, "get start_mcount_loc error!");
- return;
- }
-
- file_stop = popen(" grep stop_mcount System.map | awk '{print $1}' ", "r");
- if (!file_stop) {
- fprintf(stderr, "get stop_mcount_loc error!");
- pclose(file_start);
- return;
- }
-
- while (fgets(start_buff, sizeof(start_buff), file_start) != NULL) {
- len = strlen(start_buff);
- start_buff[len - 1] = '\0';
- }
- *_start = strtoul(start_buff, NULL, 16);
-
- while (fgets(stop_buff, sizeof(stop_buff), file_stop) != NULL) {
- len = strlen(stop_buff);
- stop_buff[len - 1] = '\0';
- }
- *_stop = strtoul(stop_buff, NULL, 16);
-
- pclose(file_start);
- pclose(file_stop);
-}
-#endif
-static int do_sort(Elf_Ehdr *ehdr,
- char const *const fname,
- table_sort_t custom_sort)
-{
- int rc = -1;
- Elf_Shdr *shdr_start;
- Elf_Shdr *strtab_sec = NULL;
- Elf_Shdr *symtab_sec = NULL;
- Elf_Shdr *extab_sec = NULL;
- Elf_Shdr *string_sec;
- Elf_Sym *sym;
- const Elf_Sym *symtab;
- Elf32_Word *symtab_shndx = NULL;
- Elf_Sym *sort_needed_sym = NULL;
- Elf_Shdr *sort_needed_sec;
- uint32_t *sort_needed_loc;
- void *sym_start;
- void *sym_end;
- const char *secstrings;
- const char *strtab;
- char *extab_image;
- int sort_need_index;
- int symentsize;
- int shentsize;
- int idx;
- int i;
- unsigned int shnum;
- unsigned int shstrndx;
-#ifdef MCOUNT_SORT_ENABLED
- struct elf_mcount_loc mstruct = {0};
- uint64_t _start_mcount_loc = 0;
- uint64_t _stop_mcount_loc = 0;
-#endif
-#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
- unsigned int orc_ip_size = 0;
- unsigned int orc_size = 0;
- unsigned int orc_num_entries = 0;
-#endif
-
- shdr_start = (Elf_Shdr *)((char *)ehdr + ehdr_shoff(ehdr));
- shentsize = ehdr_shentsize(ehdr);
-
- shstrndx = ehdr_shstrndx(ehdr);
- if (shstrndx == SHN_XINDEX)
- shstrndx = shdr_link(shdr_start);
- string_sec = get_index(shdr_start, shentsize, shstrndx);
- secstrings = (const char *)ehdr + shdr_offset(string_sec);
-
- shnum = ehdr_shnum(ehdr);
- if (shnum == SHN_UNDEF)
- shnum = shdr_size(shdr_start);
-
- for (i = 0; i < shnum; i++) {
- Elf_Shdr *shdr = get_index(shdr_start, shentsize, i);
-
- idx = shdr_name(shdr);
- if (!strcmp(secstrings + idx, "__ex_table"))
- extab_sec = shdr;
- if (!strcmp(secstrings + idx, ".symtab"))
- symtab_sec = shdr;
- if (!strcmp(secstrings + idx, ".strtab"))
- strtab_sec = shdr;
-
- if (shdr_type(shdr) == SHT_SYMTAB_SHNDX)
- symtab_shndx = (Elf32_Word *)((const char *)ehdr +
- shdr_offset(shdr));
-
-#ifdef MCOUNT_SORT_ENABLED
- /* locate the .init.data section in vmlinux */
- if (!strcmp(secstrings + idx, ".init.data")) {
- get_mcount_loc(&_start_mcount_loc, &_stop_mcount_loc);
- mstruct.ehdr = ehdr;
- mstruct.init_data_sec = shdr;
- mstruct.start_mcount_loc = _start_mcount_loc;
- mstruct.stop_mcount_loc = _stop_mcount_loc;
- }
-#endif
-
-#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
- /* locate the ORC unwind tables */
- if (!strcmp(secstrings + idx, ".orc_unwind_ip")) {
- orc_ip_size = shdr_size(shdr);
- g_orc_ip_table = (int *)((void *)ehdr +
- shdr_offset(shdr));
- }
- if (!strcmp(secstrings + idx, ".orc_unwind")) {
- orc_size = shdr_size(shdr);
- g_orc_table = (struct orc_entry *)((void *)ehdr +
- shdr_offset(shdr));
- }
-#endif
- } /* for loop */
-
-#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
- if (!g_orc_ip_table || !g_orc_table) {
- fprintf(stderr,
- "incomplete ORC unwind tables in file: %s\n", fname);
- goto out;
- }
-
- orc_num_entries = orc_ip_size / sizeof(int);
- if (orc_ip_size % sizeof(int) != 0 ||
- orc_size % sizeof(struct orc_entry) != 0 ||
- orc_num_entries != orc_size / sizeof(struct orc_entry)) {
- fprintf(stderr,
- "inconsistent ORC unwind table entries in file: %s\n",
- fname);
- goto out;
- }
-
- /* create thread to sort ORC unwind tables concurrently */
- if (pthread_create(&orc_sort_thread, NULL,
- sort_orctable, &orc_ip_size)) {
- fprintf(stderr,
- "pthread_create orc_sort_thread failed '%s': %s\n",
- strerror(errno), fname);
- goto out;
- }
-#endif
-
-#ifdef MCOUNT_SORT_ENABLED
- if (!mstruct.init_data_sec || !_start_mcount_loc || !_stop_mcount_loc) {
- fprintf(stderr,
- "incomplete mcount's sort in file: %s\n",
- fname);
- goto out;
- }
-
- /* create thread to sort mcount_loc concurrently */
- if (pthread_create(&mcount_sort_thread, NULL, &sort_mcount_loc, &mstruct)) {
- fprintf(stderr,
- "pthread_create mcount_sort_thread failed '%s': %s\n",
- strerror(errno), fname);
- goto out;
- }
-#endif
- if (!extab_sec) {
- fprintf(stderr, "no __ex_table in file: %s\n", fname);
- goto out;
- }
-
- if (!symtab_sec) {
- fprintf(stderr, "no .symtab in file: %s\n", fname);
- goto out;
- }
-
- if (!strtab_sec) {
- fprintf(stderr, "no .strtab in file: %s\n", fname);
- goto out;
- }
-
- extab_image = (void *)ehdr + shdr_offset(extab_sec);
- strtab = (const char *)ehdr + shdr_offset(strtab_sec);
- symtab = (const Elf_Sym *)((const char *)ehdr + shdr_offset(symtab_sec));
-
- if (custom_sort) {
- custom_sort(extab_image, shdr_size(extab_sec));
- } else {
- int num_entries = shdr_size(extab_sec) / extable_ent_size;
- qsort(extab_image, num_entries,
- extable_ent_size, compare_extable);
- }
-
- /* find the flag main_extable_sort_needed */
- sym_start = (void *)ehdr + shdr_offset(symtab_sec);
- sym_end = sym_start + shdr_size(symtab_sec);
- symentsize = shdr_entsize(symtab_sec);
-
- for (sym = sym_start; (void *)sym + symentsize < sym_end;
- sym = (void *)sym + symentsize) {
- if (sym_type(sym) != STT_OBJECT)
- continue;
- if (!strcmp(strtab + sym_name(sym),
- "main_extable_sort_needed")) {
- sort_needed_sym = sym;
- break;
- }
- }
-
- if (!sort_needed_sym) {
- fprintf(stderr,
- "no main_extable_sort_needed symbol in file: %s\n",
- fname);
- goto out;
- }
-
- sort_need_index = get_secindex(sym_shndx(sym),
- ((void *)sort_needed_sym - (void *)symtab) / symentsize,
- symtab_shndx);
- sort_needed_sec = get_index(shdr_start, shentsize, sort_need_index);
- sort_needed_loc = (void *)ehdr +
- shdr_offset(sort_needed_sec) +
- sym_value(sort_needed_sym) - shdr_addr(sort_needed_sec);
-
- /* extable has been sorted, clear the flag */
- w(0, sort_needed_loc);
- rc = 0;
-
-out:
-#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
- if (orc_sort_thread) {
- void *retval = NULL;
- /* wait for ORC tables sort done */
- rc = pthread_join(orc_sort_thread, &retval);
- if (rc) {
- fprintf(stderr,
- "pthread_join failed '%s': %s\n",
- strerror(errno), fname);
- } else if (retval) {
- rc = -1;
- fprintf(stderr,
- "failed to sort ORC tables '%s': %s\n",
- (char *)retval, fname);
- }
- }
-#endif
-
-#ifdef MCOUNT_SORT_ENABLED
- if (mcount_sort_thread) {
- void *retval = NULL;
- /* wait for mcount sort done */
- rc = pthread_join(mcount_sort_thread, &retval);
- if (rc) {
- fprintf(stderr,
- "pthread_join failed '%s': %s\n",
- strerror(errno), fname);
- } else if (retval) {
- rc = -1;
- fprintf(stderr,
- "failed to sort mcount '%s': %s\n",
- (char *)retval, fname);
- }
- }
-#endif
- return rc;
-}
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 6.6 057/175] scripts/sorttable: Get start/stop_mcount_loc from ELF file directly
[not found] <20260702155115.766838875@linuxfoundation.org>
` (12 preceding siblings ...)
2026-07-02 16:19 ` [PATCH 6.6 056/175] scripts/sorttable: Move code from sorttable.h into sorttable.c Greg Kroah-Hartman
@ 2026-07-02 16:19 ` Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 058/175] scripts/sorttable: Use a structure of function pointers for elf helpers Greg Kroah-Hartman
` (6 subsequent siblings)
20 siblings, 0 replies; 21+ messages in thread
From: Greg Kroah-Hartman @ 2026-07-02 16:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, bpf, Masami Hiramatsu, Mark Rutland,
Mathieu Desnoyers, Andrew Morton, Peter Zijlstra, Linus Torvalds,
Masahiro Yamada, Nathan Chancellor, Nicolas Schier, Zheng Yejian,
Martin Kelly, Christophe Leroy, Josh Poimboeuf,
Steven Rostedt (Google), Andrey Grodzovsky
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 4acda8edefa1ce66d3de845f1c12745721cd14c3 ]
The get_mcount_loc() does a cheesy trick to find the start_mcount_loc and
stop_mcount_loc values. That trick is:
file_start = popen(" grep start_mcount System.map | awk '{print $1}' ", "r");
and
file_stop = popen(" grep stop_mcount System.map | awk '{print $1}' ", "r");
Those values are stored in the Elf symbol table. Use that to capture those
values. Using the symbol table is more efficient and more robust. The
above could fail if another variable had "start_mcount" or "stop_mcount"
as part of its name.
Cc: bpf <bpf@vger.kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: Zheng Yejian <zhengyejian1@huawei.com>
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Link: https://lore.kernel.org/20250105162346.817157047@goodmis.org
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
scripts/sorttable.c | 95 ++++++++++++++++++++++++----------------------------
1 file changed, 45 insertions(+), 50 deletions(-)
--- a/scripts/sorttable.c
+++ b/scripts/sorttable.c
@@ -472,42 +472,41 @@ static void *sort_mcount_loc(void *arg)
}
/* Get the address of __start_mcount_loc and __stop_mcount_loc in System.map */
-static void get_mcount_loc(uint64_t *_start, uint64_t *_stop)
+static void get_mcount_loc(struct elf_mcount_loc *emloc, Elf_Shdr *symtab_sec,
+ const char *strtab)
{
- FILE *file_start, *file_stop;
- char start_buff[20];
- char stop_buff[20];
- int len = 0;
+ Elf_Sym *sym, *end_sym;
+ int symentsize = shdr_entsize(symtab_sec);
+ int found = 0;
+
+ sym = (void *)emloc->ehdr + shdr_offset(symtab_sec);
+ end_sym = (void *)sym + shdr_size(symtab_sec);
+
+ while (sym < end_sym) {
+ if (!strcmp(strtab + sym_name(sym), "__start_mcount_loc")) {
+ emloc->start_mcount_loc = sym_value(sym);
+ if (++found == 2)
+ break;
+ } else if (!strcmp(strtab + sym_name(sym), "__stop_mcount_loc")) {
+ emloc->stop_mcount_loc = sym_value(sym);
+ if (++found == 2)
+ break;
+ }
+ sym = (void *)sym + symentsize;
+ }
- file_start = popen(" grep start_mcount System.map | awk '{print $1}' ", "r");
- if (!file_start) {
+ if (!emloc->start_mcount_loc) {
fprintf(stderr, "get start_mcount_loc error!");
return;
}
- file_stop = popen(" grep stop_mcount System.map | awk '{print $1}' ", "r");
- if (!file_stop) {
+ if (!emloc->stop_mcount_loc) {
fprintf(stderr, "get stop_mcount_loc error!");
- pclose(file_start);
return;
}
-
- while (fgets(start_buff, sizeof(start_buff), file_start) != NULL) {
- len = strlen(start_buff);
- start_buff[len - 1] = '\0';
- }
- *_start = strtoul(start_buff, NULL, 16);
-
- while (fgets(stop_buff, sizeof(stop_buff), file_stop) != NULL) {
- len = strlen(stop_buff);
- stop_buff[len - 1] = '\0';
- }
- *_stop = strtoul(stop_buff, NULL, 16);
-
- pclose(file_start);
- pclose(file_stop);
}
#endif
+
static int do_sort(Elf_Ehdr *ehdr,
char const *const fname,
table_sort_t custom_sort)
@@ -538,8 +537,6 @@ static int do_sort(Elf_Ehdr *ehdr,
unsigned int shstrndx;
#ifdef MCOUNT_SORT_ENABLED
struct elf_mcount_loc mstruct = {0};
- uint64_t _start_mcount_loc = 0;
- uint64_t _stop_mcount_loc = 0;
#endif
#ifdef UNWINDER_ORC_ENABLED
unsigned int orc_ip_size = 0;
@@ -577,13 +574,8 @@ static int do_sort(Elf_Ehdr *ehdr,
#ifdef MCOUNT_SORT_ENABLED
/* locate the .init.data section in vmlinux */
- if (!strcmp(secstrings + idx, ".init.data")) {
- get_mcount_loc(&_start_mcount_loc, &_stop_mcount_loc);
- mstruct.ehdr = ehdr;
+ if (!strcmp(secstrings + idx, ".init.data"))
mstruct.init_data_sec = shdr;
- mstruct.start_mcount_loc = _start_mcount_loc;
- mstruct.stop_mcount_loc = _stop_mcount_loc;
- }
#endif
#ifdef UNWINDER_ORC_ENABLED
@@ -627,23 +619,6 @@ static int do_sort(Elf_Ehdr *ehdr,
goto out;
}
#endif
-
-#ifdef MCOUNT_SORT_ENABLED
- if (!mstruct.init_data_sec || !_start_mcount_loc || !_stop_mcount_loc) {
- fprintf(stderr,
- "incomplete mcount's sort in file: %s\n",
- fname);
- goto out;
- }
-
- /* create thread to sort mcount_loc concurrently */
- if (pthread_create(&mcount_sort_thread, NULL, &sort_mcount_loc, &mstruct)) {
- fprintf(stderr,
- "pthread_create mcount_sort_thread failed '%s': %s\n",
- strerror(errno), fname);
- goto out;
- }
-#endif
if (!extab_sec) {
fprintf(stderr, "no __ex_table in file: %s\n", fname);
goto out;
@@ -663,6 +638,26 @@ static int do_sort(Elf_Ehdr *ehdr,
strtab = (const char *)ehdr + shdr_offset(strtab_sec);
symtab = (const Elf_Sym *)((const char *)ehdr + shdr_offset(symtab_sec));
+#ifdef MCOUNT_SORT_ENABLED
+ mstruct.ehdr = ehdr;
+ get_mcount_loc(&mstruct, symtab_sec, strtab);
+
+ if (!mstruct.init_data_sec || !mstruct.start_mcount_loc || !mstruct.stop_mcount_loc) {
+ fprintf(stderr,
+ "incomplete mcount's sort in file: %s\n",
+ fname);
+ goto out;
+ }
+
+ /* create thread to sort mcount_loc concurrently */
+ if (pthread_create(&mcount_sort_thread, NULL, &sort_mcount_loc, &mstruct)) {
+ fprintf(stderr,
+ "pthread_create mcount_sort_thread failed '%s': %s\n",
+ strerror(errno), fname);
+ goto out;
+ }
+#endif
+
if (custom_sort) {
custom_sort(extab_image, shdr_size(extab_sec));
} else {
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 6.6 058/175] scripts/sorttable: Use a structure of function pointers for elf helpers
[not found] <20260702155115.766838875@linuxfoundation.org>
` (13 preceding siblings ...)
2026-07-02 16:19 ` [PATCH 6.6 057/175] scripts/sorttable: Get start/stop_mcount_loc from ELF file directly Greg Kroah-Hartman
@ 2026-07-02 16:19 ` Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 059/175] arm64: scripts/sorttable: Implement sorting mcount_loc at boot for arm64 Greg Kroah-Hartman
` (5 subsequent siblings)
20 siblings, 0 replies; 21+ messages in thread
From: Greg Kroah-Hartman @ 2026-07-02 16:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, bpf, Masami Hiramatsu, Mark Rutland,
Mathieu Desnoyers, Andrew Morton, Peter Zijlstra, Masahiro Yamada,
Nathan Chancellor, Nicolas Schier, Zheng Yejian, Martin Kelly,
Christophe Leroy, Josh Poimboeuf, Stephen Rothwell,
Linus Torvalds, Steven Rostedt (Google), Andrey Grodzovsky
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 1e5f6771c247b28135307058d2cfe3b0153733dc ]
Instead of having a series of function pointers that gets assigned to the
Elf64 or Elf32 versions, put them all into a single structure and use
that. Add the helper function that chooses the structure into the macros
that build the different versions of the elf functions.
Link: https://lore.kernel.org/all/CAHk-=wiafEyX7UgOeZgvd6fvuByE5WXUPh9599kwOc_d-pdeug@mail.gmail.com/
Cc: bpf <bpf@vger.kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: Zheng Yejian <zhengyejian1@huawei.com>
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Link: https://lore.kernel.org/20250110075459.13d4b94c@gandalf.local.home
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
scripts/sorttable.c | 175 +++++++++++++++++++++++++++++++++++-----------------
1 file changed, 118 insertions(+), 57 deletions(-)
--- a/scripts/sorttable.c
+++ b/scripts/sorttable.c
@@ -85,6 +85,25 @@ static uint64_t (*r8)(const uint64_t *);
static void (*w)(uint32_t, uint32_t *);
typedef void (*table_sort_t)(char *, int);
+static struct elf_funcs {
+ int (*compare_extable)(const void *a, const void *b);
+ uint64_t (*ehdr_shoff)(Elf_Ehdr *ehdr);
+ uint16_t (*ehdr_shstrndx)(Elf_Ehdr *ehdr);
+ uint16_t (*ehdr_shentsize)(Elf_Ehdr *ehdr);
+ uint16_t (*ehdr_shnum)(Elf_Ehdr *ehdr);
+ uint64_t (*shdr_addr)(Elf_Shdr *shdr);
+ uint64_t (*shdr_offset)(Elf_Shdr *shdr);
+ uint64_t (*shdr_size)(Elf_Shdr *shdr);
+ uint64_t (*shdr_entsize)(Elf_Shdr *shdr);
+ uint32_t (*shdr_link)(Elf_Shdr *shdr);
+ uint32_t (*shdr_name)(Elf_Shdr *shdr);
+ uint32_t (*shdr_type)(Elf_Shdr *shdr);
+ uint8_t (*sym_type)(Elf_Sym *sym);
+ uint32_t (*sym_name)(Elf_Sym *sym);
+ uint64_t (*sym_value)(Elf_Sym *sym);
+ uint16_t (*sym_shndx)(Elf_Sym *sym);
+} e;
+
static uint64_t ehdr64_shoff(Elf_Ehdr *ehdr)
{
return r8(&ehdr->e64.e_shoff);
@@ -95,6 +114,11 @@ static uint64_t ehdr32_shoff(Elf_Ehdr *e
return r(&ehdr->e32.e_shoff);
}
+static uint64_t ehdr_shoff(Elf_Ehdr *ehdr)
+{
+ return e.ehdr_shoff(ehdr);
+}
+
#define EHDR_HALF(fn_name) \
static uint16_t ehdr64_##fn_name(Elf_Ehdr *ehdr) \
{ \
@@ -104,6 +128,11 @@ static uint16_t ehdr64_##fn_name(Elf_Ehd
static uint16_t ehdr32_##fn_name(Elf_Ehdr *ehdr) \
{ \
return r2(&ehdr->e32.e_##fn_name); \
+} \
+ \
+static uint16_t ehdr_##fn_name(Elf_Ehdr *ehdr) \
+{ \
+ return e.ehdr_##fn_name(ehdr); \
}
EHDR_HALF(shentsize)
@@ -119,6 +148,11 @@ static uint32_t shdr64_##fn_name(Elf_Shd
static uint32_t shdr32_##fn_name(Elf_Shdr *shdr) \
{ \
return r(&shdr->e32.sh_##fn_name); \
+} \
+ \
+static uint32_t shdr_##fn_name(Elf_Shdr *shdr) \
+{ \
+ return e.shdr_##fn_name(shdr); \
}
#define SHDR_ADDR(fn_name) \
@@ -130,6 +164,11 @@ static uint64_t shdr64_##fn_name(Elf_Shd
static uint64_t shdr32_##fn_name(Elf_Shdr *shdr) \
{ \
return r(&shdr->e32.sh_##fn_name); \
+} \
+ \
+static uint64_t shdr_##fn_name(Elf_Shdr *shdr) \
+{ \
+ return e.shdr_##fn_name(shdr); \
}
#define SHDR_WORD(fn_name) \
@@ -141,6 +180,10 @@ static uint32_t shdr64_##fn_name(Elf_Shd
static uint32_t shdr32_##fn_name(Elf_Shdr *shdr) \
{ \
return r(&shdr->e32.sh_##fn_name); \
+} \
+static uint32_t shdr_##fn_name(Elf_Shdr *shdr) \
+{ \
+ return e.shdr_##fn_name(shdr); \
}
SHDR_ADDR(addr)
@@ -161,6 +204,11 @@ static uint64_t sym64_##fn_name(Elf_Sym
static uint64_t sym32_##fn_name(Elf_Sym *sym) \
{ \
return r(&sym->e32.st_##fn_name); \
+} \
+ \
+static uint64_t sym_##fn_name(Elf_Sym *sym) \
+{ \
+ return e.sym_##fn_name(sym); \
}
#define SYM_WORD(fn_name) \
@@ -172,6 +220,11 @@ static uint32_t sym64_##fn_name(Elf_Sym
static uint32_t sym32_##fn_name(Elf_Sym *sym) \
{ \
return r(&sym->e32.st_##fn_name); \
+} \
+ \
+static uint32_t sym_##fn_name(Elf_Sym *sym) \
+{ \
+ return e.sym_##fn_name(sym); \
}
#define SYM_HALF(fn_name) \
@@ -183,6 +236,11 @@ static uint16_t sym64_##fn_name(Elf_Sym
static uint16_t sym32_##fn_name(Elf_Sym *sym) \
{ \
return r2(&sym->e32.st_##fn_name); \
+} \
+ \
+static uint16_t sym_##fn_name(Elf_Sym *sym) \
+{ \
+ return e.sym_##fn_name(sym); \
}
static uint8_t sym64_type(Elf_Sym *sym)
@@ -195,6 +253,11 @@ static uint8_t sym32_type(Elf_Sym *sym)
return ELF32_ST_TYPE(sym->e32.st_info);
}
+static uint8_t sym_type(Elf_Sym *sym)
+{
+ return e.sym_type(sym);
+}
+
SYM_ADDR(value)
SYM_WORD(name)
SYM_HALF(shndx)
@@ -322,29 +385,16 @@ static int compare_extable_64(const void
return av > bv;
}
+static int compare_extable(const void *a, const void *b)
+{
+ return e.compare_extable(a, b);
+}
+
static inline void *get_index(void *start, int entsize, int index)
{
return start + (entsize * index);
}
-
-static int (*compare_extable)(const void *a, const void *b);
-static uint64_t (*ehdr_shoff)(Elf_Ehdr *ehdr);
-static uint16_t (*ehdr_shstrndx)(Elf_Ehdr *ehdr);
-static uint16_t (*ehdr_shentsize)(Elf_Ehdr *ehdr);
-static uint16_t (*ehdr_shnum)(Elf_Ehdr *ehdr);
-static uint64_t (*shdr_addr)(Elf_Shdr *shdr);
-static uint64_t (*shdr_offset)(Elf_Shdr *shdr);
-static uint64_t (*shdr_size)(Elf_Shdr *shdr);
-static uint64_t (*shdr_entsize)(Elf_Shdr *shdr);
-static uint32_t (*shdr_link)(Elf_Shdr *shdr);
-static uint32_t (*shdr_name)(Elf_Shdr *shdr);
-static uint32_t (*shdr_type)(Elf_Shdr *shdr);
-static uint8_t (*sym_type)(Elf_Sym *sym);
-static uint32_t (*sym_name)(Elf_Sym *sym);
-static uint64_t (*sym_value)(Elf_Sym *sym);
-static uint16_t (*sym_shndx)(Elf_Sym *sym);
-
static int extable_ent_size;
static int long_size;
@@ -864,7 +914,30 @@ static int do_file(char const *const fna
}
switch (ehdr->e32.e_ident[EI_CLASS]) {
- case ELFCLASS32:
+ case ELFCLASS32: {
+ struct elf_funcs efuncs = {
+ .compare_extable = compare_extable_32,
+ .ehdr_shoff = ehdr32_shoff,
+ .ehdr_shentsize = ehdr32_shentsize,
+ .ehdr_shstrndx = ehdr32_shstrndx,
+ .ehdr_shnum = ehdr32_shnum,
+ .shdr_addr = shdr32_addr,
+ .shdr_offset = shdr32_offset,
+ .shdr_link = shdr32_link,
+ .shdr_size = shdr32_size,
+ .shdr_name = shdr32_name,
+ .shdr_type = shdr32_type,
+ .shdr_entsize = shdr32_entsize,
+ .sym_type = sym32_type,
+ .sym_name = sym32_name,
+ .sym_value = sym32_value,
+ .sym_shndx = sym32_shndx,
+ };
+
+ e = efuncs;
+ long_size = 4;
+ extable_ent_size = 8;
+
if (r2(&ehdr->e32.e_ehsize) != sizeof(Elf32_Ehdr) ||
r2(&ehdr->e32.e_shentsize) != sizeof(Elf32_Shdr)) {
fprintf(stderr,
@@ -872,26 +945,32 @@ static int do_file(char const *const fna
return -1;
}
- compare_extable = compare_extable_32;
- ehdr_shoff = ehdr32_shoff;
- ehdr_shentsize = ehdr32_shentsize;
- ehdr_shstrndx = ehdr32_shstrndx;
- ehdr_shnum = ehdr32_shnum;
- shdr_addr = shdr32_addr;
- shdr_offset = shdr32_offset;
- shdr_link = shdr32_link;
- shdr_size = shdr32_size;
- shdr_name = shdr32_name;
- shdr_type = shdr32_type;
- shdr_entsize = shdr32_entsize;
- sym_type = sym32_type;
- sym_name = sym32_name;
- sym_value = sym32_value;
- sym_shndx = sym32_shndx;
- long_size = 4;
- extable_ent_size = 8;
+ }
break;
- case ELFCLASS64:
+ case ELFCLASS64: {
+ struct elf_funcs efuncs = {
+ .compare_extable = compare_extable_64,
+ .ehdr_shoff = ehdr64_shoff,
+ .ehdr_shentsize = ehdr64_shentsize,
+ .ehdr_shstrndx = ehdr64_shstrndx,
+ .ehdr_shnum = ehdr64_shnum,
+ .shdr_addr = shdr64_addr,
+ .shdr_offset = shdr64_offset,
+ .shdr_link = shdr64_link,
+ .shdr_size = shdr64_size,
+ .shdr_name = shdr64_name,
+ .shdr_type = shdr64_type,
+ .shdr_entsize = shdr64_entsize,
+ .sym_type = sym64_type,
+ .sym_name = sym64_name,
+ .sym_value = sym64_value,
+ .sym_shndx = sym64_shndx,
+ };
+
+ e = efuncs;
+ long_size = 8;
+ extable_ent_size = 16;
+
if (r2(&ehdr->e64.e_ehsize) != sizeof(Elf64_Ehdr) ||
r2(&ehdr->e64.e_shentsize) != sizeof(Elf64_Shdr)) {
fprintf(stderr,
@@ -900,25 +979,7 @@ static int do_file(char const *const fna
return -1;
}
- compare_extable = compare_extable_64;
- ehdr_shoff = ehdr64_shoff;
- ehdr_shentsize = ehdr64_shentsize;
- ehdr_shstrndx = ehdr64_shstrndx;
- ehdr_shnum = ehdr64_shnum;
- shdr_addr = shdr64_addr;
- shdr_offset = shdr64_offset;
- shdr_link = shdr64_link;
- shdr_size = shdr64_size;
- shdr_name = shdr64_name;
- shdr_type = shdr64_type;
- shdr_entsize = shdr64_entsize;
- sym_type = sym64_type;
- sym_name = sym64_name;
- sym_value = sym64_value;
- sym_shndx = sym64_shndx;
- long_size = 8;
- extable_ent_size = 16;
-
+ }
break;
default:
fprintf(stderr, "unrecognized ELF class %d %s\n",
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 6.6 059/175] arm64: scripts/sorttable: Implement sorting mcount_loc at boot for arm64
[not found] <20260702155115.766838875@linuxfoundation.org>
` (14 preceding siblings ...)
2026-07-02 16:19 ` [PATCH 6.6 058/175] scripts/sorttable: Use a structure of function pointers for elf helpers Greg Kroah-Hartman
@ 2026-07-02 16:19 ` Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 060/175] scripts/sorttable: Have mcount rela sort use direct values Greg Kroah-Hartman
` (4 subsequent siblings)
20 siblings, 0 replies; 21+ messages in thread
From: Greg Kroah-Hartman @ 2026-07-02 16:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, bpf, Masami Hiramatsu, Mark Rutland,
Mathieu Desnoyers, Andrew Morton, Peter Zijlstra, Linus Torvalds,
Masahiro Yamada, Nathan Chancellor, Nicolas Schier, Zheng Yejian,
Martin Kelly, Christophe Leroy, Josh Poimboeuf, Heiko Carstens,
Will Deacon, Vasily Gorbik, Alexander Gordeev, Catalin Marinas,
Steven Rostedt (Google), Andrey Grodzovsky
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit b3d09d06e052e1d754645acea4e4d1e96f81c934 ]
The mcount_loc section holds the addresses of the functions that get
patched by ftrace when enabling function callbacks. It can contain tens of
thousands of entries. These addresses must be sorted. If they are not
sorted at compile time, they are sorted at boot. Sorting at boot does take
some time and does have a small impact on boot performance.
x86 and arm32 have the addresses in the mcount_loc section of the ELF
file. But for arm64, the section just contains zeros. The .rela.dyn
Elf_Rela section holds the addresses and they get patched at boot during
the relocation phase.
In order to sort these addresses, the Elf_Rela needs to be updated instead
of the location in the binary that holds the mcount_loc section. Have the
sorttable code, allocate an array to hold the functions, load the
addresses from the Elf_Rela entries, sort them, then put them back in
order into the Elf_rela entries so that they will be sorted at boot up
without having to sort them during boot up.
Cc: bpf <bpf@vger.kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: Zheng Yejian <zhengyejian1@huawei.com>
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Link: https://lore.kernel.org/20250218200022.373319428@goodmis.org
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/arm64/Kconfig | 1
scripts/sorttable.c | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 183 insertions(+), 3 deletions(-)
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -202,6 +202,7 @@ config ARM64
if DYNAMIC_FTRACE_WITH_ARGS
select HAVE_SAMPLE_FTRACE_DIRECT
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
+ select HAVE_BUILDTIME_MCOUNT_SORT
select HAVE_EFFICIENT_UNALIGNED_ACCESS
select HAVE_FAST_GUP
select HAVE_FTRACE_MCOUNT_RECORD
--- a/scripts/sorttable.c
+++ b/scripts/sorttable.c
@@ -28,6 +28,7 @@
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
@@ -79,10 +80,16 @@ typedef union {
Elf64_Sym e64;
} Elf_Sym;
+typedef union {
+ Elf32_Rela e32;
+ Elf64_Rela e64;
+} Elf_Rela;
+
static uint32_t (*r)(const uint32_t *);
static uint16_t (*r2)(const uint16_t *);
static uint64_t (*r8)(const uint64_t *);
static void (*w)(uint32_t, uint32_t *);
+static void (*w8)(uint64_t, uint64_t *);
typedef void (*table_sort_t)(char *, int);
static struct elf_funcs {
@@ -102,6 +109,10 @@ static struct elf_funcs {
uint32_t (*sym_name)(Elf_Sym *sym);
uint64_t (*sym_value)(Elf_Sym *sym);
uint16_t (*sym_shndx)(Elf_Sym *sym);
+ uint64_t (*rela_offset)(Elf_Rela *rela);
+ uint64_t (*rela_info)(Elf_Rela *rela);
+ uint64_t (*rela_addend)(Elf_Rela *rela);
+ void (*rela_write_addend)(Elf_Rela *rela, uint64_t val);
} e;
static uint64_t ehdr64_shoff(Elf_Ehdr *ehdr)
@@ -262,6 +273,38 @@ SYM_ADDR(value)
SYM_WORD(name)
SYM_HALF(shndx)
+#define __maybe_unused __attribute__((__unused__))
+
+#define RELA_ADDR(fn_name) \
+static uint64_t rela64_##fn_name(Elf_Rela *rela) \
+{ \
+ return r8((uint64_t *)&rela->e64.r_##fn_name); \
+} \
+ \
+static uint64_t rela32_##fn_name(Elf_Rela *rela) \
+{ \
+ return r((uint32_t *)&rela->e32.r_##fn_name); \
+} \
+ \
+static uint64_t __maybe_unused rela_##fn_name(Elf_Rela *rela) \
+{ \
+ return e.rela_##fn_name(rela); \
+}
+
+RELA_ADDR(offset)
+RELA_ADDR(info)
+RELA_ADDR(addend)
+
+static void rela64_write_addend(Elf_Rela *rela, uint64_t val)
+{
+ w8(val, (uint64_t *)&rela->e64.r_addend);
+}
+
+static void rela32_write_addend(Elf_Rela *rela, uint64_t val)
+{
+ w(val, (uint32_t *)&rela->e32.r_addend);
+}
+
/*
* Get the whole file as a programming convenience in order to avoid
* malloc+lseek+read+free of many pieces. If successful, then mmap
@@ -341,6 +384,16 @@ static void wle(uint32_t val, uint32_t *
put_unaligned_le32(val, x);
}
+static void w8be(uint64_t val, uint64_t *x)
+{
+ put_unaligned_be64(val, x);
+}
+
+static void w8le(uint64_t val, uint64_t *x)
+{
+ put_unaligned_le64(val, x);
+}
+
/*
* Move reserved section indices SHN_LORESERVE..SHN_HIRESERVE out of
* the way to -256..-1, to avoid conflicting with real section
@@ -398,13 +451,12 @@ static inline void *get_index(void *star
static int extable_ent_size;
static int long_size;
+#define ERRSTR_MAXSZ 256
#ifdef UNWINDER_ORC_ENABLED
/* ORC unwinder only support X86_64 */
#include <asm/orc_types.h>
-#define ERRSTR_MAXSZ 256
-
static char g_err[ERRSTR_MAXSZ];
static int *g_orc_ip_table;
static struct orc_entry *g_orc_table;
@@ -499,7 +551,19 @@ static void *sort_orctable(void *arg)
#endif
#ifdef MCOUNT_SORT_ENABLED
+
+/* Only used for sorting mcount table */
+static void rela_write_addend(Elf_Rela *rela, uint64_t val)
+{
+ e.rela_write_addend(rela, val);
+}
+
static pthread_t mcount_sort_thread;
+static bool sort_reloc;
+
+static long rela_type;
+
+static char m_err[ERRSTR_MAXSZ];
struct elf_mcount_loc {
Elf_Ehdr *ehdr;
@@ -508,6 +572,103 @@ struct elf_mcount_loc {
uint64_t stop_mcount_loc;
};
+/* Sort the relocations not the address itself */
+static void *sort_relocs(Elf_Ehdr *ehdr, uint64_t start_loc, uint64_t size)
+{
+ Elf_Shdr *shdr_start;
+ Elf_Rela *rel;
+ unsigned int shnum;
+ unsigned int count;
+ int shentsize;
+ void *vals;
+ void *ptr;
+
+ shdr_start = (Elf_Shdr *)((char *)ehdr + ehdr_shoff(ehdr));
+ shentsize = ehdr_shentsize(ehdr);
+
+ vals = malloc(long_size * size);
+ if (!vals) {
+ snprintf(m_err, ERRSTR_MAXSZ, "Failed to allocate sort array");
+ pthread_exit(m_err);
+ return NULL;
+ }
+
+ ptr = vals;
+
+ shnum = ehdr_shnum(ehdr);
+ if (shnum == SHN_UNDEF)
+ shnum = shdr_size(shdr_start);
+
+ for (int i = 0; i < shnum; i++) {
+ Elf_Shdr *shdr = get_index(shdr_start, shentsize, i);
+ void *end;
+
+ if (shdr_type(shdr) != SHT_RELA)
+ continue;
+
+ rel = (void *)ehdr + shdr_offset(shdr);
+ end = (void *)rel + shdr_size(shdr);
+
+ for (; (void *)rel < end; rel = (void *)rel + shdr_entsize(shdr)) {
+ uint64_t offset = rela_offset(rel);
+
+ if (offset >= start_loc && offset < start_loc + size) {
+ if (ptr + long_size > vals + size) {
+ free(vals);
+ snprintf(m_err, ERRSTR_MAXSZ,
+ "Too many relocations");
+ pthread_exit(m_err);
+ return NULL;
+ }
+
+ /* Make sure this has the correct type */
+ if (rela_info(rel) != rela_type) {
+ free(vals);
+ snprintf(m_err, ERRSTR_MAXSZ,
+ "rela has type %lx but expected %lx\n",
+ (long)rela_info(rel), rela_type);
+ pthread_exit(m_err);
+ return NULL;
+ }
+
+ if (long_size == 4)
+ *(uint32_t *)ptr = rela_addend(rel);
+ else
+ *(uint64_t *)ptr = rela_addend(rel);
+ ptr += long_size;
+ }
+ }
+ }
+ count = ptr - vals;
+ qsort(vals, count / long_size, long_size, compare_extable);
+
+ ptr = vals;
+ for (int i = 0; i < shnum; i++) {
+ Elf_Shdr *shdr = get_index(shdr_start, shentsize, i);
+ void *end;
+
+ if (shdr_type(shdr) != SHT_RELA)
+ continue;
+
+ rel = (void *)ehdr + shdr_offset(shdr);
+ end = (void *)rel + shdr_size(shdr);
+
+ for (; (void *)rel < end; rel = (void *)rel + shdr_entsize(shdr)) {
+ uint64_t offset = rela_offset(rel);
+
+ if (offset >= start_loc && offset < start_loc + size) {
+ if (long_size == 4)
+ rela_write_addend(rel, *(uint32_t *)ptr);
+ else
+ rela_write_addend(rel, *(uint64_t *)ptr);
+ ptr += long_size;
+ }
+ }
+ }
+ free(vals);
+ return NULL;
+}
+
/* Sort the addresses stored between __start_mcount_loc to __stop_mcount_loc in vmlinux */
static void *sort_mcount_loc(void *arg)
{
@@ -517,6 +678,9 @@ static void *sort_mcount_loc(void *arg)
uint64_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
unsigned char *start_loc = (void *)emloc->ehdr + offset;
+ if (sort_reloc)
+ return sort_relocs(emloc->ehdr, emloc->start_mcount_loc, count);
+
qsort(start_loc, count/long_size, long_size, compare_extable);
return NULL;
}
@@ -866,12 +1030,14 @@ static int do_file(char const *const fna
r2 = r2le;
r8 = r8le;
w = wle;
+ w8 = w8le;
break;
case ELFDATA2MSB:
r = rbe;
r2 = r2be;
r8 = r8be;
w = wbe;
+ w8 = w8be;
break;
default:
fprintf(stderr, "unrecognized ELF data encoding %d: %s\n",
@@ -887,8 +1053,13 @@ static int do_file(char const *const fna
}
switch (r2(&ehdr->e32.e_machine)) {
- case EM_386:
case EM_AARCH64:
+#ifdef MCOUNT_SORT_ENABLED
+ sort_reloc = true;
+ rela_type = 0x403;
+#endif
+ /* fallthrough */
+ case EM_386:
case EM_LOONGARCH:
case EM_RISCV:
case EM_S390:
@@ -932,6 +1103,10 @@ static int do_file(char const *const fna
.sym_name = sym32_name,
.sym_value = sym32_value,
.sym_shndx = sym32_shndx,
+ .rela_offset = rela32_offset,
+ .rela_info = rela32_info,
+ .rela_addend = rela32_addend,
+ .rela_write_addend = rela32_write_addend,
};
e = efuncs;
@@ -965,6 +1140,10 @@ static int do_file(char const *const fna
.sym_name = sym64_name,
.sym_value = sym64_value,
.sym_shndx = sym64_shndx,
+ .rela_offset = rela64_offset,
+ .rela_info = rela64_info,
+ .rela_addend = rela64_addend,
+ .rela_write_addend = rela64_write_addend,
};
e = efuncs;
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 6.6 060/175] scripts/sorttable: Have mcount rela sort use direct values
[not found] <20260702155115.766838875@linuxfoundation.org>
` (15 preceding siblings ...)
2026-07-02 16:19 ` [PATCH 6.6 059/175] arm64: scripts/sorttable: Implement sorting mcount_loc at boot for arm64 Greg Kroah-Hartman
@ 2026-07-02 16:19 ` Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 061/175] scripts/sorttable: Always use an array for the mcount_loc sorting Greg Kroah-Hartman
` (3 subsequent siblings)
20 siblings, 0 replies; 21+ messages in thread
From: Greg Kroah-Hartman @ 2026-07-02 16:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, bpf, Masami Hiramatsu, Mark Rutland,
Mathieu Desnoyers, Andrew Morton, Peter Zijlstra, Linus Torvalds,
Masahiro Yamada, Nathan Chancellor, Nicolas Schier, Zheng Yejian,
Martin Kelly, Christophe Leroy, Josh Poimboeuf, Heiko Carstens,
Catalin Marinas, Will Deacon, Vasily Gorbik, Alexander Gordeev,
Steven Rostedt (Google), Andrey Grodzovsky
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit a0265659322540d656727b9e132edfb6f06b6c1a ]
The mcount_loc sorting for when the values are stored in the Elf_Rela
entries uses the compare_extable() function to do the compares in the
qsort(). That function does handle byte swapping if the machine being
compiled for is a different endian than the host machine. But the
sort_relocs() function sorts an array that pulled in the values from the
Elf_Rela section and has already done the swapping.
Create two new compare functions that will sort the direct values. One
will sort 32 bit values and the other will sort the 64 bit value. One of
these will be assigned to a compare_values function pointer and that will
be used for sorting the Elf_Rela mcount values.
Cc: bpf <bpf@vger.kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: Zheng Yejian <zhengyejian1@huawei.com>
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Link: https://lore.kernel.org/20250218200022.538888594@goodmis.org
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
scripts/sorttable.c | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
--- a/scripts/sorttable.c
+++ b/scripts/sorttable.c
@@ -552,6 +552,28 @@ static void *sort_orctable(void *arg)
#ifdef MCOUNT_SORT_ENABLED
+static int compare_values_64(const void *a, const void *b)
+{
+ uint64_t av = *(uint64_t *)a;
+ uint64_t bv = *(uint64_t *)b;
+
+ if (av < bv)
+ return -1;
+ return av > bv;
+}
+
+static int compare_values_32(const void *a, const void *b)
+{
+ uint32_t av = *(uint32_t *)a;
+ uint32_t bv = *(uint32_t *)b;
+
+ if (av < bv)
+ return -1;
+ return av > bv;
+}
+
+static int (*compare_values)(const void *a, const void *b);
+
/* Only used for sorting mcount table */
static void rela_write_addend(Elf_Rela *rela, uint64_t val)
{
@@ -583,6 +605,8 @@ static void *sort_relocs(Elf_Ehdr *ehdr,
void *vals;
void *ptr;
+ compare_values = long_size == 4 ? compare_values_32 : compare_values_64;
+
shdr_start = (Elf_Shdr *)((char *)ehdr + ehdr_shoff(ehdr));
shentsize = ehdr_shentsize(ehdr);
@@ -640,7 +664,7 @@ static void *sort_relocs(Elf_Ehdr *ehdr,
}
}
count = ptr - vals;
- qsort(vals, count / long_size, long_size, compare_extable);
+ qsort(vals, count / long_size, long_size, compare_values);
ptr = vals;
for (int i = 0; i < shnum; i++) {
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 6.6 061/175] scripts/sorttable: Always use an array for the mcount_loc sorting
[not found] <20260702155115.766838875@linuxfoundation.org>
` (16 preceding siblings ...)
2026-07-02 16:19 ` [PATCH 6.6 060/175] scripts/sorttable: Have mcount rela sort use direct values Greg Kroah-Hartman
@ 2026-07-02 16:19 ` Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 062/175] scripts/sorttable: Zero out weak functions in mcount_loc table Greg Kroah-Hartman
` (2 subsequent siblings)
20 siblings, 0 replies; 21+ messages in thread
From: Greg Kroah-Hartman @ 2026-07-02 16:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, bpf, Masami Hiramatsu, Mark Rutland,
Mathieu Desnoyers, Andrew Morton, Peter Zijlstra, Linus Torvalds,
Masahiro Yamada, Nathan Chancellor, Nicolas Schier, Zheng Yejian,
Martin Kelly, Christophe Leroy, Josh Poimboeuf, Heiko Carstens,
Catalin Marinas, Will Deacon, Vasily Gorbik, Alexander Gordeev,
Steven Rostedt (Google), Andrey Grodzovsky
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 5fb964f5ba53afda0e2b6dbc00b8205461ffe04a ]
The sorting of the mcount_loc section is done directly to the section for
x86 and arm32 but it uses a separate array for arm64 as arm64 has the
values for the mcount_loc stored in the rela sections of the vmlinux ELF
file.
In order to use the same code to remove weak functions, always use a
separate array to do the sorting. This requires splitting up the filling
of the array into one function and the placing the contents of the array
back into the rela sections or into the mcount_loc section into a separate
file.
Cc: bpf <bpf@vger.kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: Zheng Yejian <zhengyejian1@huawei.com>
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Link: https://lore.kernel.org/20250218200022.710676551@goodmis.org
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
scripts/sorttable.c | 122 ++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 90 insertions(+), 32 deletions(-)
--- a/scripts/sorttable.c
+++ b/scripts/sorttable.c
@@ -594,31 +594,19 @@ struct elf_mcount_loc {
uint64_t stop_mcount_loc;
};
-/* Sort the relocations not the address itself */
-static void *sort_relocs(Elf_Ehdr *ehdr, uint64_t start_loc, uint64_t size)
+/* Fill the array with the content of the relocs */
+static int fill_relocs(void *ptr, uint64_t size, Elf_Ehdr *ehdr, uint64_t start_loc)
{
Elf_Shdr *shdr_start;
Elf_Rela *rel;
unsigned int shnum;
- unsigned int count;
+ unsigned int count = 0;
int shentsize;
- void *vals;
- void *ptr;
-
- compare_values = long_size == 4 ? compare_values_32 : compare_values_64;
+ void *array_end = ptr + size;
shdr_start = (Elf_Shdr *)((char *)ehdr + ehdr_shoff(ehdr));
shentsize = ehdr_shentsize(ehdr);
- vals = malloc(long_size * size);
- if (!vals) {
- snprintf(m_err, ERRSTR_MAXSZ, "Failed to allocate sort array");
- pthread_exit(m_err);
- return NULL;
- }
-
- ptr = vals;
-
shnum = ehdr_shnum(ehdr);
if (shnum == SHN_UNDEF)
shnum = shdr_size(shdr_start);
@@ -637,22 +625,18 @@ static void *sort_relocs(Elf_Ehdr *ehdr,
uint64_t offset = rela_offset(rel);
if (offset >= start_loc && offset < start_loc + size) {
- if (ptr + long_size > vals + size) {
- free(vals);
+ if (ptr + long_size > array_end) {
snprintf(m_err, ERRSTR_MAXSZ,
"Too many relocations");
- pthread_exit(m_err);
- return NULL;
+ return -1;
}
/* Make sure this has the correct type */
if (rela_info(rel) != rela_type) {
- free(vals);
snprintf(m_err, ERRSTR_MAXSZ,
"rela has type %lx but expected %lx\n",
(long)rela_info(rel), rela_type);
- pthread_exit(m_err);
- return NULL;
+ return -1;
}
if (long_size == 4)
@@ -660,13 +644,28 @@ static void *sort_relocs(Elf_Ehdr *ehdr,
else
*(uint64_t *)ptr = rela_addend(rel);
ptr += long_size;
+ count++;
}
}
}
- count = ptr - vals;
- qsort(vals, count / long_size, long_size, compare_values);
+ return count;
+}
+
+/* Put the sorted vals back into the relocation elements */
+static void replace_relocs(void *ptr, uint64_t size, Elf_Ehdr *ehdr, uint64_t start_loc)
+{
+ Elf_Shdr *shdr_start;
+ Elf_Rela *rel;
+ unsigned int shnum;
+ int shentsize;
+
+ shdr_start = (Elf_Shdr *)((char *)ehdr + ehdr_shoff(ehdr));
+ shentsize = ehdr_shentsize(ehdr);
+
+ shnum = ehdr_shnum(ehdr);
+ if (shnum == SHN_UNDEF)
+ shnum = shdr_size(shdr_start);
- ptr = vals;
for (int i = 0; i < shnum; i++) {
Elf_Shdr *shdr = get_index(shdr_start, shentsize, i);
void *end;
@@ -689,8 +688,32 @@ static void *sort_relocs(Elf_Ehdr *ehdr,
}
}
}
- free(vals);
- return NULL;
+}
+
+static int fill_addrs(void *ptr, uint64_t size, void *addrs)
+{
+ void *end = ptr + size;
+ int count = 0;
+
+ for (; ptr < end; ptr += long_size, addrs += long_size, count++) {
+ if (long_size == 4)
+ *(uint32_t *)ptr = r(addrs);
+ else
+ *(uint64_t *)ptr = r8(addrs);
+ }
+ return count;
+}
+
+static void replace_addrs(void *ptr, uint64_t size, void *addrs)
+{
+ void *end = ptr + size;
+
+ for (; ptr < end; ptr += long_size, addrs += long_size) {
+ if (long_size == 4)
+ w(*(uint32_t *)ptr, addrs);
+ else
+ w8(*(uint64_t *)ptr, addrs);
+ }
}
/* Sort the addresses stored between __start_mcount_loc to __stop_mcount_loc in vmlinux */
@@ -699,14 +722,49 @@ static void *sort_mcount_loc(void *arg)
struct elf_mcount_loc *emloc = (struct elf_mcount_loc *)arg;
uint64_t offset = emloc->start_mcount_loc - shdr_addr(emloc->init_data_sec)
+ shdr_offset(emloc->init_data_sec);
- uint64_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
+ uint64_t size = emloc->stop_mcount_loc - emloc->start_mcount_loc;
unsigned char *start_loc = (void *)emloc->ehdr + offset;
+ Elf_Ehdr *ehdr = emloc->ehdr;
+ void *e_msg = NULL;
+ void *vals;
+ int count;
+
+ vals = malloc(long_size * size);
+ if (!vals) {
+ snprintf(m_err, ERRSTR_MAXSZ, "Failed to allocate sort array");
+ pthread_exit(m_err);
+ }
if (sort_reloc)
- return sort_relocs(emloc->ehdr, emloc->start_mcount_loc, count);
+ count = fill_relocs(vals, size, ehdr, emloc->start_mcount_loc);
+ else
+ count = fill_addrs(vals, size, start_loc);
+
+ if (count < 0) {
+ e_msg = m_err;
+ goto out;
+ }
+
+ if (count != size / long_size) {
+ snprintf(m_err, ERRSTR_MAXSZ, "Expected %u mcount elements but found %u\n",
+ (int)(size / long_size), count);
+ e_msg = m_err;
+ goto out;
+ }
+
+ compare_values = long_size == 4 ? compare_values_32 : compare_values_64;
+
+ qsort(vals, count, long_size, compare_values);
+
+ if (sort_reloc)
+ replace_relocs(vals, size, ehdr, emloc->start_mcount_loc);
+ else
+ replace_addrs(vals, size, start_loc);
+
+out:
+ free(vals);
- qsort(start_loc, count/long_size, long_size, compare_extable);
- return NULL;
+ pthread_exit(e_msg);
}
/* Get the address of __start_mcount_loc and __stop_mcount_loc in System.map */
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 6.6 062/175] scripts/sorttable: Zero out weak functions in mcount_loc table
[not found] <20260702155115.766838875@linuxfoundation.org>
` (17 preceding siblings ...)
2026-07-02 16:19 ` [PATCH 6.6 061/175] scripts/sorttable: Always use an array for the mcount_loc sorting Greg Kroah-Hartman
@ 2026-07-02 16:19 ` Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 063/175] ftrace: Update the mcount_loc check of skipped entries Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 064/175] ftrace: Have ftrace pages output reflect freed pages Greg Kroah-Hartman
20 siblings, 0 replies; 21+ messages in thread
From: Greg Kroah-Hartman @ 2026-07-02 16:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, bpf, Masami Hiramatsu, Mark Rutland,
Mathieu Desnoyers, Andrew Morton, Peter Zijlstra, Linus Torvalds,
Masahiro Yamada, Nathan Chancellor, Nicolas Schier, Zheng Yejian,
Martin Kelly, Christophe Leroy, Josh Poimboeuf, Heiko Carstens,
Catalin Marinas, Will Deacon, Vasily Gorbik, Alexander Gordeev,
Steven Rostedt (Google), Andrey Grodzovsky
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit ef378c3b8233855497a414b9d67bf22592c928a4 ]
When a function is annotated as "weak" and is overridden, the code is not
removed. If it is traced, the fentry/mcount location in the weak function
will be referenced by the "__mcount_loc" section. This will then be added
to the available_filter_functions list. Since only the address of the
functions are listed, to find the name to show, a search of kallsyms is
used.
Since kallsyms will return the function by simply finding the function
that the address is after but before the next function, an address of a
weak function will show up as the function before it. This is because
kallsyms does not save names of weak functions. This has caused issues in
the past, as now the traced weak function will be listed in
available_filter_functions with the name of the function before it.
At best, this will cause the previous function's name to be listed twice.
At worse, if the previous function was marked notrace, it will now show up
as a function that can be traced. Note that it only shows up that it can
be traced but will not be if enabled, which causes confusion.
https://lore.kernel.org/all/20220412094923.0abe90955e5db486b7bca279@kernel.org/
The commit b39181f7c6907 ("ftrace: Add FTRACE_MCOUNT_MAX_OFFSET to avoid
adding weak function") was a workaround to this by checking the function
address before printing its name. If the address was too far from the
function given by the name then instead of printing the name it would
print: __ftrace_invalid_address___<invalid-offset>
The real issue is that these invalid addresses are listed in the ftrace
table look up which available_filter_functions is derived from. A place
holder must be listed in that file because set_ftrace_filter may take a
series of indexes into that file instead of names to be able to do O(1)
lookups to enable filtering (many tools use this method).
Even if kallsyms saved the size of the function, it does not remove the
need of having these place holders. The real solution is to not add a weak
function into the ftrace table in the first place.
To solve this, the sorttable.c code that sorts the mcount regions during
the build is modified to take a "nm -S vmlinux" input, sort it, and any
function listed in the mcount_loc section that is not within a boundary of
the function list given by nm is considered a weak function and is zeroed
out.
Note, this does not mean they will remain zero when booting as KASLR
will still shift those addresses. To handle this, the entries in the
mcount_loc section will be ignored if they are zero or match the
kaslr_offset() value.
Before:
~# grep __ftrace_invalid_address___ /sys/kernel/tracing/available_filter_functions | wc -l
551
After:
~# grep __ftrace_invalid_address___ /sys/kernel/tracing/available_filter_functions | wc -l
0
Cc: bpf <bpf@vger.kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: Zheng Yejian <zhengyejian1@huawei.com>
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Link: https://lore.kernel.org/20250218200022.883095980@goodmis.org
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/ftrace.c | 6 +-
scripts/link-vmlinux.sh | 4 +
scripts/sorttable.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 134 insertions(+), 4 deletions(-)
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -6525,6 +6525,7 @@ static int ftrace_process_locs(struct mo
unsigned long count;
unsigned long *p;
unsigned long addr;
+ unsigned long kaslr;
unsigned long flags = 0; /* Shut up gcc */
int ret = -ENOMEM;
@@ -6573,6 +6574,9 @@ static int ftrace_process_locs(struct mo
ftrace_pages->next = start_pg;
}
+ /* For zeroed locations that were shifted for core kernel */
+ kaslr = !mod ? kaslr_offset() : 0;
+
p = start;
pg = start_pg;
while (p < end) {
@@ -6584,7 +6588,7 @@ static int ftrace_process_locs(struct mo
* object files to satisfy alignments.
* Skip any NULL pointers.
*/
- if (!addr) {
+ if (!addr || addr == kaslr) {
skipped++;
continue;
}
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -198,13 +198,15 @@ mksysmap()
sorttable()
{
- ${objtree}/scripts/sorttable ${1}
+ ${NM} -S ${1} > .tmp_vmlinux.nm-sort
+ ${objtree}/scripts/sorttable -s .tmp_vmlinux.nm-sort ${1}
}
# Delete output files in case of error
cleanup()
{
rm -f .btf.*
+ rm -f .tmp_vmlinux.nm-sort
rm -f System.map
rm -f vmlinux
rm -f vmlinux.map
--- a/scripts/sorttable.c
+++ b/scripts/sorttable.c
@@ -580,6 +580,98 @@ static void rela_write_addend(Elf_Rela *
e.rela_write_addend(rela, val);
}
+struct func_info {
+ uint64_t addr;
+ uint64_t size;
+};
+
+/* List of functions created by: nm -S vmlinux */
+static struct func_info *function_list;
+static int function_list_size;
+
+/* Allocate functions in 1k blocks */
+#define FUNC_BLK_SIZE 1024
+#define FUNC_BLK_MASK (FUNC_BLK_SIZE - 1)
+
+static int add_field(uint64_t addr, uint64_t size)
+{
+ struct func_info *fi;
+ int fsize = function_list_size;
+
+ if (!(fsize & FUNC_BLK_MASK)) {
+ fsize += FUNC_BLK_SIZE;
+ fi = realloc(function_list, fsize * sizeof(struct func_info));
+ if (!fi)
+ return -1;
+ function_list = fi;
+ }
+ fi = &function_list[function_list_size++];
+ fi->addr = addr;
+ fi->size = size;
+ return 0;
+}
+
+/* Only return match if the address lies inside the function size */
+static int cmp_func_addr(const void *K, const void *A)
+{
+ uint64_t key = *(const uint64_t *)K;
+ const struct func_info *a = A;
+
+ if (key < a->addr)
+ return -1;
+ return key >= a->addr + a->size;
+}
+
+/* Find the function in function list that is bounded by the function size */
+static int find_func(uint64_t key)
+{
+ return bsearch(&key, function_list, function_list_size,
+ sizeof(struct func_info), cmp_func_addr) != NULL;
+}
+
+static int cmp_funcs(const void *A, const void *B)
+{
+ const struct func_info *a = A;
+ const struct func_info *b = B;
+
+ if (a->addr < b->addr)
+ return -1;
+ return a->addr > b->addr;
+}
+
+static int parse_symbols(const char *fname)
+{
+ FILE *fp;
+ char addr_str[20]; /* Only need 17, but round up to next int size */
+ char size_str[20];
+ char type;
+
+ fp = fopen(fname, "r");
+ if (!fp) {
+ perror(fname);
+ return -1;
+ }
+
+ while (fscanf(fp, "%16s %16s %c %*s\n", addr_str, size_str, &type) == 3) {
+ uint64_t addr;
+ uint64_t size;
+
+ /* Only care about functions */
+ if (type != 't' && type != 'T' && type != 'W')
+ continue;
+
+ addr = strtoull(addr_str, NULL, 16);
+ size = strtoull(size_str, NULL, 16);
+ if (add_field(addr, size) < 0)
+ return -1;
+ }
+ fclose(fp);
+
+ qsort(function_list, function_list_size, sizeof(struct func_info), cmp_funcs);
+
+ return 0;
+}
+
static pthread_t mcount_sort_thread;
static bool sort_reloc;
@@ -752,6 +844,21 @@ static void *sort_mcount_loc(void *arg)
goto out;
}
+ /* zero out any locations not found by function list */
+ if (function_list_size) {
+ for (void *ptr = vals; ptr < vals + size; ptr += long_size) {
+ uint64_t key;
+
+ key = long_size == 4 ? r((uint32_t *)ptr) : r8((uint64_t *)ptr);
+ if (!find_func(key)) {
+ if (long_size == 4)
+ *(uint32_t *)ptr = 0;
+ else
+ *(uint64_t *)ptr = 0;
+ }
+ }
+ }
+
compare_values = long_size == 4 ? compare_values_32 : compare_values_64;
qsort(vals, count, long_size, compare_values);
@@ -801,6 +908,8 @@ static void get_mcount_loc(struct elf_mc
return;
}
}
+#else /* MCOUNT_SORT_ENABLED */
+static inline int parse_symbols(const char *fname) { return 0; }
#endif
static int do_sort(Elf_Ehdr *ehdr,
@@ -1256,14 +1365,29 @@ int main(int argc, char *argv[])
int i, n_error = 0; /* gcc-4.3.0 false positive complaint */
size_t size = 0;
void *addr = NULL;
+ int c;
+
+ while ((c = getopt(argc, argv, "s:")) >= 0) {
+ switch (c) {
+ case 's':
+ if (parse_symbols(optarg) < 0) {
+ fprintf(stderr, "Could not parse %s\n", optarg);
+ return -1;
+ }
+ break;
+ default:
+ fprintf(stderr, "usage: sorttable [-s nm-file] vmlinux...\n");
+ return 0;
+ }
+ }
- if (argc < 2) {
+ if ((argc - optind) < 1) {
fprintf(stderr, "usage: sorttable vmlinux...\n");
return 0;
}
/* Process each file in turn, allowing deep failure. */
- for (i = 1; i < argc; i++) {
+ for (i = optind; i < argc; i++) {
addr = mmap_file(argv[i], &size);
if (!addr) {
++n_error;
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 6.6 063/175] ftrace: Update the mcount_loc check of skipped entries
[not found] <20260702155115.766838875@linuxfoundation.org>
` (18 preceding siblings ...)
2026-07-02 16:19 ` [PATCH 6.6 062/175] scripts/sorttable: Zero out weak functions in mcount_loc table Greg Kroah-Hartman
@ 2026-07-02 16:19 ` Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 064/175] ftrace: Have ftrace pages output reflect freed pages Greg Kroah-Hartman
20 siblings, 0 replies; 21+ messages in thread
From: Greg Kroah-Hartman @ 2026-07-02 16:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, bpf, Masami Hiramatsu, Mark Rutland,
Mathieu Desnoyers, Andrew Morton, Peter Zijlstra, Linus Torvalds,
Masahiro Yamada, Nathan Chancellor, Nicolas Schier, Zheng Yejian,
Martin Kelly, Christophe Leroy, Josh Poimboeuf, Heiko Carstens,
Catalin Marinas, Will Deacon, Vasily Gorbik, Alexander Gordeev,
Steven Rostedt (Google), Andrey Grodzovsky
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 4a3efc6baff931da9a85c6d2e42c87bd9a827399 ]
Now that weak functions turn into skipped entries, update the check to
make sure the amount that was allocated would fit both the entries that
were allocated as well as those that were skipped.
Cc: bpf <bpf@vger.kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: Zheng Yejian <zhengyejian1@huawei.com>
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Link: https://lore.kernel.org/20250218200023.055162048@goodmis.org
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/ftrace.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -6632,7 +6632,28 @@ static int ftrace_process_locs(struct mo
/* We should have used all pages unless we skipped some */
if (pg_unuse) {
- WARN_ON(!skipped);
+ unsigned long pg_remaining, remaining = 0;
+ unsigned long skip;
+
+ /* Count the number of entries unused and compare it to skipped. */
+ pg_remaining = (ENTRIES_PER_PAGE << pg->order) - pg->index;
+
+ if (!WARN(skipped < pg_remaining, "Extra allocated pages for ftrace")) {
+
+ skip = skipped - pg_remaining;
+
+ for (pg = pg_unuse; pg; pg = pg->next)
+ remaining += 1 << pg->order;
+
+ skip = DIV_ROUND_UP(skip, ENTRIES_PER_PAGE);
+
+ /*
+ * Check to see if the number of pages remaining would
+ * just fit the number of entries skipped.
+ */
+ WARN(skip != remaining, "Extra allocated pages for ftrace: %lu with %lu skipped",
+ remaining, skipped);
+ }
/* Need to synchronize with ftrace_location_range() */
synchronize_rcu();
ftrace_free_pages(pg_unuse);
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 6.6 064/175] ftrace: Have ftrace pages output reflect freed pages
[not found] <20260702155115.766838875@linuxfoundation.org>
` (19 preceding siblings ...)
2026-07-02 16:19 ` [PATCH 6.6 063/175] ftrace: Update the mcount_loc check of skipped entries Greg Kroah-Hartman
@ 2026-07-02 16:19 ` Greg Kroah-Hartman
20 siblings, 0 replies; 21+ messages in thread
From: Greg Kroah-Hartman @ 2026-07-02 16:19 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, bpf, Masami Hiramatsu, Mark Rutland,
Mathieu Desnoyers, Andrew Morton, Peter Zijlstra, Linus Torvalds,
Masahiro Yamada, Nathan Chancellor, Nicolas Schier, Zheng Yejian,
Martin Kelly, Christophe Leroy, Josh Poimboeuf, Heiko Carstens,
Catalin Marinas, Will Deacon, Vasily Gorbik, Alexander Gordeev,
Steven Rostedt (Google), Andrey Grodzovsky
6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 264143c4e54412095f4b615e65bf736fc3c60af0 ]
The amount of memory that ftrace uses to save the descriptors to manage
the functions it can trace is shown at output. But if there are a lot of
functions that are skipped because they were weak or the architecture
added holes into the tables, then the extra pages that were allocated are
freed. But these freed pages are not reflected in the numbers shown, and
they can even be inconsistent with what is reported:
ftrace: allocating 57482 entries in 225 pages
ftrace: allocated 224 pages with 3 groups
The above shows the number of original entries that are in the mcount_loc
section and the pages needed to save them (225), but the second output
reflects the number of pages that were actually used. The two should be
consistent as:
ftrace: allocating 56739 entries in 224 pages
ftrace: allocated 224 pages with 3 groups
The above also shows the accurate number of entires that were actually
stored and does not include the entries that were removed.
Cc: bpf <bpf@vger.kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: Zheng Yejian <zhengyejian1@huawei.com>
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Link: https://lore.kernel.org/20250218200023.221100846@goodmis.org
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@crowdstrike.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/ftrace.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -6527,6 +6527,7 @@ static int ftrace_process_locs(struct mo
unsigned long addr;
unsigned long kaslr;
unsigned long flags = 0; /* Shut up gcc */
+ unsigned long pages;
int ret = -ENOMEM;
count = end - start;
@@ -6534,6 +6535,8 @@ static int ftrace_process_locs(struct mo
if (!count)
return 0;
+ pages = DIV_ROUND_UP(count, ENTRIES_PER_PAGE);
+
/*
* Sorting mcount in vmlinux at build time depend on
* CONFIG_BUILDTIME_MCOUNT_SORT, while mcount loc in
@@ -6645,6 +6648,8 @@ static int ftrace_process_locs(struct mo
for (pg = pg_unuse; pg; pg = pg->next)
remaining += 1 << pg->order;
+ pages -= remaining;
+
skip = DIV_ROUND_UP(skip, ENTRIES_PER_PAGE);
/*
@@ -6658,6 +6663,13 @@ static int ftrace_process_locs(struct mo
synchronize_rcu();
ftrace_free_pages(pg_unuse);
}
+
+ if (!mod) {
+ count -= skipped;
+ pr_info("ftrace: allocating %ld entries in %ld pages\n",
+ count, pages);
+ }
+
return ret;
}
@@ -7315,9 +7327,6 @@ void __init ftrace_init(void)
goto failed;
}
- pr_info("ftrace: allocating %ld entries in %ld pages\n",
- count, DIV_ROUND_UP(count, ENTRIES_PER_PAGE));
-
ret = ftrace_process_locs(NULL,
__start_mcount_loc,
__stop_mcount_loc);
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2026-07-02 16:49 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20260702155115.766838875@linuxfoundation.org>
2026-07-02 16:19 ` [PATCH 6.6 044/175] scripts/sorttable: Remove unused macro defines Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 045/175] scripts/sorttable: Remove unused write functions Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 046/175] scripts/sorttable: Remove unneeded Elf_Rel Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 047/175] scripts/sorttable: Have the ORC code use the _r() functions to read Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 048/175] scripts/sorttable: Make compare_extable() into two functions Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 049/175] scripts/sorttable: Convert Elf_Ehdr to union Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 050/175] scripts/sorttable: Replace Elf_Shdr Macro with a union Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 051/175] scripts/sorttable: Convert Elf_Sym MACRO over to " Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 052/175] scripts/sorttable: Add helper functions for Elf_Ehdr Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 053/175] scripts/sorttable: Add helper functions for Elf_Shdr Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 054/175] scripts/sorttable: Add helper functions for Elf_Sym Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 055/175] scripts/sorttable: Use uint64_t for mcount sorting Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 056/175] scripts/sorttable: Move code from sorttable.h into sorttable.c Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 057/175] scripts/sorttable: Get start/stop_mcount_loc from ELF file directly Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 058/175] scripts/sorttable: Use a structure of function pointers for elf helpers Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 059/175] arm64: scripts/sorttable: Implement sorting mcount_loc at boot for arm64 Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 060/175] scripts/sorttable: Have mcount rela sort use direct values Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 061/175] scripts/sorttable: Always use an array for the mcount_loc sorting Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 062/175] scripts/sorttable: Zero out weak functions in mcount_loc table Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 063/175] ftrace: Update the mcount_loc check of skipped entries Greg Kroah-Hartman
2026-07-02 16:19 ` [PATCH 6.6 064/175] ftrace: Have ftrace pages output reflect freed pages Greg Kroah-Hartman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox