From 668de2b9d48dccdc1b992e07287f15459515fefb Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 14 Jan 2025 00:00:43 +0900 Subject: [PATCH 01/16] genksyms: fix last 3 shift/reduce conflicts The genksyms parser has ambiguities in its grammar, which are currently suppressed by a workaround in scripts/genksyms/Makefile. Building genksyms with W=1 generates the following warnings: YACC scripts/genksyms/parse.tab.[ch] scripts/genksyms/parse.y: warning: 3 shift/reduce conflicts [-Wconflicts-sr] scripts/genksyms/parse.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples The ambiguity arises when decl_specifier_seq is followed by '(' because the following two interpretations are possible: - decl_specifier_seq direct_abstract_declarator '(' parameter_declaration_clause ')' - decl_specifier_seq '(' abstract_declarator ')' This issue occurs because the current parser allows an empty string to be reduced to direct_abstract_declarator, which is incorrect. K&R [1] explains the correct grammar: ::= {}+ | {}+ | {}+ ::= | | ::= ( ) | {}? [ {}? ] | {}? ( {}? ) This commit resolves all remaining conflicts. We need to consider the difference between the following two examples: [Example 1] ( ) can become void my_func(int (foo)); ... is equivalent to: void my_func(int foo); [Example 2] ( ) can become typedef int foo; void my_func(int (foo)); ... is equivalent to: void my_func(int (*callback)(int)); Please note that the function declaration is identical in both examples, but the preceding typedef creates the distinction. I introduced a new term, open_paren, to enable the type lookup immediately after the '(' token. Without this, we cannot distinguish between [Example 1] and [Example 2]. [1]: https://cs.wmich.edu/~gupta/teaching/cs4850/sumII06/The%20syntax%20of%20C%20in%20Backus-Naur%20form.htm Signed-off-by: Masahiro Yamada Acked-by: Nicolas Schier --- scripts/genksyms/parse.y | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y index dc575d467bbf..fafce939c32f 100644 --- a/scripts/genksyms/parse.y +++ b/scripts/genksyms/parse.y @@ -363,35 +363,47 @@ parameter_declaration_list: ; parameter_declaration: - decl_specifier_seq abstract_declarator + decl_specifier_seq abstract_declarator_opt { $$ = $2 ? $2 : $1; } ; +abstract_declarator_opt: + /* empty */ { $$ = NULL; } + | abstract_declarator + ; + abstract_declarator: - ptr_operator abstract_declarator + ptr_operator + | ptr_operator abstract_declarator { $$ = $2 ? $2 : $1; } | direct_abstract_declarator { $$ = $1; dont_want_type_specifier = false; } ; direct_abstract_declarator: - /* empty */ { $$ = NULL; } - | IDENT + IDENT { /* For version 2 checksums, we don't want to remember private parameter names. */ remove_node($1); $$ = $1; } - | direct_abstract_declarator '(' parameter_declaration_clause ')' + | direct_abstract_declarator open_paren parameter_declaration_clause ')' { $$ = $4; } - | direct_abstract_declarator '(' error ')' + | direct_abstract_declarator open_paren error ')' { $$ = $4; } | direct_abstract_declarator BRACKET_PHRASE { $$ = $2; } - | '(' abstract_declarator ')' + | open_paren parameter_declaration_clause ')' { $$ = $3; } - | '(' error ')' + | open_paren abstract_declarator ')' { $$ = $3; } + | open_paren error ')' + { $$ = $3; } + | BRACKET_PHRASE + ; + +open_paren: + '(' { $$ = $1; dont_want_type_specifier = false; } ; function_definition: -- 2.51.0 From a95298656c434357b38bec242412c65dcf6114d1 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 14 Jan 2025 00:00:44 +0900 Subject: [PATCH 02/16] genksyms: remove Makefile hack This workaround was introduced for suppressing the reduce/reduce conflict warnings because the %expect-rr directive, which is applicable only to GLR parsers, cannot be used for genksyms. Since there are no longer any conflicts, this Makefile hack is now unnecessary. Signed-off-by: Masahiro Yamada Acked-by: Nicolas Schier --- scripts/genksyms/Makefile | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/scripts/genksyms/Makefile b/scripts/genksyms/Makefile index 312edccda736..4350311fb7b3 100644 --- a/scripts/genksyms/Makefile +++ b/scripts/genksyms/Makefile @@ -4,24 +4,6 @@ hostprogs-always-y += genksyms genksyms-objs := genksyms.o parse.tab.o lex.lex.o -# FIXME: fix the ambiguous grammar in parse.y and delete this hack -# -# Suppress shift/reduce, reduce/reduce conflicts warnings -# unless W=1 is specified. -# -# Just in case, run "$(YACC) --version" without suppressing stderr -# so that 'bison: not found' will be displayed if it is missing. -ifeq ($(findstring 1,$(KBUILD_EXTRA_WARN)),) - -quiet_cmd_bison_no_warn = $(quiet_cmd_bison) - cmd_bison_no_warn = $(YACC) --version >/dev/null; \ - $(cmd_bison) 2>/dev/null - -$(obj)/pars%.tab.c $(obj)/pars%.tab.h: $(src)/pars%.y FORCE - $(call if_changed,bison_no_warn) - -endif - # -I needed for generated C source to include headers in source tree HOSTCFLAGS_parse.tab.o := -I $(src) HOSTCFLAGS_lex.lex.o := -I $(src) -- 2.51.0 From c2f1846ba87ead7ac544be624c13249d6b90eca0 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 14 Jan 2025 00:00:45 +0900 Subject: [PATCH 03/16] genksyms: restrict direct-abstract-declarator to take one parameter-type-list While there is no more grammatical ambiguity in genksyms, the parser logic is still inaccurate. For example, genksyms accepts the following invalid C code: void my_func(int ()(int)); This should result in a syntax error because () cannot be reduced to . ( ) can be reduced, but must not be empty in the following grammar from K&R [1]: ::= ( ) | {}? [ {}? ] | {}? ( {}? ) Furthermore, genksyms accepts the following weird code: void my_func(int (*callback)(int)(int)(int)); The parser allows to recursively absorb multiple ( {}? ), but this behavior is incorrect. In the example above, (*callback) should be followed by at most one (int). [1]: https://cs.wmich.edu/~gupta/teaching/cs4850/sumII06/The%20syntax%20of%20C%20in%20Backus-Naur%20form.htm Signed-off-by: Masahiro Yamada Acked-by: Nicolas Schier --- scripts/genksyms/parse.y | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y index fafce939c32f..03cdd8d53c13 100644 --- a/scripts/genksyms/parse.y +++ b/scripts/genksyms/parse.y @@ -381,20 +381,24 @@ abstract_declarator: ; direct_abstract_declarator: + direct_abstract_declarator1 + | direct_abstract_declarator1 open_paren parameter_declaration_clause ')' + { $$ = $4; } + | open_paren parameter_declaration_clause ')' + { $$ = $3; } + ; + +direct_abstract_declarator1: IDENT { /* For version 2 checksums, we don't want to remember private parameter names. */ remove_node($1); $$ = $1; } - | direct_abstract_declarator open_paren parameter_declaration_clause ')' - { $$ = $4; } - | direct_abstract_declarator open_paren error ')' + | direct_abstract_declarator1 open_paren error ')' { $$ = $4; } - | direct_abstract_declarator BRACKET_PHRASE + | direct_abstract_declarator1 BRACKET_PHRASE { $$ = $2; } - | open_paren parameter_declaration_clause ')' - { $$ = $3; } | open_paren abstract_declarator ')' { $$ = $3; } | open_paren error ')' -- 2.51.0 From aa710cee0d677043f49a447c4665df51a553a2ba Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 14 Jan 2025 00:00:46 +0900 Subject: [PATCH 04/16] genksyms: restrict direct-declarator to take one parameter-type-list Similar to the previous commit, this change makes the parser logic a little more accurate. Currently, genksyms accepts the following invalid code: struct foo { int (*callback)(int)(int)(int); }; A direct-declarator should not recursively absorb multiple ( parameter-type-list ) constructs. In the example above, (*callback) should be followed by at most one (int). Signed-off-by: Masahiro Yamada Acked-by: Nicolas Schier --- scripts/genksyms/parse.y | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y index 03cdd8d53c13..33a6aab53b69 100644 --- a/scripts/genksyms/parse.y +++ b/scripts/genksyms/parse.y @@ -331,12 +331,16 @@ nested_declarator: ; direct_nested_declarator: - IDENT { $$ = $1; dont_want_type_specifier = false; } - | direct_nested_declarator '(' parameter_declaration_clause ')' + direct_nested_declarator1 + | direct_nested_declarator1 '(' parameter_declaration_clause ')' { $$ = $4; } - | direct_nested_declarator '(' error ')' + ; + +direct_nested_declarator1: + IDENT { $$ = $1; dont_want_type_specifier = false; } + | direct_nested_declarator1 '(' error ')' { $$ = $4; } - | direct_nested_declarator BRACKET_PHRASE + | direct_nested_declarator1 BRACKET_PHRASE { $$ = $2; } | '(' nested_declarator ')' { $$ = $3; } -- 2.51.0 From ccc11a195c69b0c01ee140aecadfbdcdcdd03605 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 14 Jan 2025 00:00:47 +0900 Subject: [PATCH 05/16] genksyms: record attributes consistently for init-declarator I believe the missing action here is a bug. For rules with no explicit action, the following default is used: { $$ = $1; } However, in this case, $1 is the value of attribute_opt itself. As a result, the value of attribute_opt is always NULL. The following test code demonstrates inconsistent behavior. int x __attribute__((__aligned__(4))); int y __attribute__((__aligned__(4))) = 0; The attribute is recorded only when followed by an initializer. This commit adds the correct action to propagate the value of the ATTRIBUTE_PHRASE token. With this change, the attribute in the example above is consistently recorded for both 'x' and 'y'. [Before] $ cat < Defn for type0 y == Hash table occupancy 2/4096 = 0.000488281 [After] $ cat < Defn for type0 y == Hash table occupancy 2/4096 = 0.000488281 Signed-off-by: Masahiro Yamada Acked-by: Nicolas Schier --- scripts/genksyms/parse.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y index 33a6aab53b69..e3c160046143 100644 --- a/scripts/genksyms/parse.y +++ b/scripts/genksyms/parse.y @@ -480,7 +480,7 @@ member_bitfield_declarator: attribute_opt: /* empty */ { $$ = NULL; } - | attribute_opt ATTRIBUTE_PHRASE + | attribute_opt ATTRIBUTE_PHRASE { $$ = $2; } ; enum_body: -- 2.51.0 From ec28bfff83c49b65527f0055e313d9d7c8c04a31 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 14 Jan 2025 00:00:48 +0900 Subject: [PATCH 06/16] genksyms: decouple ATTRIBUTE_PHRASE from type-qualifier The __attribute__ keyword can appear in more contexts than 'const' or 'volatile'. To avoid grammatical conflicts with future changes, ATTRIBUTE_PHRASE should not be reduced into type_qualifier. No functional changes are intended. Signed-off-by: Masahiro Yamada Acked-by: Nicolas Schier --- scripts/genksyms/parse.y | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y index e3c160046143..cd933a95548d 100644 --- a/scripts/genksyms/parse.y +++ b/scripts/genksyms/parse.y @@ -216,6 +216,7 @@ decl_specifier: } | type_specifier { dont_want_type_specifier = true; $$ = $1; } | type_qualifier + | ATTRIBUTE_PHRASE ; storage_class_specifier: @@ -285,11 +286,13 @@ type_qualifier_seq_opt: type_qualifier_seq: type_qualifier + | ATTRIBUTE_PHRASE | type_qualifier_seq type_qualifier { $$ = $2; } + | type_qualifier_seq ATTRIBUTE_PHRASE { $$ = $2; } ; type_qualifier: - CONST_KEYW | VOLATILE_KEYW | ATTRIBUTE_PHRASE + CONST_KEYW | VOLATILE_KEYW | RESTRICT_KEYW { /* restrict has no effect in prototypes so ignore it */ remove_node($1); -- 2.51.0 From 2966b66c94a2b0d897f8626b8f2c50a0fd4878a9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 14 Jan 2025 00:00:49 +0900 Subject: [PATCH 07/16] genksyms: fix syntax error for attribute before abstract_declarator A longstanding issue with genksyms is that it has hidden syntax errors. When a syntax error occurs, yyerror() is called. However, error_with_pos() is a no-op unless the -w option is provided. You can observe syntax errors by manually passing the -w option. For example, with CONFIG_MODVERSIONS=y on v6.13-rc1: $ make -s KCFLAGS=-D__GENKSYMS__ init/main.i $ cat init/main.i | scripts/genksyms/genksyms -w [ snip ] ./include/linux/efi.h:1225: syntax error The syntax error occurs in the following code in include/linux/efi.h: efi_status_t efi_call_acpi_prm_handler(efi_status_t (__efiapi *handler_addr)(u64, void *), u64 param_buffer_addr, void *context); The issue arises from __efiapi, which is defined as either __attribute__((ms_abi)) or __attribute__((regparm(0))). This commit allows abstract_declarator to be prefixed with attributes. To avoid conflicts, I tweaked the rule for decl_specifier_seq. Due to this change, a standalone attribute cannot become decl_specifier_seq. Otherwise, I do not know how to resolve the conflicts. The following code, which was previously accepted by genksyms, will now result in a syntax error: void my_func(__attribute__((unused))x); I do not think it is a big deal because GCC also fails to parse it. $ echo 'void my_func(__attribute__((unused))x);' | gcc -c -x c - :1:37: error: unknown type name 'x' Signed-off-by: Masahiro Yamada Acked-by: Nicolas Schier --- scripts/genksyms/parse.y | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y index cd933a95548d..54e16c2e0b4b 100644 --- a/scripts/genksyms/parse.y +++ b/scripts/genksyms/parse.y @@ -203,8 +203,9 @@ decl_specifier_seq_opt: ; decl_specifier_seq: - decl_specifier { decl_spec = *$1; } + attribute_opt decl_specifier { decl_spec = *$2; } | decl_specifier_seq decl_specifier { decl_spec = *$2; } + | decl_specifier_seq ATTRIBUTE_PHRASE { decl_spec = *$2; } ; decl_specifier: @@ -216,7 +217,6 @@ decl_specifier: } | type_specifier { dont_want_type_specifier = true; $$ = $1; } | type_qualifier - | ATTRIBUTE_PHRASE ; storage_class_specifier: @@ -406,8 +406,8 @@ direct_abstract_declarator1: { $$ = $4; } | direct_abstract_declarator1 BRACKET_PHRASE { $$ = $2; } - | open_paren abstract_declarator ')' - { $$ = $3; } + | open_paren attribute_opt abstract_declarator ')' + { $$ = $4; } | open_paren error ')' { $$ = $3; } | BRACKET_PHRASE -- 2.51.0 From a8b7d066f8626ec847d3e66aef1320968d1fe298 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 14 Jan 2025 00:00:50 +0900 Subject: [PATCH 08/16] genksyms: fix syntax error for attribute before nested_declarator A longstanding issue with genksyms is that it has hidden syntax errors. When a syntax error occurs, yyerror() is called. However, error_with_pos() is a no-op unless the -w option is provided. You can observe syntax errors by manually passing the -w option. For example, with CONFIG_MODVERSIONS=y on v6.13-rc1: $ make -s KCFLAGS=-D__GENKSYMS__ drivers/acpi/prmt.i $ cat drivers/acpi/prmt.i | scripts/genksyms/genksyms -w [ snip ] drivers/acpi/prmt.c:56: syntax error The syntax error occurs in the following code in drivers/acpi/prmt.c: struct prm_handler_info { [ snip ] efi_status_t (__efiapi *handler_addr)(u64, void *); [ snip ] }; The issue arises from __efiapi, which is defined as either __attribute__((ms_abi)) or __attribute__((regparm(0))). This commit allows nested_declarator to be prefixed with attributes. Signed-off-by: Masahiro Yamada Acked-by: Nicolas Schier --- scripts/genksyms/parse.y | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y index 54e16c2e0b4b..49d3e536b9a8 100644 --- a/scripts/genksyms/parse.y +++ b/scripts/genksyms/parse.y @@ -345,8 +345,8 @@ direct_nested_declarator1: { $$ = $4; } | direct_nested_declarator1 BRACKET_PHRASE { $$ = $2; } - | '(' nested_declarator ')' - { $$ = $3; } + | '(' attribute_opt nested_declarator ')' + { $$ = $4; } | '(' error ')' { $$ = $3; } ; -- 2.51.0 From 2ac068cb0b366c61e7aebaccf0240eae8b2c1b43 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 14 Jan 2025 00:00:51 +0900 Subject: [PATCH 09/16] genksyms: fix syntax error for attribute after abstact_declarator A longstanding issue with genksyms is that it has hidden syntax errors. When a syntax error occurs, yyerror() is called. However, error_with_pos() is a no-op unless the -w option is provided. You can observe syntax errors by manually passing the -w option. For example, with CONFIG_MODVERSIONS=y on v6.13-rc1: $ make -s KCFLAGS=-D__GENKSYMS__ kernel/module/main.i $ cat kernel/module/main.i | scripts/genksyms/genksyms -w [ snip ] kernel/module/main.c:97: syntax error The syntax error occurs in the following code in kernel/module/main.c: static void __mod_update_bounds(enum mod_mem_type type __maybe_unused, void *base, unsigned int size, struct mod_tree_root *tree) { [ snip ] } The issue arises from __maybe_unused, which is defined as __attribute__((__unused__)). This commit allows direct_abstract_declarator to be followed with attributes. Signed-off-by: Masahiro Yamada Acked-by: Nicolas Schier --- scripts/genksyms/parse.y | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y index 49d3e536b9a8..82774df50642 100644 --- a/scripts/genksyms/parse.y +++ b/scripts/genksyms/parse.y @@ -383,8 +383,8 @@ abstract_declarator: ptr_operator | ptr_operator abstract_declarator { $$ = $2 ? $2 : $1; } - | direct_abstract_declarator - { $$ = $1; dont_want_type_specifier = false; } + | direct_abstract_declarator attribute_opt + { $$ = $2; dont_want_type_specifier = false; } ; direct_abstract_declarator: -- 2.51.0 From 82db1c29103ebf581484c0b30805e68726121dcb Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 14 Jan 2025 00:00:52 +0900 Subject: [PATCH 10/16] genksyms: fix syntax error for attribute after 'struct' A longstanding issue with genksyms is that it has hidden syntax errors. When a syntax error occurs, yyerror() is called. However, error_with_pos() is a no-op unless the -w option is provided. You can observe syntax errors by manually passing the -w option. For example, with CONFIG_MODVERSIONS=y on v6.13-rc1: $ make -s KCFLAGS=-D__GENKSYMS__ arch/x86/kernel/cpu/mshyperv.i $ cat arch/x86/kernel/cpu/mshyperv.i | scripts/genksyms/genksyms -w [ snip ] ./arch/x86/include/asm/svm.h:122: syntax error The syntax error occurs in the following code in arch/x86/include/asm/svm.h: struct __attribute__ ((__packed__)) vmcb_control_area { [ snip ] }; The issue arises from __attribute__ immediately after the 'struct' keyword. This commit allows the 'struct' keyword to be followed by attributes. The lexer must be adjusted because dont_want_brace_phase should not be decremented while processing attributes. Signed-off-by: Masahiro Yamada Acked-by: Nicolas Schier --- scripts/genksyms/lex.l | 7 ++++++- scripts/genksyms/parse.y | 10 +++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/scripts/genksyms/lex.l b/scripts/genksyms/lex.l index e886133af578..a1f969dcf24f 100644 --- a/scripts/genksyms/lex.l +++ b/scripts/genksyms/lex.l @@ -438,7 +438,12 @@ fini: if (suppress_type_lookup > 0) --suppress_type_lookup; - if (dont_want_brace_phrase > 0) + + /* + * __attribute__() can be placed immediately after the 'struct' keyword. + * e.g.) struct __attribute__((__packed__)) foo { ... }; + */ + if (token != ATTRIBUTE_PHRASE && dont_want_brace_phrase > 0) --dont_want_brace_phrase; yylval = &next_node->next; diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y index 82774df50642..33639232a709 100644 --- a/scripts/genksyms/parse.y +++ b/scripts/genksyms/parse.y @@ -234,16 +234,16 @@ type_specifier: /* References to s/u/e's defined elsewhere. Rearrange things so that it is easier to expand the definition fully later. */ - | STRUCT_KEYW IDENT - { remove_node($1); (*$2)->tag = SYM_STRUCT; $$ = $2; } + | STRUCT_KEYW attribute_opt IDENT + { remove_node($1); (*$3)->tag = SYM_STRUCT; $$ = $3; } | UNION_KEYW IDENT { remove_node($1); (*$2)->tag = SYM_UNION; $$ = $2; } | ENUM_KEYW IDENT { remove_node($1); (*$2)->tag = SYM_ENUM; $$ = $2; } /* Full definitions of an s/u/e. Record it. */ - | STRUCT_KEYW IDENT class_body - { record_compound($1, $2, $3, SYM_STRUCT); $$ = $3; } + | STRUCT_KEYW attribute_opt IDENT class_body + { record_compound($1, $3, $4, SYM_STRUCT); $$ = $4; } | UNION_KEYW IDENT class_body { record_compound($1, $2, $3, SYM_UNION); $$ = $3; } | ENUM_KEYW IDENT enum_body @@ -254,7 +254,7 @@ type_specifier: | ENUM_KEYW enum_body { add_symbol(NULL, SYM_ENUM, NULL, 0); $$ = $2; } /* Anonymous s/u definitions. Nothing needs doing. */ - | STRUCT_KEYW class_body { $$ = $2; } + | STRUCT_KEYW attribute_opt class_body { $$ = $3; } | UNION_KEYW class_body { $$ = $2; } ; -- 2.51.0 From 6494bd2d05f927fc0395c2ea11461517a9e0bb80 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 14 Jan 2025 00:00:53 +0900 Subject: [PATCH 11/16] genksyms: fix syntax error for attribute after 'union' A longstanding issue with genksyms is that it has hidden syntax errors. When a syntax error occurs, yyerror() is called. However, error_with_pos() is a no-op unless the -w option is provided. You can observe syntax errors by manually passing the -w option. For example, with CONFIG_MODVERSIONS=y on v6.13-rc1: $ make -s KCFLAGS=-D__GENKSYMS__ fs/lockd/svc.i $ cat fs/lockd/svc.i | scripts/genksyms/genksyms -w [ snip ] ./include/net/addrconf.h:35: syntax error The syntax error occurs in the following code in include/net/addrconf.h: union __packed { [ snip ] }; The issue arises from __packed, which is defined as __attribute__((__packed__)), immediately after the 'union' keyword. This commit allows the 'union' keyword to be followed by attributes. Signed-off-by: Masahiro Yamada Acked-by: Nicolas Schier --- scripts/genksyms/parse.y | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y index 33639232a709..a2cd035a78c9 100644 --- a/scripts/genksyms/parse.y +++ b/scripts/genksyms/parse.y @@ -236,16 +236,16 @@ type_specifier: so that it is easier to expand the definition fully later. */ | STRUCT_KEYW attribute_opt IDENT { remove_node($1); (*$3)->tag = SYM_STRUCT; $$ = $3; } - | UNION_KEYW IDENT - { remove_node($1); (*$2)->tag = SYM_UNION; $$ = $2; } + | UNION_KEYW attribute_opt IDENT + { remove_node($1); (*$3)->tag = SYM_UNION; $$ = $3; } | ENUM_KEYW IDENT { remove_node($1); (*$2)->tag = SYM_ENUM; $$ = $2; } /* Full definitions of an s/u/e. Record it. */ | STRUCT_KEYW attribute_opt IDENT class_body { record_compound($1, $3, $4, SYM_STRUCT); $$ = $4; } - | UNION_KEYW IDENT class_body - { record_compound($1, $2, $3, SYM_UNION); $$ = $3; } + | UNION_KEYW attribute_opt IDENT class_body + { record_compound($1, $3, $4, SYM_UNION); $$ = $4; } | ENUM_KEYW IDENT enum_body { record_compound($1, $2, $3, SYM_ENUM); $$ = $3; } /* @@ -255,7 +255,7 @@ type_specifier: { add_symbol(NULL, SYM_ENUM, NULL, 0); $$ = $2; } /* Anonymous s/u definitions. Nothing needs doing. */ | STRUCT_KEYW attribute_opt class_body { $$ = $3; } - | UNION_KEYW class_body { $$ = $2; } + | UNION_KEYW attribute_opt class_body { $$ = $3; } ; simple_type_specifier: -- 2.51.0 From c825840527813582385edca3ddeee46886527258 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 14 Jan 2025 00:00:54 +0900 Subject: [PATCH 12/16] genksyms: fix syntax error for builtin (u)int*x*_t types A longstanding issue with genksyms is that it has hidden syntax errors. When a syntax error occurs, yyerror() is called. However, error_with_pos() is a no-op unless the -w option is provided. You can observe syntax errors by manually passing the -w option. For example, genksyms fails to parse the following code in arch/arm64/lib/xor-neon.c: static inline uint64x2_t eor3(uint64x2_t p, uint64x2_t q, uint64x2_t r) { [ snip ] } The syntax error occurs because genksyms does not recognize the uint64x2_t keyword. This commit adds support for builtin types described in Arm Neon Intrinsics Reference. Signed-off-by: Masahiro Yamada Acked-by: Nicolas Schier --- scripts/genksyms/lex.l | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/genksyms/lex.l b/scripts/genksyms/lex.l index a1f969dcf24f..22aeb57649d9 100644 --- a/scripts/genksyms/lex.l +++ b/scripts/genksyms/lex.l @@ -51,6 +51,7 @@ MC_TOKEN ([~%^&*+=|<>/-]=)|(&&)|("||")|(->)|(<<)|(>>) %% +u?int(8|16|32|64)x(1|2|4|8|16)_t return BUILTIN_INT_KEYW; /* Keep track of our location in the original source files. */ ^#[ \t]+{INT}[ \t]+\"[^\"\n]+\".*\n return FILENAME; -- 2.51.0 From a23d4c2f5b80a8dc5f1e40658abbe5983af1a0e9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 14 Jan 2025 00:00:55 +0900 Subject: [PATCH 13/16] genksyms: fix syntax error for attribute before init-declarator A longstanding issue with genksyms is that it has hidden syntax errors. For example, genksyms fails to parse the following valid code: int x, __attribute__((__section__(".init.data")))y; Here, only 'y' is annotated by the attribute, although I am not aware of actual uses of this pattern in the kernel tree. When a syntax error occurs, yyerror() is called. However, error_with_pos() is a no-op unless the -w option is provided. You can observe syntax errors by manually passing the -w option. $ echo 'int x, __attribute__((__section__(".init.data")))y;' | scripts/genksyms/genksyms -w :1: syntax error This commit allows attributes to be placed between a comma and init_declarator. Signed-off-by: Masahiro Yamada Acked-by: Nicolas Schier --- scripts/genksyms/parse.y | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y index a2cd035a78c9..ee600a804fa1 100644 --- a/scripts/genksyms/parse.y +++ b/scripts/genksyms/parse.y @@ -173,9 +173,9 @@ init_declarator_list: $$ = $1; dont_want_type_specifier = true; } - | init_declarator_list ',' init_declarator - { struct string_list *decl = *$3; - *$3 = NULL; + | init_declarator_list ',' attribute_opt init_declarator + { struct string_list *decl = *$4; + *$4 = NULL; free_list(*$2, NULL); *$2 = decl_spec; @@ -186,7 +186,7 @@ init_declarator_list: add_symbol(current_name, is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern); current_name = NULL; - $$ = $3; + $$ = $4; dont_want_type_specifier = true; } ; -- 2.51.0 From a314f52a0210730d0d556de76bb7388e76d4597d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 20 Jan 2025 16:59:14 +0900 Subject: [PATCH 14/16] kconfig: fix file name in warnings when loading KCONFIG_DEFCONFIG_LIST Most 'make *config' commands use .config as the base configuration file. When .config does not exist, Kconfig tries to load a file listed in KCONFIG_DEFCONFIG_LIST instead. However, since commit b75b0a819af9 ("kconfig: change defconfig_list option to environment variable"), warning messages have displayed an incorrect file name in such cases. Below is a demonstration using Debian Trixie. While loading /boot/config-6.12.9-amd64, the warning messages incorrectly show .config as the file name. With this commit, the correct file name is displayed in warnings. [Before] $ rm -f .config $ make config # # using defaults found in /boot/config-6.12.9-amd64 # .config:6804:warning: symbol value 'm' invalid for FB_BACKLIGHT .config:9895:warning: symbol value 'm' invalid for ANDROID_BINDER_IPC [After] $ rm -f .config $ make config # # using defaults found in /boot/config-6.12.9-amd64 # /boot/config-6.12.9-amd64:6804:warning: symbol value 'm' invalid for FB_BACKLIGHT /boot/config-6.12.9-amd64:9895:warning: symbol value 'm' invalid for ANDROID_BINDER_IPC Fixes: b75b0a819af9 ("kconfig: change defconfig_list option to environment variable") Signed-off-by: Masahiro Yamada --- scripts/kconfig/confdata.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 4286d5e7f95d..3b55e7a4131d 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -360,10 +360,12 @@ int conf_read_simple(const char *name, int def) *p = '\0'; - in = zconf_fopen(env); + name = env; + + in = zconf_fopen(name); if (in) { conf_message("using defaults found in %s", - env); + name); goto load; } -- 2.51.0 From a409fc1463d664002ea9bf700ae4674df03de111 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 20 Jan 2025 17:10:31 +0900 Subject: [PATCH 15/16] kconfig: fix memory leak in sym_warn_unmet_dep() The string allocated in sym_warn_unmet_dep() is never freed, leading to a memory leak when an unmet dependency is detected. Fixes: f8f69dc0b4e0 ("kconfig: make unmet dependency warnings readable") Signed-off-by: Masahiro Yamada Reviewed-by: Petr Vorel --- scripts/kconfig/symbol.c | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 89b84bf8e21f..7beb59dec5a0 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -388,6 +388,7 @@ static void sym_warn_unmet_dep(const struct symbol *sym) " Selected by [m]:\n"); fputs(str_get(&gs), stderr); + str_free(&gs); sym_warnings++; } -- 2.51.0 From 71d815bf5dfd4f63f7557e0abe7f257c202863a1 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 13 Jan 2025 16:53:07 +0100 Subject: [PATCH 16/16] kbuild: Strip runtime const RELA sections correctly Due to the fact that runtime const ELF sections are named without a leading period or double underscore, the RSTRIP logic that removes the static RELA sections from vmlinux fails to identify them. This results in a situation like below, where some sections that were supposed to get removed are left behind. [Nr] Name Type Address Off Size ES Flg Lk Inf Al [58] runtime_shift_d_hash_shift PROGBITS ffffffff83500f50 2900f50 000014 00 A 0 0 1 [59] .relaruntime_shift_d_hash_shift RELA 0000000000000000 55b6f00 000078 18 I 70 58 8 [60] runtime_ptr_dentry_hashtable PROGBITS ffffffff83500f68 2900f68 000014 00 A 0 0 1 [61] .relaruntime_ptr_dentry_hashtable RELA 0000000000000000 55b6f78 000078 18 I 70 60 8 [62] runtime_ptr_USER_PTR_MAX PROGBITS ffffffff83500f80 2900f80 000238 00 A 0 0 1 [63] .relaruntime_ptr_USER_PTR_MAX RELA 0000000000000000 55b6ff0 000d50 18 I 70 62 8 So tweak the match expression to strip all sections starting with .rel. While at it, consolidate the logic used by RISC-V, s390 and x86 into a single shared Makefile library command. Link: https://lore.kernel.org/all/CAHk-=wjk3ynjomNvFN8jf9A1k=qSc=JFF591W00uXj-qqNUxPQ@mail.gmail.com/ Signed-off-by: Ard Biesheuvel Reviewed-by: Charlie Jenkins Tested-by: Charlie Jenkins Tested-by: Alexander Gordeev Signed-off-by: Masahiro Yamada --- arch/riscv/Makefile.postlink | 8 ++------ arch/s390/Makefile.postlink | 6 +----- arch/x86/Makefile.postlink | 6 +----- scripts/Makefile.lib | 3 +++ 4 files changed, 7 insertions(+), 16 deletions(-) diff --git a/arch/riscv/Makefile.postlink b/arch/riscv/Makefile.postlink index 829b9abc91f6..6b0580949b6a 100644 --- a/arch/riscv/Makefile.postlink +++ b/arch/riscv/Makefile.postlink @@ -10,6 +10,7 @@ __archpost: -include include/config/auto.conf include $(srctree)/scripts/Kbuild.include +include $(srctree)/scripts/Makefile.lib quiet_cmd_relocs_check = CHKREL $@ cmd_relocs_check = \ @@ -19,11 +20,6 @@ ifdef CONFIG_RELOCATABLE quiet_cmd_cp_vmlinux_relocs = CPREL vmlinux.relocs cmd_cp_vmlinux_relocs = cp vmlinux vmlinux.relocs -quiet_cmd_relocs_strip = STRIPREL $@ -cmd_relocs_strip = $(OBJCOPY) --remove-section='.rel.*' \ - --remove-section='.rel__*' \ - --remove-section='.rela.*' \ - --remove-section='.rela__*' $@ endif # `@true` prevents complaint when there is nothing to be done @@ -33,7 +29,7 @@ vmlinux: FORCE ifdef CONFIG_RELOCATABLE $(call if_changed,relocs_check) $(call if_changed,cp_vmlinux_relocs) - $(call if_changed,relocs_strip) + $(call if_changed,strip_relocs) endif clean: diff --git a/arch/s390/Makefile.postlink b/arch/s390/Makefile.postlink index df82f5410769..1ae5478cd6ac 100644 --- a/arch/s390/Makefile.postlink +++ b/arch/s390/Makefile.postlink @@ -11,6 +11,7 @@ __archpost: -include include/config/auto.conf include $(srctree)/scripts/Kbuild.include +include $(srctree)/scripts/Makefile.lib CMD_RELOCS=arch/s390/tools/relocs OUT_RELOCS = arch/s390/boot @@ -19,11 +20,6 @@ quiet_cmd_relocs = RELOCS $(OUT_RELOCS)/relocs.S mkdir -p $(OUT_RELOCS); \ $(CMD_RELOCS) $@ > $(OUT_RELOCS)/relocs.S -quiet_cmd_strip_relocs = RSTRIP $@ - cmd_strip_relocs = \ - $(OBJCOPY) --remove-section='.rel.*' --remove-section='.rel__*' \ - --remove-section='.rela.*' --remove-section='.rela__*' $@ - vmlinux: FORCE $(call cmd,relocs) $(call cmd,strip_relocs) diff --git a/arch/x86/Makefile.postlink b/arch/x86/Makefile.postlink index fef2e977cc7d..8b8a68162c94 100644 --- a/arch/x86/Makefile.postlink +++ b/arch/x86/Makefile.postlink @@ -11,6 +11,7 @@ __archpost: -include include/config/auto.conf include $(srctree)/scripts/Kbuild.include +include $(srctree)/scripts/Makefile.lib CMD_RELOCS = arch/x86/tools/relocs OUT_RELOCS = arch/x86/boot/compressed @@ -20,11 +21,6 @@ quiet_cmd_relocs = RELOCS $(OUT_RELOCS)/$@.relocs $(CMD_RELOCS) $@ > $(OUT_RELOCS)/$@.relocs; \ $(CMD_RELOCS) --abs-relocs $@ -quiet_cmd_strip_relocs = RSTRIP $@ - cmd_strip_relocs = \ - $(OBJCOPY) --remove-section='.rel.*' --remove-section='.rel__*' \ - --remove-section='.rela.*' --remove-section='.rela__*' $@ - # `@true` prevents complaint when there is nothing to be done vmlinux: FORCE diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 7395200538da..f604f51d23ca 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -374,6 +374,9 @@ quiet_cmd_ar = AR $@ quiet_cmd_objcopy = OBJCOPY $@ cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@ +quiet_cmd_strip_relocs = RSTRIP $@ +cmd_strip_relocs = $(OBJCOPY) --remove-section='.rel*' $@ + # Gzip # --------------------------------------------------------------------------- -- 2.51.0