diff options
Diffstat (limited to 'scripts/mod')
| -rw-r--r-- | scripts/mod/mk_elfconfig.c | 6 | ||||
| -rw-r--r-- | scripts/mod/modpost.c | 177 | ||||
| -rw-r--r-- | scripts/mod/modpost.h | 4 |
3 files changed, 165 insertions, 22 deletions
diff --git a/scripts/mod/mk_elfconfig.c b/scripts/mod/mk_elfconfig.c index 3c92c83733f4..725d61c0fb43 100644 --- a/scripts/mod/mk_elfconfig.c +++ b/scripts/mod/mk_elfconfig.c | |||
| @@ -28,7 +28,7 @@ main(int argc, char **argv) | |||
| 28 | printf("#define KERNEL_ELFCLASS ELFCLASS64\n"); | 28 | printf("#define KERNEL_ELFCLASS ELFCLASS64\n"); |
| 29 | break; | 29 | break; |
| 30 | default: | 30 | default: |
| 31 | abort(); | 31 | exit(1); |
| 32 | } | 32 | } |
| 33 | switch (ei[EI_DATA]) { | 33 | switch (ei[EI_DATA]) { |
| 34 | case ELFDATA2LSB: | 34 | case ELFDATA2LSB: |
| @@ -38,7 +38,7 @@ main(int argc, char **argv) | |||
| 38 | printf("#define KERNEL_ELFDATA ELFDATA2MSB\n"); | 38 | printf("#define KERNEL_ELFDATA ELFDATA2MSB\n"); |
| 39 | break; | 39 | break; |
| 40 | default: | 40 | default: |
| 41 | abort(); | 41 | exit(1); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | if (sizeof(unsigned long) == 4) { | 44 | if (sizeof(unsigned long) == 4) { |
| @@ -53,7 +53,7 @@ main(int argc, char **argv) | |||
| 53 | else if (memcmp(endian_test.c, "\x02\x01", 2) == 0) | 53 | else if (memcmp(endian_test.c, "\x02\x01", 2) == 0) |
| 54 | printf("#define HOST_ELFDATA ELFDATA2LSB\n"); | 54 | printf("#define HOST_ELFDATA ELFDATA2LSB\n"); |
| 55 | else | 55 | else |
| 56 | abort(); | 56 | exit(1); |
| 57 | 57 | ||
| 58 | if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0)) | 58 | if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0)) |
| 59 | printf("#define MODULE_SYMBOL_PREFIX \"_\"\n"); | 59 | printf("#define MODULE_SYMBOL_PREFIX \"_\"\n"); |
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index d0f86ed43f7a..0dd16177642d 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | #include <ctype.h> | 14 | #include <ctype.h> |
| 15 | #include "modpost.h" | 15 | #include "modpost.h" |
| 16 | #include "../../include/linux/license.h" | ||
| 16 | 17 | ||
| 17 | /* Are we using CONFIG_MODVERSIONS? */ | 18 | /* Are we using CONFIG_MODVERSIONS? */ |
| 18 | int modversions = 0; | 19 | int modversions = 0; |
| @@ -22,6 +23,8 @@ int have_vmlinux = 0; | |||
| 22 | static int all_versions = 0; | 23 | static int all_versions = 0; |
| 23 | /* If we are modposting external module set to 1 */ | 24 | /* If we are modposting external module set to 1 */ |
| 24 | static int external_module = 0; | 25 | static int external_module = 0; |
| 26 | /* How a symbol is exported */ | ||
| 27 | enum export {export_plain, export_gpl, export_gpl_future, export_unknown}; | ||
| 25 | 28 | ||
| 26 | void fatal(const char *fmt, ...) | 29 | void fatal(const char *fmt, ...) |
| 27 | { | 30 | { |
| @@ -97,6 +100,7 @@ static struct module *new_module(char *modname) | |||
| 97 | 100 | ||
| 98 | /* add to list */ | 101 | /* add to list */ |
| 99 | mod->name = p; | 102 | mod->name = p; |
| 103 | mod->gpl_compatible = -1; | ||
| 100 | mod->next = modules; | 104 | mod->next = modules; |
| 101 | modules = mod; | 105 | modules = mod; |
| 102 | 106 | ||
| @@ -118,6 +122,7 @@ struct symbol { | |||
| 118 | unsigned int kernel:1; /* 1 if symbol is from kernel | 122 | unsigned int kernel:1; /* 1 if symbol is from kernel |
| 119 | * (only for external modules) **/ | 123 | * (only for external modules) **/ |
| 120 | unsigned int preloaded:1; /* 1 if symbol from Module.symvers */ | 124 | unsigned int preloaded:1; /* 1 if symbol from Module.symvers */ |
| 125 | enum export export; /* Type of export */ | ||
| 121 | char name[0]; | 126 | char name[0]; |
| 122 | }; | 127 | }; |
| 123 | 128 | ||
| @@ -153,7 +158,8 @@ static struct symbol *alloc_symbol(const char *name, unsigned int weak, | |||
| 153 | } | 158 | } |
| 154 | 159 | ||
| 155 | /* For the hash of exported symbols */ | 160 | /* For the hash of exported symbols */ |
| 156 | static struct symbol *new_symbol(const char *name, struct module *module) | 161 | static struct symbol *new_symbol(const char *name, struct module *module, |
| 162 | enum export export) | ||
| 157 | { | 163 | { |
| 158 | unsigned int hash; | 164 | unsigned int hash; |
| 159 | struct symbol *new; | 165 | struct symbol *new; |
| @@ -161,6 +167,7 @@ static struct symbol *new_symbol(const char *name, struct module *module) | |||
| 161 | hash = tdb_hash(name) % SYMBOL_HASH_SIZE; | 167 | hash = tdb_hash(name) % SYMBOL_HASH_SIZE; |
| 162 | new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]); | 168 | new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]); |
| 163 | new->module = module; | 169 | new->module = module; |
| 170 | new->export = export; | ||
| 164 | return new; | 171 | return new; |
| 165 | } | 172 | } |
| 166 | 173 | ||
| @@ -179,16 +186,55 @@ static struct symbol *find_symbol(const char *name) | |||
| 179 | return NULL; | 186 | return NULL; |
| 180 | } | 187 | } |
| 181 | 188 | ||
| 189 | static struct { | ||
| 190 | const char *str; | ||
| 191 | enum export export; | ||
| 192 | } export_list[] = { | ||
| 193 | { .str = "EXPORT_SYMBOL", .export = export_plain }, | ||
| 194 | { .str = "EXPORT_SYMBOL_GPL", .export = export_gpl }, | ||
| 195 | { .str = "EXPORT_SYMBOL_GPL_FUTURE", .export = export_gpl_future }, | ||
| 196 | { .str = "(unknown)", .export = export_unknown }, | ||
| 197 | }; | ||
| 198 | |||
| 199 | |||
| 200 | static const char *export_str(enum export ex) | ||
| 201 | { | ||
| 202 | return export_list[ex].str; | ||
| 203 | } | ||
| 204 | |||
| 205 | static enum export export_no(const char * s) | ||
| 206 | { | ||
| 207 | int i; | ||
| 208 | for (i = 0; export_list[i].export != export_unknown; i++) { | ||
| 209 | if (strcmp(export_list[i].str, s) == 0) | ||
| 210 | return export_list[i].export; | ||
| 211 | } | ||
| 212 | return export_unknown; | ||
| 213 | } | ||
| 214 | |||
| 215 | static enum export export_from_sec(struct elf_info *elf, Elf_Section sec) | ||
| 216 | { | ||
| 217 | if (sec == elf->export_sec) | ||
| 218 | return export_plain; | ||
| 219 | else if (sec == elf->export_gpl_sec) | ||
| 220 | return export_gpl; | ||
| 221 | else if (sec == elf->export_gpl_future_sec) | ||
| 222 | return export_gpl_future; | ||
| 223 | else | ||
| 224 | return export_unknown; | ||
| 225 | } | ||
| 226 | |||
| 182 | /** | 227 | /** |
| 183 | * Add an exported symbol - it may have already been added without a | 228 | * Add an exported symbol - it may have already been added without a |
| 184 | * CRC, in this case just update the CRC | 229 | * CRC, in this case just update the CRC |
| 185 | **/ | 230 | **/ |
| 186 | static struct symbol *sym_add_exported(const char *name, struct module *mod) | 231 | static struct symbol *sym_add_exported(const char *name, struct module *mod, |
| 232 | enum export export) | ||
| 187 | { | 233 | { |
| 188 | struct symbol *s = find_symbol(name); | 234 | struct symbol *s = find_symbol(name); |
| 189 | 235 | ||
| 190 | if (!s) { | 236 | if (!s) { |
| 191 | s = new_symbol(name, mod); | 237 | s = new_symbol(name, mod, export); |
| 192 | } else { | 238 | } else { |
| 193 | if (!s->preloaded) { | 239 | if (!s->preloaded) { |
| 194 | warn("%s: '%s' exported twice. Previous export " | 240 | warn("%s: '%s' exported twice. Previous export " |
| @@ -200,16 +246,17 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod) | |||
| 200 | s->preloaded = 0; | 246 | s->preloaded = 0; |
| 201 | s->vmlinux = is_vmlinux(mod->name); | 247 | s->vmlinux = is_vmlinux(mod->name); |
| 202 | s->kernel = 0; | 248 | s->kernel = 0; |
| 249 | s->export = export; | ||
| 203 | return s; | 250 | return s; |
| 204 | } | 251 | } |
| 205 | 252 | ||
| 206 | static void sym_update_crc(const char *name, struct module *mod, | 253 | static void sym_update_crc(const char *name, struct module *mod, |
| 207 | unsigned int crc) | 254 | unsigned int crc, enum export export) |
| 208 | { | 255 | { |
| 209 | struct symbol *s = find_symbol(name); | 256 | struct symbol *s = find_symbol(name); |
| 210 | 257 | ||
| 211 | if (!s) | 258 | if (!s) |
| 212 | s = new_symbol(name, mod); | 259 | s = new_symbol(name, mod, export); |
| 213 | s->crc = crc; | 260 | s->crc = crc; |
| 214 | s->crc_valid = 1; | 261 | s->crc_valid = 1; |
| 215 | } | 262 | } |
| @@ -283,7 +330,7 @@ static void parse_elf(struct elf_info *info, const char *filename) | |||
| 283 | hdr = grab_file(filename, &info->size); | 330 | hdr = grab_file(filename, &info->size); |
| 284 | if (!hdr) { | 331 | if (!hdr) { |
| 285 | perror(filename); | 332 | perror(filename); |
| 286 | abort(); | 333 | exit(1); |
| 287 | } | 334 | } |
| 288 | info->hdr = hdr; | 335 | info->hdr = hdr; |
| 289 | if (info->size < sizeof(*hdr)) | 336 | if (info->size < sizeof(*hdr)) |
| @@ -309,13 +356,21 @@ static void parse_elf(struct elf_info *info, const char *filename) | |||
| 309 | for (i = 1; i < hdr->e_shnum; i++) { | 356 | for (i = 1; i < hdr->e_shnum; i++) { |
| 310 | const char *secstrings | 357 | const char *secstrings |
| 311 | = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; | 358 | = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; |
| 359 | const char *secname; | ||
| 312 | 360 | ||
| 313 | if (sechdrs[i].sh_offset > info->size) | 361 | if (sechdrs[i].sh_offset > info->size) |
| 314 | goto truncated; | 362 | goto truncated; |
| 315 | if (strcmp(secstrings+sechdrs[i].sh_name, ".modinfo") == 0) { | 363 | secname = secstrings + sechdrs[i].sh_name; |
| 364 | if (strcmp(secname, ".modinfo") == 0) { | ||
| 316 | info->modinfo = (void *)hdr + sechdrs[i].sh_offset; | 365 | info->modinfo = (void *)hdr + sechdrs[i].sh_offset; |
| 317 | info->modinfo_len = sechdrs[i].sh_size; | 366 | info->modinfo_len = sechdrs[i].sh_size; |
| 318 | } | 367 | } else if (strcmp(secname, "__ksymtab") == 0) |
| 368 | info->export_sec = i; | ||
| 369 | else if (strcmp(secname, "__ksymtab_gpl") == 0) | ||
| 370 | info->export_gpl_sec = i; | ||
| 371 | else if (strcmp(secname, "__ksymtab_gpl_future") == 0) | ||
| 372 | info->export_gpl_future_sec = i; | ||
| 373 | |||
| 319 | if (sechdrs[i].sh_type != SHT_SYMTAB) | 374 | if (sechdrs[i].sh_type != SHT_SYMTAB) |
| 320 | continue; | 375 | continue; |
| 321 | 376 | ||
| @@ -353,6 +408,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info, | |||
| 353 | Elf_Sym *sym, const char *symname) | 408 | Elf_Sym *sym, const char *symname) |
| 354 | { | 409 | { |
| 355 | unsigned int crc; | 410 | unsigned int crc; |
| 411 | enum export export = export_from_sec(info, sym->st_shndx); | ||
| 356 | 412 | ||
| 357 | switch (sym->st_shndx) { | 413 | switch (sym->st_shndx) { |
| 358 | case SHN_COMMON: | 414 | case SHN_COMMON: |
| @@ -362,7 +418,8 @@ static void handle_modversions(struct module *mod, struct elf_info *info, | |||
| 362 | /* CRC'd symbol */ | 418 | /* CRC'd symbol */ |
| 363 | if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { | 419 | if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { |
| 364 | crc = (unsigned int) sym->st_value; | 420 | crc = (unsigned int) sym->st_value; |
| 365 | sym_update_crc(symname + strlen(CRC_PFX), mod, crc); | 421 | sym_update_crc(symname + strlen(CRC_PFX), mod, crc, |
| 422 | export); | ||
| 366 | } | 423 | } |
| 367 | break; | 424 | break; |
| 368 | case SHN_UNDEF: | 425 | case SHN_UNDEF: |
| @@ -406,7 +463,8 @@ static void handle_modversions(struct module *mod, struct elf_info *info, | |||
| 406 | default: | 463 | default: |
| 407 | /* All exported symbols */ | 464 | /* All exported symbols */ |
| 408 | if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { | 465 | if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { |
| 409 | sym_add_exported(symname + strlen(KSYMTAB_PFX), mod); | 466 | sym_add_exported(symname + strlen(KSYMTAB_PFX), mod, |
| 467 | export); | ||
| 410 | } | 468 | } |
| 411 | if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0) | 469 | if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0) |
| 412 | mod->has_init = 1; | 470 | mod->has_init = 1; |
| @@ -437,13 +495,18 @@ static char *next_string(char *string, unsigned long *secsize) | |||
| 437 | return string; | 495 | return string; |
| 438 | } | 496 | } |
| 439 | 497 | ||
| 440 | static char *get_modinfo(void *modinfo, unsigned long modinfo_len, | 498 | static char *get_next_modinfo(void *modinfo, unsigned long modinfo_len, |
| 441 | const char *tag) | 499 | const char *tag, char *info) |
| 442 | { | 500 | { |
| 443 | char *p; | 501 | char *p; |
| 444 | unsigned int taglen = strlen(tag); | 502 | unsigned int taglen = strlen(tag); |
| 445 | unsigned long size = modinfo_len; | 503 | unsigned long size = modinfo_len; |
| 446 | 504 | ||
| 505 | if (info) { | ||
| 506 | size -= info - (char *)modinfo; | ||
| 507 | modinfo = next_string(info, &size); | ||
| 508 | } | ||
| 509 | |||
| 447 | for (p = modinfo; p; p = next_string(p, &size)) { | 510 | for (p = modinfo; p; p = next_string(p, &size)) { |
| 448 | if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=') | 511 | if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=') |
| 449 | return p + taglen + 1; | 512 | return p + taglen + 1; |
| @@ -451,6 +514,13 @@ static char *get_modinfo(void *modinfo, unsigned long modinfo_len, | |||
| 451 | return NULL; | 514 | return NULL; |
| 452 | } | 515 | } |
| 453 | 516 | ||
| 517 | static char *get_modinfo(void *modinfo, unsigned long modinfo_len, | ||
| 518 | const char *tag) | ||
| 519 | |||
| 520 | { | ||
| 521 | return get_next_modinfo(modinfo, modinfo_len, tag, NULL); | ||
| 522 | } | ||
| 523 | |||
| 454 | /** | 524 | /** |
| 455 | * Test if string s ends in string sub | 525 | * Test if string s ends in string sub |
| 456 | * return 0 if match | 526 | * return 0 if match |
| @@ -821,6 +891,10 @@ static int init_section_ref_ok(const char *name) | |||
| 821 | ".pci_fixup_final", | 891 | ".pci_fixup_final", |
| 822 | ".pdr", | 892 | ".pdr", |
| 823 | "__param", | 893 | "__param", |
| 894 | "__ex_table", | ||
| 895 | ".fixup", | ||
| 896 | ".smp_locks", | ||
| 897 | ".plt", /* seen on ARCH=um build on x86_64. Harmless */ | ||
| 824 | NULL | 898 | NULL |
| 825 | }; | 899 | }; |
| 826 | /* Start of section names */ | 900 | /* Start of section names */ |
| @@ -846,6 +920,8 @@ static int init_section_ref_ok(const char *name) | |||
| 846 | for (s = namelist3; *s; s++) | 920 | for (s = namelist3; *s; s++) |
| 847 | if (strstr(name, *s) != NULL) | 921 | if (strstr(name, *s) != NULL) |
| 848 | return 1; | 922 | return 1; |
| 923 | if (strrcmp(name, ".init") == 0) | ||
| 924 | return 1; | ||
| 849 | return 0; | 925 | return 0; |
| 850 | } | 926 | } |
| 851 | 927 | ||
| @@ -892,6 +968,10 @@ static int exit_section_ref_ok(const char *name) | |||
| 892 | ".exitcall.exit", | 968 | ".exitcall.exit", |
| 893 | ".eh_frame", | 969 | ".eh_frame", |
| 894 | ".stab", | 970 | ".stab", |
| 971 | "__ex_table", | ||
| 972 | ".fixup", | ||
| 973 | ".smp_locks", | ||
| 974 | ".plt", /* seen on ARCH=um build on x86_64. Harmless */ | ||
| 895 | NULL | 975 | NULL |
| 896 | }; | 976 | }; |
| 897 | /* Start of section names */ | 977 | /* Start of section names */ |
| @@ -921,6 +1001,7 @@ static void read_symbols(char *modname) | |||
| 921 | { | 1001 | { |
| 922 | const char *symname; | 1002 | const char *symname; |
| 923 | char *version; | 1003 | char *version; |
| 1004 | char *license; | ||
| 924 | struct module *mod; | 1005 | struct module *mod; |
| 925 | struct elf_info info = { }; | 1006 | struct elf_info info = { }; |
| 926 | Elf_Sym *sym; | 1007 | Elf_Sym *sym; |
| @@ -936,6 +1017,18 @@ static void read_symbols(char *modname) | |||
| 936 | mod->skip = 1; | 1017 | mod->skip = 1; |
| 937 | } | 1018 | } |
| 938 | 1019 | ||
| 1020 | license = get_modinfo(info.modinfo, info.modinfo_len, "license"); | ||
| 1021 | while (license) { | ||
| 1022 | if (license_is_gpl_compatible(license)) | ||
| 1023 | mod->gpl_compatible = 1; | ||
| 1024 | else { | ||
| 1025 | mod->gpl_compatible = 0; | ||
| 1026 | break; | ||
| 1027 | } | ||
| 1028 | license = get_next_modinfo(info.modinfo, info.modinfo_len, | ||
| 1029 | "license", license); | ||
| 1030 | } | ||
| 1031 | |||
| 939 | for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { | 1032 | for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { |
| 940 | symname = info.strtab + sym->st_name; | 1033 | symname = info.strtab + sym->st_name; |
| 941 | 1034 | ||
| @@ -992,6 +1085,41 @@ void buf_write(struct buffer *buf, const char *s, int len) | |||
| 992 | buf->pos += len; | 1085 | buf->pos += len; |
| 993 | } | 1086 | } |
| 994 | 1087 | ||
| 1088 | void check_license(struct module *mod) | ||
| 1089 | { | ||
| 1090 | struct symbol *s, *exp; | ||
| 1091 | |||
| 1092 | for (s = mod->unres; s; s = s->next) { | ||
| 1093 | const char *basename; | ||
| 1094 | if (mod->gpl_compatible == 1) { | ||
| 1095 | /* GPL-compatible modules may use all symbols */ | ||
| 1096 | continue; | ||
| 1097 | } | ||
| 1098 | exp = find_symbol(s->name); | ||
| 1099 | if (!exp || exp->module == mod) | ||
| 1100 | continue; | ||
| 1101 | basename = strrchr(mod->name, '/'); | ||
| 1102 | if (basename) | ||
| 1103 | basename++; | ||
| 1104 | switch (exp->export) { | ||
| 1105 | case export_gpl: | ||
| 1106 | fatal("modpost: GPL-incompatible module %s " | ||
| 1107 | "uses GPL-only symbol '%s'\n", | ||
| 1108 | basename ? basename : mod->name, | ||
| 1109 | exp->name); | ||
| 1110 | break; | ||
| 1111 | case export_gpl_future: | ||
| 1112 | warn("modpost: GPL-incompatible module %s " | ||
| 1113 | "uses future GPL-only symbol '%s'\n", | ||
| 1114 | basename ? basename : mod->name, | ||
| 1115 | exp->name); | ||
| 1116 | break; | ||
| 1117 | case export_plain: /* ignore */ break; | ||
| 1118 | case export_unknown: /* ignore */ break; | ||
| 1119 | } | ||
| 1120 | } | ||
| 1121 | } | ||
| 1122 | |||
| 995 | /** | 1123 | /** |
| 996 | * Header for the generated file | 1124 | * Header for the generated file |
| 997 | **/ | 1125 | **/ |
| @@ -1142,6 +1270,9 @@ static void write_if_changed(struct buffer *b, const char *fname) | |||
| 1142 | fclose(file); | 1270 | fclose(file); |
| 1143 | } | 1271 | } |
| 1144 | 1272 | ||
| 1273 | /* parse Module.symvers file. line format: | ||
| 1274 | * 0x12345678<tab>symbol<tab>module[<tab>export] | ||
| 1275 | **/ | ||
| 1145 | static void read_dump(const char *fname, unsigned int kernel) | 1276 | static void read_dump(const char *fname, unsigned int kernel) |
| 1146 | { | 1277 | { |
| 1147 | unsigned long size, pos = 0; | 1278 | unsigned long size, pos = 0; |
| @@ -1153,7 +1284,7 @@ static void read_dump(const char *fname, unsigned int kernel) | |||
| 1153 | return; | 1284 | return; |
| 1154 | 1285 | ||
| 1155 | while ((line = get_next_line(&pos, file, size))) { | 1286 | while ((line = get_next_line(&pos, file, size))) { |
| 1156 | char *symname, *modname, *d; | 1287 | char *symname, *modname, *d, *export; |
| 1157 | unsigned int crc; | 1288 | unsigned int crc; |
| 1158 | struct module *mod; | 1289 | struct module *mod; |
| 1159 | struct symbol *s; | 1290 | struct symbol *s; |
| @@ -1164,8 +1295,9 @@ static void read_dump(const char *fname, unsigned int kernel) | |||
| 1164 | if (!(modname = strchr(symname, '\t'))) | 1295 | if (!(modname = strchr(symname, '\t'))) |
| 1165 | goto fail; | 1296 | goto fail; |
| 1166 | *modname++ = '\0'; | 1297 | *modname++ = '\0'; |
| 1167 | if (strchr(modname, '\t')) | 1298 | if ((export = strchr(modname, '\t')) != NULL) |
| 1168 | goto fail; | 1299 | *export++ = '\0'; |
| 1300 | |||
| 1169 | crc = strtoul(line, &d, 16); | 1301 | crc = strtoul(line, &d, 16); |
| 1170 | if (*symname == '\0' || *modname == '\0' || *d != '\0') | 1302 | if (*symname == '\0' || *modname == '\0' || *d != '\0') |
| 1171 | goto fail; | 1303 | goto fail; |
| @@ -1177,10 +1309,10 @@ static void read_dump(const char *fname, unsigned int kernel) | |||
| 1177 | mod = new_module(NOFAIL(strdup(modname))); | 1309 | mod = new_module(NOFAIL(strdup(modname))); |
| 1178 | mod->skip = 1; | 1310 | mod->skip = 1; |
| 1179 | } | 1311 | } |
| 1180 | s = sym_add_exported(symname, mod); | 1312 | s = sym_add_exported(symname, mod, export_no(export)); |
| 1181 | s->kernel = kernel; | 1313 | s->kernel = kernel; |
| 1182 | s->preloaded = 1; | 1314 | s->preloaded = 1; |
| 1183 | sym_update_crc(symname, mod, crc); | 1315 | sym_update_crc(symname, mod, crc, export_no(export)); |
| 1184 | } | 1316 | } |
| 1185 | return; | 1317 | return; |
| 1186 | fail: | 1318 | fail: |
| @@ -1210,9 +1342,10 @@ static void write_dump(const char *fname) | |||
| 1210 | symbol = symbolhash[n]; | 1342 | symbol = symbolhash[n]; |
| 1211 | while (symbol) { | 1343 | while (symbol) { |
| 1212 | if (dump_sym(symbol)) | 1344 | if (dump_sym(symbol)) |
| 1213 | buf_printf(&buf, "0x%08x\t%s\t%s\n", | 1345 | buf_printf(&buf, "0x%08x\t%s\t%s\t%s\n", |
| 1214 | symbol->crc, symbol->name, | 1346 | symbol->crc, symbol->name, |
| 1215 | symbol->module->name); | 1347 | symbol->module->name, |
| 1348 | export_str(symbol->export)); | ||
| 1216 | symbol = symbol->next; | 1349 | symbol = symbol->next; |
| 1217 | } | 1350 | } |
| 1218 | } | 1351 | } |
| @@ -1263,6 +1396,12 @@ int main(int argc, char **argv) | |||
| 1263 | for (mod = modules; mod; mod = mod->next) { | 1396 | for (mod = modules; mod; mod = mod->next) { |
| 1264 | if (mod->skip) | 1397 | if (mod->skip) |
| 1265 | continue; | 1398 | continue; |
| 1399 | check_license(mod); | ||
| 1400 | } | ||
| 1401 | |||
| 1402 | for (mod = modules; mod; mod = mod->next) { | ||
| 1403 | if (mod->skip) | ||
| 1404 | continue; | ||
| 1266 | 1405 | ||
| 1267 | buf.pos = 0; | 1406 | buf.pos = 0; |
| 1268 | 1407 | ||
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 861d866fcd83..2b00c6062844 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h | |||
| @@ -100,6 +100,7 @@ buf_write(struct buffer *buf, const char *s, int len); | |||
| 100 | struct module { | 100 | struct module { |
| 101 | struct module *next; | 101 | struct module *next; |
| 102 | const char *name; | 102 | const char *name; |
| 103 | int gpl_compatible; | ||
| 103 | struct symbol *unres; | 104 | struct symbol *unres; |
| 104 | int seen; | 105 | int seen; |
| 105 | int skip; | 106 | int skip; |
| @@ -115,6 +116,9 @@ struct elf_info { | |||
| 115 | Elf_Shdr *sechdrs; | 116 | Elf_Shdr *sechdrs; |
| 116 | Elf_Sym *symtab_start; | 117 | Elf_Sym *symtab_start; |
| 117 | Elf_Sym *symtab_stop; | 118 | Elf_Sym *symtab_stop; |
| 119 | Elf_Section export_sec; | ||
| 120 | Elf_Section export_gpl_sec; | ||
| 121 | Elf_Section export_gpl_future_sec; | ||
| 118 | const char *strtab; | 122 | const char *strtab; |
| 119 | char *modinfo; | 123 | char *modinfo; |
| 120 | unsigned int modinfo_len; | 124 | unsigned int modinfo_len; |
