modpost: add handler function pointer to sectioncheck.
authorQuentin Casasnovas <quentin.casasnovas@oracle.com>
Mon, 13 Apr 2015 11:13:17 +0000 (20:43 +0930)
committerRusty Russell <rusty@rustcorp.com.au>
Mon, 13 Apr 2015 11:32:59 +0000 (21:02 +0930)
This will be useful when we want to have special handlers which need to go
through more hops to print useful information to the user.

Signed-off-by: Quentin Casasnovas <quentin.casasnovas@oracle.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
scripts/mod/modpost.c

index 8cef46b18dc668da2419c6c05cf18e2361063e3a..0f48f8b97b17a6b3ecbd62afd2c2afe3b0186dc9 100644 (file)
@@ -930,6 +930,10 @@ struct sectioncheck {
        const char *good_tosec[20];
        enum mismatch mismatch;
        const char *symbol_white_list[20];
+       void (*handler)(const char *modname, struct elf_info *elf,
+                       const struct sectioncheck* const mismatch,
+                       Elf_Rela *r, Elf_Sym *sym, const char *fromsec);
+
 };
 
 static const struct sectioncheck sectioncheck[] = {
@@ -1417,37 +1421,49 @@ static void report_sec_mismatch(const char *modname,
        fprintf(stderr, "\n");
 }
 
-static void check_section_mismatch(const char *modname, struct elf_info *elf,
-                                  Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
+static void default_mismatch_handler(const char *modname, struct elf_info *elf,
+                                    const struct sectioncheck* const mismatch,
+                                    Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
 {
        const char *tosec;
-       const struct sectioncheck *mismatch;
+       Elf_Sym *to;
+       Elf_Sym *from;
+       const char *tosym;
+       const char *fromsym;
 
        tosec = sec_name(elf, get_secindex(elf, sym));
-       mismatch = section_mismatch(fromsec, tosec);
+       from = find_elf_symbol2(elf, r->r_offset, fromsec);
+       fromsym = sym_name(elf, from);
+       to = find_elf_symbol(elf, r->r_addend, sym);
+       tosym = sym_name(elf, to);
+
+       if (!strncmp(fromsym, "reference___initcall",
+                    sizeof("reference___initcall")-1))
+               return;
+
+       /* check whitelist - we may ignore it */
+       if (secref_whitelist(mismatch,
+                            fromsec, fromsym, tosec, tosym)) {
+               report_sec_mismatch(modname, mismatch,
+                                   fromsec, r->r_offset, fromsym,
+                                   is_function(from), tosec, tosym,
+                                   is_function(to));
+       }
+}
+
+static void check_section_mismatch(const char *modname, struct elf_info *elf,
+                                  Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
+{
+       const char *tosec = sec_name(elf, get_secindex(elf, sym));;
+       const struct sectioncheck *mismatch = section_mismatch(fromsec, tosec);
+
        if (mismatch) {
-               Elf_Sym *to;
-               Elf_Sym *from;
-               const char *tosym;
-               const char *fromsym;
-
-               from = find_elf_symbol2(elf, r->r_offset, fromsec);
-               fromsym = sym_name(elf, from);
-               to = find_elf_symbol(elf, r->r_addend, sym);
-               tosym = sym_name(elf, to);
-
-               if (!strncmp(fromsym, "reference___initcall",
-                               sizeof("reference___initcall")-1))
-                       return;
-
-               /* check whitelist - we may ignore it */
-               if (secref_whitelist(mismatch,
-                                       fromsec, fromsym, tosec, tosym)) {
-                       report_sec_mismatch(modname, mismatch,
-                          fromsec, r->r_offset, fromsym,
-                          is_function(from), tosec, tosym,
-                          is_function(to));
-               }
+               if (mismatch->handler)
+                       mismatch->handler(modname, elf,  mismatch,
+                                         r, sym, fromsec);
+               else
+                       default_mismatch_handler(modname, elf, mismatch,
+                                                r, sym, fromsec);
        }
 }