aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@suse.de>2008-12-01 17:21:03 -0500
committerSam Ravnborg <sam@ravnborg.org>2008-12-03 16:33:12 -0500
commit5dae9a550a7478c8d6a7da2336d3ceeebf90ab84 (patch)
tree15936b08138ed2f8abfee946c3f2c31b76a4e491
parent64e6c1e12372840e7caf8e25325a9e9c5fd370e6 (diff)
genksyms: allow to ignore symbol checksum changes
This adds an "override" keyword for use in *.symvers / *.symref files. When a symbol is overridden, the symbol's old definition will be used for computing checksums instead of the new one, preserving the previous checksum. (Genksyms will still warn about the change.) This is meant to allow distributions to hide minor actual as well as fake ABI changes. (For example, when extra type information becomes available because additional headers are included, this may change checksums even though none of the types used have actully changed.) This approach also allows to get rid of "#ifdef __GENKSYMS__" hacks in the code, which are currently used in some vendor kernels to work around checksum changes. Signed-off-by: Andreas Gruenbacher <agruen@suse.de> Cc: Randy Dunlap <randy.dunlap@oracle.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
-rw-r--r--scripts/genksyms/genksyms.c34
-rw-r--r--scripts/genksyms/genksyms.h1
2 files changed, 31 insertions, 4 deletions
diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c
index ddac1746908e..3a8297b5184c 100644
--- a/scripts/genksyms/genksyms.c
+++ b/scripts/genksyms/genksyms.c
@@ -191,11 +191,26 @@ struct symbol *__add_symbol(const char *name, enum symbol_type type,
191 /* fall through */ ; 191 /* fall through */ ;
192 else if (sym->type == type && 192 else if (sym->type == type &&
193 equal_list(sym->defn, defn)) { 193 equal_list(sym->defn, defn)) {
194 if (!sym->is_declared && sym->is_override) {
195 print_location();
196 print_type_name(type, name);
197 fprintf(stderr, " modversion is "
198 "unchanged\n");
199 }
194 sym->is_declared = 1; 200 sym->is_declared = 1;
195 return sym; 201 return sym;
196 } else if (!sym->is_declared) { 202 } else if (!sym->is_declared) {
197 status = is_unknown_symbol(sym) ? 203 if (sym->is_override && flag_preserve) {
198 STATUS_DEFINED : STATUS_MODIFIED; 204 print_location();
205 fprintf(stderr, "ignoring ");
206 print_type_name(type, name);
207 fprintf(stderr, " modversion change\n");
208 sym->is_declared = 1;
209 return sym;
210 } else {
211 status = is_unknown_symbol(sym) ?
212 STATUS_DEFINED : STATUS_MODIFIED;
213 }
199 } else { 214 } else {
200 error_with_pos("redefinition of %s", name); 215 error_with_pos("redefinition of %s", name);
201 return sym; 216 return sym;
@@ -229,6 +244,7 @@ struct symbol *__add_symbol(const char *name, enum symbol_type type,
229 244
230 sym->is_declared = !is_reference; 245 sym->is_declared = !is_reference;
231 sym->status = status; 246 sym->status = status;
247 sym->is_override = 0;
232 248
233 if (flag_debug) { 249 if (flag_debug) {
234 fprintf(debugfile, "Defn for %s %s == <", 250 fprintf(debugfile, "Defn for %s %s == <",
@@ -348,9 +364,16 @@ static void read_reference(FILE *f)
348 while (!feof(f)) { 364 while (!feof(f)) {
349 struct string_list *defn = NULL; 365 struct string_list *defn = NULL;
350 struct string_list *sym, *def; 366 struct string_list *sym, *def;
351 int is_extern = 0; 367 int is_extern = 0, is_override = 0;
368 struct symbol *subsym;
352 369
353 sym = read_node(f); 370 sym = read_node(f);
371 if (sym && sym->tag == SYM_NORMAL &&
372 !strcmp(sym->string, "override")) {
373 is_override = 1;
374 free_node(sym);
375 sym = read_node(f);
376 }
354 if (!sym) 377 if (!sym)
355 continue; 378 continue;
356 def = read_node(f); 379 def = read_node(f);
@@ -365,8 +388,9 @@ static void read_reference(FILE *f)
365 defn = def; 388 defn = def;
366 def = read_node(f); 389 def = read_node(f);
367 } 390 }
368 add_reference_symbol(xstrdup(sym->string), sym->tag, 391 subsym = add_reference_symbol(xstrdup(sym->string), sym->tag,
369 defn, is_extern); 392 defn, is_extern);
393 subsym->is_override = is_override;
370 free_node(sym); 394 free_node(sym);
371 } 395 }
372} 396}
@@ -743,6 +767,8 @@ int main(int argc, char **argv)
743 while (visited_symbols != (struct symbol *)-1L) { 767 while (visited_symbols != (struct symbol *)-1L) {
744 struct symbol *sym = visited_symbols; 768 struct symbol *sym = visited_symbols;
745 769
770 if (sym->is_override)
771 fputs("override ", dumpfile);
746 if (sym->type != SYM_NORMAL) { 772 if (sym->type != SYM_NORMAL) {
747 putc(symbol_type_name[sym->type][0], dumpfile); 773 putc(symbol_type_name[sym->type][0], dumpfile);
748 putc('#', dumpfile); 774 putc('#', dumpfile);
diff --git a/scripts/genksyms/genksyms.h b/scripts/genksyms/genksyms.h
index 2831158426cd..25c4d40cefc1 100644
--- a/scripts/genksyms/genksyms.h
+++ b/scripts/genksyms/genksyms.h
@@ -49,6 +49,7 @@ struct symbol {
49 int is_extern; 49 int is_extern;
50 int is_declared; 50 int is_declared;
51 enum symbol_status status; 51 enum symbol_status status;
52 int is_override;
52}; 53};
53 54
54typedef struct string_list **yystype; 55typedef struct string_list **yystype;