From 9dfade39f5d9e5ea5ff8bf75200adb0a15a3d7d6 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Sat, 10 Jun 2023 05:33:44 +0200 Subject: [PATCH] generic: 5.15: backport patch supporting "big" kernel symbols Backport patch supporting "big" kernel symbols. This is needed for powerpc arch that seems to suffer from this problem when CONFIG_ALL_KMODS is selected and fail to compile with the error: Inconsistent kallsyms data Try make KALLSYMS_EXTRA_PASS=1 as a workaround Backport this patch to handle these corner case. Signed-off-by: Christian Marangi --- ...-kallsyms-support-big-kernel-symbols.patch | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 target/linux/generic/backport-5.15/202-v6.1-kallsyms-support-big-kernel-symbols.patch diff --git a/target/linux/generic/backport-5.15/202-v6.1-kallsyms-support-big-kernel-symbols.patch b/target/linux/generic/backport-5.15/202-v6.1-kallsyms-support-big-kernel-symbols.patch new file mode 100644 index 0000000000..786a2d93b5 --- /dev/null +++ b/target/linux/generic/backport-5.15/202-v6.1-kallsyms-support-big-kernel-symbols.patch @@ -0,0 +1,128 @@ +From 73bbb94466fd3f8b313eeb0b0467314a262dddb3 Mon Sep 17 00:00:00 2001 +From: Miguel Ojeda +Date: Mon, 5 Apr 2021 04:58:39 +0200 +Subject: [PATCH] kallsyms: support "big" kernel symbols + +Rust symbols can become quite long due to namespacing introduced +by modules, types, traits, generics, etc. + +Increasing to 255 is not enough in some cases, therefore +introduce longer lengths to the symbol table. + +In order to avoid increasing all lengths to 2 bytes (since most +of them are small, including many Rust ones), use ULEB128 to +keep smaller symbols in 1 byte, with the rest in 2 bytes. + +Reviewed-by: Kees Cook +Reviewed-by: Greg Kroah-Hartman +Co-developed-by: Alex Gaynor +Signed-off-by: Alex Gaynor +Co-developed-by: Wedson Almeida Filho +Signed-off-by: Wedson Almeida Filho +Co-developed-by: Gary Guo +Signed-off-by: Gary Guo +Co-developed-by: Boqun Feng +Signed-off-by: Boqun Feng +Co-developed-by: Matthew Wilcox +Signed-off-by: Matthew Wilcox +Signed-off-by: Miguel Ojeda +--- + kernel/kallsyms.c | 26 ++++++++++++++++++++++---- + scripts/kallsyms.c | 29 ++++++++++++++++++++++++++--- + 2 files changed, 48 insertions(+), 7 deletions(-) + +--- a/kernel/kallsyms.c ++++ b/kernel/kallsyms.c +@@ -69,12 +69,20 @@ static unsigned int kallsyms_expand_symb + data = &kallsyms_names[off]; + len = *data; + data++; ++ off++; ++ ++ /* If MSB is 1, it is a "big" symbol, so needs an additional byte. */ ++ if ((len & 0x80) != 0) { ++ len = (len & 0x7F) | (*data << 7); ++ data++; ++ off++; ++ } + + /* + * Update the offset to return the offset for the next symbol on + * the compressed stream. + */ +- off += len + 1; ++ off += len; + + /* + * For every byte on the compressed symbol data, copy the table +@@ -127,7 +135,7 @@ static char kallsyms_get_symbol_type(uns + static unsigned int get_symbol_offset(unsigned long pos) + { + const u8 *name; +- int i; ++ int i, len; + + /* + * Use the closest marker we have. We have markers every 256 positions, +@@ -141,8 +149,18 @@ static unsigned int get_symbol_offset(un + * so we just need to add the len to the current pointer for every + * symbol we wish to skip. + */ +- for (i = 0; i < (pos & 0xFF); i++) +- name = name + (*name) + 1; ++ for (i = 0; i < (pos & 0xFF); i++) { ++ len = *name; ++ ++ /* ++ * If MSB is 1, it is a "big" symbol, so we need to look into ++ * the next byte (and skip it, too). ++ */ ++ if ((len & 0x80) != 0) ++ len = ((len & 0x7F) | (name[1] << 7)) + 1; ++ ++ name = name + len + 1; ++ } + + return name - kallsyms_names; + } +--- a/scripts/kallsyms.c ++++ b/scripts/kallsyms.c +@@ -470,12 +470,35 @@ static void write_src(void) + if ((i & 0xFF) == 0) + markers[i >> 8] = off; + +- printf("\t.byte 0x%02x", table[i]->len); ++ /* There cannot be any symbol of length zero. */ ++ if (table[i]->len == 0) { ++ fprintf(stderr, "kallsyms failure: " ++ "unexpected zero symbol length\n"); ++ exit(EXIT_FAILURE); ++ } ++ ++ /* Only lengths that fit in up-to-two-byte ULEB128 are supported. */ ++ if (table[i]->len > 0x3FFF) { ++ fprintf(stderr, "kallsyms failure: " ++ "unexpected huge symbol length\n"); ++ exit(EXIT_FAILURE); ++ } ++ ++ /* Encode length with ULEB128. */ ++ if (table[i]->len <= 0x7F) { ++ /* Most symbols use a single byte for the length. */ ++ printf("\t.byte 0x%02x", table[i]->len); ++ off += table[i]->len + 1; ++ } else { ++ /* "Big" symbols use two bytes. */ ++ printf("\t.byte 0x%02x, 0x%02x", ++ (table[i]->len & 0x7F) | 0x80, ++ (table[i]->len >> 7) & 0x7F); ++ off += table[i]->len + 2; ++ } + for (k = 0; k < table[i]->len; k++) + printf(", 0x%02x", table[i]->sym[k]); + printf("\n"); +- +- off += table[i]->len + 1; + } + printf("\n"); + -- 2.30.2