]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - scripts/mod/modpost.c
Merge remote-tracking branch 'modules/modules-next'
[karo-tx-linux.git] / scripts / mod / modpost.c
index 12d3db3bd46b491542090cd2db01637754467e99..e080746e1a6b528a218b416b5344368cd6db7065 100644 (file)
@@ -38,6 +38,7 @@ static int warn_unresolved = 0;
 /* How a symbol is exported */
 static int sec_mismatch_count = 0;
 static int sec_mismatch_verbose = 1;
+static int sec_mismatch_fatal = 0;
 /* ignore missing files */
 static int ignore_missing_files;
 
@@ -833,6 +834,8 @@ static const char *const section_white_list[] =
        ".xt.lit",         /* xtensa */
        ".arcextmap*",                  /* arc */
        ".gnu.linkonce.arcext*",        /* arc : modules */
+       ".cmem*",                       /* EZchip */
+       ".fmt_slot*",                   /* EZchip */
        ".gnu.lto*",
        NULL
 };
@@ -2133,6 +2136,11 @@ static void add_staging_flag(struct buffer *b, const char *name)
                buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
 }
 
+/* In kernel, this size is defined in linux/module.h;
+ * here we use Elf_Addr instead of long for covering cross-compile
+ */
+#define MODULE_NAME_LEN (64 - sizeof(Elf_Addr))
+
 /**
  * Record CRCs for unresolved symbols
  **/
@@ -2177,6 +2185,12 @@ static int add_versions(struct buffer *b, struct module *mod)
                                s->name, mod->name);
                        continue;
                }
+               if (strlen(s->name) >= MODULE_NAME_LEN) {
+                       merror("too long symbol \"%s\" [%s.ko]\n",
+                              s->name, mod->name);
+                       err = 1;
+                       break;
+               }
                buf_printf(b, "\t{ %#8x, __VMLINUX_SYMBOL_STR(%s) },\n",
                           s->crc, s->name);
        }
@@ -2374,7 +2388,7 @@ int main(int argc, char **argv)
        struct ext_sym_list *extsym_iter;
        struct ext_sym_list *extsym_start = NULL;
 
-       while ((opt = getopt(argc, argv, "i:I:e:mnsST:o:awM:K:")) != -1) {
+       while ((opt = getopt(argc, argv, "i:I:e:mnsST:o:awM:K:E")) != -1) {
                switch (opt) {
                case 'i':
                        kernel_read = optarg;
@@ -2415,6 +2429,9 @@ int main(int argc, char **argv)
                case 'w':
                        warn_unresolved = 1;
                        break;
+               case 'E':
+                       sec_mismatch_fatal = 1;
+                       break;
                default:
                        exit(1);
                }
@@ -2464,14 +2481,20 @@ int main(int argc, char **argv)
                sprintf(fname, "%s.mod.c", mod->name);
                write_if_changed(&buf, fname);
        }
-
        if (dump_write)
                write_dump(dump_write);
-       if (sec_mismatch_count && !sec_mismatch_verbose)
-               warn("modpost: Found %d section mismatch(es).\n"
-                    "To see full details build your kernel with:\n"
-                    "'make CONFIG_DEBUG_SECTION_MISMATCH=y'\n",
-                    sec_mismatch_count);
+       if (sec_mismatch_count) {
+               if (!sec_mismatch_verbose) {
+                       warn("modpost: Found %d section mismatch(es).\n"
+                            "To see full details build your kernel with:\n"
+                            "'make CONFIG_DEBUG_SECTION_MISMATCH=y'\n",
+                            sec_mismatch_count);
+               }
+               if (sec_mismatch_fatal) {
+                       fatal("modpost: Section mismatches detected.\n"
+                             "Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n");
+               }
+       }
 
        return err;
 }