]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.suse/genksyms-override.diff
Move xen patchset to new version's subdir.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.suse / genksyms-override.diff
diff --git a/src/patches/suse-2.6.27.31/patches.suse/genksyms-override.diff b/src/patches/suse-2.6.27.31/patches.suse/genksyms-override.diff
new file mode 100644 (file)
index 0000000..1b77b4a
--- /dev/null
@@ -0,0 +1,110 @@
+From: Andreas Gruenbacher <agruen@suse.de>
+Subject: 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>
+
+---
+ scripts/genksyms/genksyms.c |   34 ++++++++++++++++++++++++++++++----
+ scripts/genksyms/genksyms.h |    1 +
+ 2 files changed, 31 insertions(+), 4 deletions(-)
+
+--- a/scripts/genksyms/genksyms.c
++++ b/scripts/genksyms/genksyms.c
+@@ -191,11 +191,26 @@ struct symbol *__add_symbol(const char *
+                               /* fall through */ ;
+                       else if (sym->type == type &&
+                                equal_list(sym->defn, defn)) {
++                              if (!sym->is_declared && sym->is_override) {
++                                      print_location();
++                                      print_type_name(type, name);
++                                      fprintf(stderr, " modversion is "
++                                              "unchanged\n");
++                              }
+                               sym->is_declared = 1;
+                               return sym;
+                       } else if (!sym->is_declared) {
+-                              status = is_unknown_symbol(sym) ?
+-                                      STATUS_DEFINED : STATUS_MODIFIED;
++                              if (sym->is_override && flag_preserve) {
++                                      print_location();
++                                      fprintf(stderr, "ignoring ");
++                                      print_type_name(type, name);
++                                      fprintf(stderr, " modversion change\n");
++                                      sym->is_declared = 1;
++                                      return sym;
++                              } else {
++                                      status = is_unknown_symbol(sym) ?
++                                              STATUS_DEFINED : STATUS_MODIFIED;
++                              }
+                       } else {
+                               error_with_pos("redefinition of %s", name);
+                               return sym;
+@@ -229,6 +244,7 @@ struct symbol *__add_symbol(const char *
+       sym->is_declared = !is_reference;
+       sym->status = status;
++      sym->is_override = 0;
+       if (flag_debug) {
+               fprintf(debugfile, "Defn for %s %s == <",
+@@ -348,9 +364,16 @@ static void read_reference(FILE *f)
+       while (!feof(f)) {
+               struct string_list *defn = NULL;
+               struct string_list *sym, *def;
+-              int is_extern = 0;
++              int is_extern = 0, is_override = 0;
++              struct symbol *subsym;
+               sym = read_node(f);
++              if (sym && sym->tag == SYM_NORMAL &&
++                  !strcmp(sym->string, "override")) {
++                      is_override = 1;
++                      free_node(sym);
++                      sym = read_node(f);
++              }
+               if (!sym)
+                       continue;
+               def = read_node(f);
+@@ -365,8 +388,9 @@ static void read_reference(FILE *f)
+                       defn = def;
+                       def = read_node(f);
+               }
+-              add_reference_symbol(xstrdup(sym->string), sym->tag,
++              subsym = add_reference_symbol(xstrdup(sym->string), sym->tag,
+                                             defn, is_extern);
++              subsym->is_override = is_override;
+               free_node(sym);
+       }
+ }
+@@ -743,6 +767,8 @@ int main(int argc, char **argv)
+               while (visited_symbols != (struct symbol *)-1L) {
+                       struct symbol *sym = visited_symbols;
++                      if (sym->is_override)
++                              fputs("override ", dumpfile);
+                       if (sym->type != SYM_NORMAL) {
+                               putc(symbol_type_name[sym->type][0], dumpfile);
+                               putc('#', dumpfile);
+--- a/scripts/genksyms/genksyms.h
++++ b/scripts/genksyms/genksyms.h
+@@ -49,6 +49,7 @@ struct symbol {
+       int is_extern;
+       int is_declared;
+       enum symbol_status status;
++      int is_override;
+ };
+ typedef struct string_list **yystype;