Commit 5dae9a550a7478c8d6a7da2336d3ceeebf90ab84

Authored by Andreas Gruenbacher
Committed by Sam Ravnborg
1 parent 64e6c1e123

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>

Showing 2 changed files with 31 additions and 4 deletions Side-by-side Diff

scripts/genksyms/genksyms.c
... ... @@ -191,11 +191,26 @@
191 191 /* fall through */ ;
192 192 else if (sym->type == type &&
193 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 200 sym->is_declared = 1;
195 201 return sym;
196 202 } else if (!sym->is_declared) {
197   - status = is_unknown_symbol(sym) ?
198   - STATUS_DEFINED : STATUS_MODIFIED;
  203 + if (sym->is_override && flag_preserve) {
  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 214 } else {
200 215 error_with_pos("redefinition of %s", name);
201 216 return sym;
... ... @@ -229,6 +244,7 @@
229 244  
230 245 sym->is_declared = !is_reference;
231 246 sym->status = status;
  247 + sym->is_override = 0;
232 248  
233 249 if (flag_debug) {
234 250 fprintf(debugfile, "Defn for %s %s == <",
235 251  
... ... @@ -348,9 +364,16 @@
348 364 while (!feof(f)) {
349 365 struct string_list *defn = NULL;
350 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 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 377 if (!sym)
355 378 continue;
356 379 def = read_node(f);
357 380  
... ... @@ -365,8 +388,9 @@
365 388 defn = def;
366 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 392 defn, is_extern);
  393 + subsym->is_override = is_override;
370 394 free_node(sym);
371 395 }
372 396 }
... ... @@ -743,6 +767,8 @@
743 767 while (visited_symbols != (struct symbol *)-1L) {
744 768 struct symbol *sym = visited_symbols;
745 769  
  770 + if (sym->is_override)
  771 + fputs("override ", dumpfile);
746 772 if (sym->type != SYM_NORMAL) {
747 773 putc(symbol_type_name[sym->type][0], dumpfile);
748 774 putc('#', dumpfile);
scripts/genksyms/genksyms.h
... ... @@ -49,6 +49,7 @@
49 49 int is_extern;
50 50 int is_declared;
51 51 enum symbol_status status;
  52 + int is_override;
52 53 };
53 54  
54 55 typedef struct string_list **yystype;