From: Andreas Gruenbacher <agruen@suse.de>
Subject: genksyms: add --override flag
Patch-mainline: not yet

Add --override flag to genksyms to allow overriding types with old
definitions using the 'override' keyword. This is similar to -p --preserve,
but it doesn't abort the build if a symtype cannot be preserved

[mmarek: added KBUILD_OVERRIDE env var to set this globally for the entire
 build]
---
 scripts/Makefile.build      |    1 +
 scripts/genksyms/genksyms.c |   21 +++++++++++++++------
 2 files changed, 16 insertions(+), 6 deletions(-)

--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -161,6 +161,7 @@ cmd_gensymtypes =
     $(CPP) -D__GENKSYMS__ $(c_flags) $< |                                   \
     $(GENKSYMS) $(if $(1), -T $(2)) -a $(ARCH)                              \
      $(if $(KBUILD_PRESERVE),-p)                                            \
+     $(if $(KBUILD_OVERRIDE),-o)                                            \
      -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
 
 quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
--- a/scripts/genksyms/genksyms.c
+++ b/scripts/genksyms/genksyms.c
@@ -43,7 +43,7 @@ int cur_line = 1;
 char *cur_filename;
 
 static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types,
-	   flag_preserve, flag_warnings;
+	   flag_override, flag_preserve, flag_warnings;
 static const char *arch = "";
 static const char *mod_prefix = "";
 
@@ -200,7 +200,7 @@ static struct symbol *__add_symbol(const
 				sym->is_declared = 1;
 				return sym;
 			} else if (!sym->is_declared) {
-				if (sym->is_override && flag_preserve) {
+				if (sym->is_override && flag_override) {
 					print_location();
 					fprintf(stderr, "ignoring ");
 					print_type_name(type, name);
@@ -586,11 +586,13 @@ void export_symbol(const char *name)
 			struct symbol *n = sym->expansion_trail;
 
 			if (sym->status != STATUS_UNCHANGED) {
+				int fail = sym->is_override && flag_preserve;
+
 				if (!has_changed) {
 					print_location();
 					fprintf(stderr, "%s: %s: modversion "
 						"changed because of changes "
-						"in ", flag_preserve ? "error" :
+						"in ", fail ? "error" :
 						       "warning", name);
 				} else
 					fprintf(stderr, ", ");
@@ -598,7 +600,7 @@ void export_symbol(const char *name)
 				if (sym->status == STATUS_DEFINED)
 					fprintf(stderr, " (became defined)");
 				has_changed = 1;
-				if (flag_preserve)
+				if (fail)
 					errors++;
 			}
 			sym->expansion_trail = 0;
@@ -655,6 +657,7 @@ static void genksyms_usage(void)
 	      "  -D, --dump            Dump expanded symbol defs (for debugging only)\n"
 	      "  -r, --reference file  Read reference symbols from a file\n"
 	      "  -T, --dump-types file Dump expanded types into file\n"
+	      "  -o, --override        Allow to override reference modversions\n"
 	      "  -p, --preserve        Preserve reference modversions or fail\n"
 	      "  -w, --warnings        Enable warnings\n"
 	      "  -q, --quiet           Disable warnings (default)\n"
@@ -666,6 +669,7 @@ static void genksyms_usage(void)
 	      "  -D                    Dump expanded symbol defs (for debugging only)\n"
 	      "  -r file               Read reference symbols from a file\n"
 	      "  -T file               Dump expanded types into file\n"
+	      "  -o                    Allow to override reference modversions\n"
 	      "  -p                    Preserve reference modversions or fail\n"
 	      "  -w                    Enable warnings\n"
 	      "  -q                    Disable warnings (default)\n"
@@ -690,15 +694,16 @@ int main(int argc, char **argv)
 		{"reference", 1, 0, 'r'},
 		{"dump-types", 1, 0, 'T'},
 		{"preserve", 0, 0, 'p'},
+		{"override", 0, 0, 'o'},
 		{"version", 0, 0, 'V'},
 		{"help", 0, 0, 'h'},
 		{0, 0, 0, 0}
 	};
 
-	while ((o = getopt_long(argc, argv, "a:dwqVDr:T:ph",
+	while ((o = getopt_long(argc, argv, "a:dwqVDr:T:oph",
 				&long_opts[0], NULL)) != EOF)
 #else				/* __GNU_LIBRARY__ */
-	while ((o = getopt(argc, argv, "a:dwqVDr:T:ph")) != EOF)
+	while ((o = getopt(argc, argv, "a:dwqVDr:T:oph")) != EOF)
 #endif				/* __GNU_LIBRARY__ */
 		switch (o) {
 		case 'a':
@@ -735,7 +740,11 @@ int main(int argc, char **argv)
 				return 1;
 			}
 			break;
+		case 'o':
+			flag_override = 1;
+			break;
 		case 'p':
+			flag_override = 1;
 			flag_preserve = 1;
 			break;
 		case 'h':
