diff options
Diffstat (limited to 'scripts/mod/modpost.c')
-rw-r--r-- | scripts/mod/modpost.c | 197 |
1 files changed, 101 insertions, 96 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 4d1c59063b27..696d2a59e4b8 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * Copyright 2003 Kai Germaschewski | 3 | * Copyright 2003 Kai Germaschewski |
4 | * Copyright 2002-2004 Rusty Russell, IBM Corporation | 4 | * Copyright 2002-2004 Rusty Russell, IBM Corporation |
5 | * Copyright 2006 Sam Ravnborg | 5 | * Copyright 2006-2008 Sam Ravnborg |
6 | * Based in part on module-init-tools/depmod.c,file2alias | 6 | * Based in part on module-init-tools/depmod.c,file2alias |
7 | * | 7 | * |
8 | * This software may be used and distributed according to the terms | 8 | * This software may be used and distributed according to the terms |
@@ -74,7 +74,8 @@ static int is_vmlinux(const char *modname) | |||
74 | { | 74 | { |
75 | const char *myname; | 75 | const char *myname; |
76 | 76 | ||
77 | if ((myname = strrchr(modname, '/'))) | 77 | myname = strrchr(modname, '/'); |
78 | if (myname) | ||
78 | myname++; | 79 | myname++; |
79 | else | 80 | else |
80 | myname = modname; | 81 | myname = modname; |
@@ -85,14 +86,13 @@ static int is_vmlinux(const char *modname) | |||
85 | 86 | ||
86 | void *do_nofail(void *ptr, const char *expr) | 87 | void *do_nofail(void *ptr, const char *expr) |
87 | { | 88 | { |
88 | if (!ptr) { | 89 | if (!ptr) |
89 | fatal("modpost: Memory allocation failure: %s.\n", expr); | 90 | fatal("modpost: Memory allocation failure: %s.\n", expr); |
90 | } | 91 | |
91 | return ptr; | 92 | return ptr; |
92 | } | 93 | } |
93 | 94 | ||
94 | /* A list of all modules we processed */ | 95 | /* A list of all modules we processed */ |
95 | |||
96 | static struct module *modules; | 96 | static struct module *modules; |
97 | 97 | ||
98 | static struct module *find_module(char *modname) | 98 | static struct module *find_module(char *modname) |
@@ -115,7 +115,8 @@ static struct module *new_module(char *modname) | |||
115 | p = NOFAIL(strdup(modname)); | 115 | p = NOFAIL(strdup(modname)); |
116 | 116 | ||
117 | /* strip trailing .o */ | 117 | /* strip trailing .o */ |
118 | if ((s = strrchr(p, '.')) != NULL) | 118 | s = strrchr(p, '.'); |
119 | if (s != NULL) | ||
119 | if (strcmp(s, ".o") == 0) | 120 | if (strcmp(s, ".o") == 0) |
120 | *s = '\0'; | 121 | *s = '\0'; |
121 | 122 | ||
@@ -156,7 +157,7 @@ static inline unsigned int tdb_hash(const char *name) | |||
156 | unsigned i; /* Used to cycle through random values. */ | 157 | unsigned i; /* Used to cycle through random values. */ |
157 | 158 | ||
158 | /* Set the initial value from the key size. */ | 159 | /* Set the initial value from the key size. */ |
159 | for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++) | 160 | for (value = 0x238F13AF * strlen(name), i = 0; name[i]; i++) |
160 | value = (value + (((unsigned char *)name)[i] << (i*5 % 24))); | 161 | value = (value + (((unsigned char *)name)[i] << (i*5 % 24))); |
161 | 162 | ||
162 | return (1103515243 * value + 12345); | 163 | return (1103515243 * value + 12345); |
@@ -200,7 +201,7 @@ static struct symbol *find_symbol(const char *name) | |||
200 | if (name[0] == '.') | 201 | if (name[0] == '.') |
201 | name++; | 202 | name++; |
202 | 203 | ||
203 | for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s=s->next) { | 204 | for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s = s->next) { |
204 | if (strcmp(s->name, name) == 0) | 205 | if (strcmp(s->name, name) == 0) |
205 | return s; | 206 | return s; |
206 | } | 207 | } |
@@ -225,9 +226,10 @@ static const char *export_str(enum export ex) | |||
225 | return export_list[ex].str; | 226 | return export_list[ex].str; |
226 | } | 227 | } |
227 | 228 | ||
228 | static enum export export_no(const char * s) | 229 | static enum export export_no(const char *s) |
229 | { | 230 | { |
230 | int i; | 231 | int i; |
232 | |||
231 | if (!s) | 233 | if (!s) |
232 | return export_unknown; | 234 | return export_unknown; |
233 | for (i = 0; export_list[i].export != export_unknown; i++) { | 235 | for (i = 0; export_list[i].export != export_unknown; i++) { |
@@ -317,7 +319,7 @@ void *grab_file(const char *filename, unsigned long *size) | |||
317 | * spaces in the beginning of the line is trimmed away. | 319 | * spaces in the beginning of the line is trimmed away. |
318 | * Return a pointer to a static buffer. | 320 | * Return a pointer to a static buffer. |
319 | **/ | 321 | **/ |
320 | char* get_next_line(unsigned long *pos, void *file, unsigned long size) | 322 | char *get_next_line(unsigned long *pos, void *file, unsigned long size) |
321 | { | 323 | { |
322 | static char line[4096]; | 324 | static char line[4096]; |
323 | int skip = 1; | 325 | int skip = 1; |
@@ -325,8 +327,7 @@ char* get_next_line(unsigned long *pos, void *file, unsigned long size) | |||
325 | signed char *p = (signed char *)file + *pos; | 327 | signed char *p = (signed char *)file + *pos; |
326 | char *s = line; | 328 | char *s = line; |
327 | 329 | ||
328 | for (; *pos < size ; (*pos)++) | 330 | for (; *pos < size ; (*pos)++) { |
329 | { | ||
330 | if (skip && isspace(*p)) { | 331 | if (skip && isspace(*p)) { |
331 | p++; | 332 | p++; |
332 | continue; | 333 | continue; |
@@ -388,7 +389,9 @@ static int parse_elf(struct elf_info *info, const char *filename) | |||
388 | 389 | ||
389 | /* Check if file offset is correct */ | 390 | /* Check if file offset is correct */ |
390 | if (hdr->e_shoff > info->size) { | 391 | if (hdr->e_shoff > info->size) { |
391 | fatal("section header offset=%lu in file '%s' is bigger then filesize=%lu\n", (unsigned long)hdr->e_shoff, filename, info->size); | 392 | fatal("section header offset=%lu in file '%s' is bigger than " |
393 | "filesize=%lu\n", (unsigned long)hdr->e_shoff, | ||
394 | filename, info->size); | ||
392 | return 0; | 395 | return 0; |
393 | } | 396 | } |
394 | 397 | ||
@@ -409,7 +412,10 @@ static int parse_elf(struct elf_info *info, const char *filename) | |||
409 | const char *secname; | 412 | const char *secname; |
410 | 413 | ||
411 | if (sechdrs[i].sh_offset > info->size) { | 414 | if (sechdrs[i].sh_offset > info->size) { |
412 | fatal("%s is truncated. sechdrs[i].sh_offset=%lu > sizeof(*hrd)=%lu\n", filename, (unsigned long)sechdrs[i].sh_offset, sizeof(*hdr)); | 415 | fatal("%s is truncated. sechdrs[i].sh_offset=%lu > " |
416 | "sizeof(*hrd)=%zu\n", filename, | ||
417 | (unsigned long)sechdrs[i].sh_offset, | ||
418 | sizeof(*hdr)); | ||
413 | return 0; | 419 | return 0; |
414 | } | 420 | } |
415 | secname = secstrings + sechdrs[i].sh_name; | 421 | secname = secstrings + sechdrs[i].sh_name; |
@@ -436,9 +442,9 @@ static int parse_elf(struct elf_info *info, const char *filename) | |||
436 | info->strtab = (void *)hdr + | 442 | info->strtab = (void *)hdr + |
437 | sechdrs[sechdrs[i].sh_link].sh_offset; | 443 | sechdrs[sechdrs[i].sh_link].sh_offset; |
438 | } | 444 | } |
439 | if (!info->symtab_start) { | 445 | if (!info->symtab_start) |
440 | fatal("%s has no symtab?\n", filename); | 446 | fatal("%s has no symtab?\n", filename); |
441 | } | 447 | |
442 | /* Fix endianness in symbols */ | 448 | /* Fix endianness in symbols */ |
443 | for (sym = info->symtab_start; sym < info->symtab_stop; sym++) { | 449 | for (sym = info->symtab_start; sym < info->symtab_stop; sym++) { |
444 | sym->st_shndx = TO_NATIVE(sym->st_shndx); | 450 | sym->st_shndx = TO_NATIVE(sym->st_shndx); |
@@ -507,11 +513,13 @@ static void handle_modversions(struct module *mod, struct elf_info *info, | |||
507 | #endif | 513 | #endif |
508 | 514 | ||
509 | if (memcmp(symname, MODULE_SYMBOL_PREFIX, | 515 | if (memcmp(symname, MODULE_SYMBOL_PREFIX, |
510 | strlen(MODULE_SYMBOL_PREFIX)) == 0) | 516 | strlen(MODULE_SYMBOL_PREFIX)) == 0) { |
511 | mod->unres = alloc_symbol(symname + | 517 | mod->unres = |
512 | strlen(MODULE_SYMBOL_PREFIX), | 518 | alloc_symbol(symname + |
513 | ELF_ST_BIND(sym->st_info) == STB_WEAK, | 519 | strlen(MODULE_SYMBOL_PREFIX), |
514 | mod->unres); | 520 | ELF_ST_BIND(sym->st_info) == STB_WEAK, |
521 | mod->unres); | ||
522 | } | ||
515 | break; | 523 | break; |
516 | default: | 524 | default: |
517 | /* All exported symbols */ | 525 | /* All exported symbols */ |
@@ -580,21 +588,21 @@ static char *get_modinfo(void *modinfo, unsigned long modinfo_len, | |||
580 | **/ | 588 | **/ |
581 | static int strrcmp(const char *s, const char *sub) | 589 | static int strrcmp(const char *s, const char *sub) |
582 | { | 590 | { |
583 | int slen, sublen; | 591 | int slen, sublen; |
584 | 592 | ||
585 | if (!s || !sub) | 593 | if (!s || !sub) |
586 | return 1; | 594 | return 1; |
587 | 595 | ||
588 | slen = strlen(s); | 596 | slen = strlen(s); |
589 | sublen = strlen(sub); | 597 | sublen = strlen(sub); |
590 | 598 | ||
591 | if ((slen == 0) || (sublen == 0)) | 599 | if ((slen == 0) || (sublen == 0)) |
592 | return 1; | 600 | return 1; |
593 | 601 | ||
594 | if (sublen > slen) | 602 | if (sublen > slen) |
595 | return 1; | 603 | return 1; |
596 | 604 | ||
597 | return memcmp(s + slen - sublen, sub, sublen); | 605 | return memcmp(s + slen - sublen, sub, sublen); |
598 | } | 606 | } |
599 | 607 | ||
600 | /* | 608 | /* |
@@ -671,7 +679,8 @@ static int data_section(const char *name) | |||
671 | * the pattern is identified by: | 679 | * the pattern is identified by: |
672 | * tosec = init or exit section | 680 | * tosec = init or exit section |
673 | * fromsec = data section | 681 | * fromsec = data section |
674 | * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one, *_console, *_timer | 682 | * atsym = *driver, *_template, *_sht, *_ops, *_probe, |
683 | * *probe_one, *_console, *_timer | ||
675 | * | 684 | * |
676 | * Pattern 3: | 685 | * Pattern 3: |
677 | * Whitelist all refereces from .text.head to .init.data | 686 | * Whitelist all refereces from .text.head to .init.data |
@@ -731,15 +740,16 @@ static int secref_whitelist(const char *modname, const char *tosec, | |||
731 | return 1; | 740 | return 1; |
732 | 741 | ||
733 | /* Check for pattern 2 */ | 742 | /* Check for pattern 2 */ |
734 | if ((init_section(tosec) || exit_section(tosec)) && data_section(fromsec)) | 743 | if ((init_section(tosec) || exit_section(tosec)) |
744 | && data_section(fromsec)) | ||
735 | for (s = pat2sym; *s; s++) | 745 | for (s = pat2sym; *s; s++) |
736 | if (strrcmp(atsym, *s) == 0) | 746 | if (strrcmp(atsym, *s) == 0) |
737 | return 1; | 747 | return 1; |
738 | 748 | ||
739 | /* Check for pattern 3 */ | 749 | /* Check for pattern 3 */ |
740 | if ((strcmp(fromsec, ".text.head") == 0) && | 750 | if ((strcmp(fromsec, ".text.head") == 0) && |
741 | ((strcmp(tosec, ".init.data") == 0) || | 751 | ((strcmp(tosec, ".init.data") == 0) || |
742 | (strcmp(tosec, ".init.text") == 0))) | 752 | (strcmp(tosec, ".init.text") == 0))) |
743 | return 1; | 753 | return 1; |
744 | 754 | ||
745 | /* Check for pattern 4 */ | 755 | /* Check for pattern 4 */ |
@@ -816,7 +826,7 @@ static inline int is_valid_name(struct elf_info *elf, Elf_Sym *sym) | |||
816 | **/ | 826 | **/ |
817 | static void find_symbols_between(struct elf_info *elf, Elf_Addr addr, | 827 | static void find_symbols_between(struct elf_info *elf, Elf_Addr addr, |
818 | const char *sec, | 828 | const char *sec, |
819 | Elf_Sym **before, Elf_Sym **after) | 829 | Elf_Sym **before, Elf_Sym **after) |
820 | { | 830 | { |
821 | Elf_Sym *sym; | 831 | Elf_Sym *sym; |
822 | Elf_Ehdr *hdr = elf->hdr; | 832 | Elf_Ehdr *hdr = elf->hdr; |
@@ -842,20 +852,15 @@ static void find_symbols_between(struct elf_info *elf, Elf_Addr addr, | |||
842 | if ((addr - sym->st_value) < beforediff) { | 852 | if ((addr - sym->st_value) < beforediff) { |
843 | beforediff = addr - sym->st_value; | 853 | beforediff = addr - sym->st_value; |
844 | *before = sym; | 854 | *before = sym; |
845 | } | 855 | } else if ((addr - sym->st_value) == beforediff) { |
846 | else if ((addr - sym->st_value) == beforediff) { | ||
847 | *before = sym; | 856 | *before = sym; |
848 | } | 857 | } |
849 | } | 858 | } else { |
850 | else | ||
851 | { | ||
852 | if ((sym->st_value - addr) < afterdiff) { | 859 | if ((sym->st_value - addr) < afterdiff) { |
853 | afterdiff = sym->st_value - addr; | 860 | afterdiff = sym->st_value - addr; |
854 | *after = sym; | 861 | *after = sym; |
855 | } | 862 | } else if ((sym->st_value - addr) == afterdiff) |
856 | else if ((sym->st_value - addr) == afterdiff) { | ||
857 | *after = sym; | 863 | *after = sym; |
858 | } | ||
859 | } | 864 | } |
860 | } | 865 | } |
861 | } | 866 | } |
@@ -952,12 +957,14 @@ static int addend_arm_rel(struct elf_info *elf, int rsection, Elf_Rela *r) | |||
952 | switch (r_typ) { | 957 | switch (r_typ) { |
953 | case R_ARM_ABS32: | 958 | case R_ARM_ABS32: |
954 | /* From ARM ABI: (S + A) | T */ | 959 | /* From ARM ABI: (S + A) | T */ |
955 | r->r_addend = (int)(long)(elf->symtab_start + ELF_R_SYM(r->r_info)); | 960 | r->r_addend = (int)(long) |
961 | (elf->symtab_start + ELF_R_SYM(r->r_info)); | ||
956 | break; | 962 | break; |
957 | case R_ARM_PC24: | 963 | case R_ARM_PC24: |
958 | /* From ARM ABI: ((S + A) | T) - P */ | 964 | /* From ARM ABI: ((S + A) | T) - P */ |
959 | r->r_addend = (int)(long)(elf->hdr + elf->sechdrs[rsection].sh_offset + | 965 | r->r_addend = (int)(long)(elf->hdr + |
960 | (r->r_offset - elf->sechdrs[rsection].sh_addr)); | 966 | elf->sechdrs[rsection].sh_offset + |
967 | (r->r_offset - elf->sechdrs[rsection].sh_addr)); | ||
961 | break; | 968 | break; |
962 | default: | 969 | default: |
963 | return 1; | 970 | return 1; |
@@ -1002,7 +1009,7 @@ static int addend_mips_rel(struct elf_info *elf, int rsection, Elf_Rela *r) | |||
1002 | **/ | 1009 | **/ |
1003 | static void check_sec_ref(struct module *mod, const char *modname, | 1010 | static void check_sec_ref(struct module *mod, const char *modname, |
1004 | struct elf_info *elf, | 1011 | struct elf_info *elf, |
1005 | int section(const char*), | 1012 | int section(const char *), |
1006 | int section_ref_ok(const char *)) | 1013 | int section_ref_ok(const char *)) |
1007 | { | 1014 | { |
1008 | int i; | 1015 | int i; |
@@ -1022,7 +1029,7 @@ static void check_sec_ref(struct module *mod, const char *modname, | |||
1022 | if (sechdrs[i].sh_type == SHT_RELA) { | 1029 | if (sechdrs[i].sh_type == SHT_RELA) { |
1023 | Elf_Rela *rela; | 1030 | Elf_Rela *rela; |
1024 | Elf_Rela *start = (void *)hdr + sechdrs[i].sh_offset; | 1031 | Elf_Rela *start = (void *)hdr + sechdrs[i].sh_offset; |
1025 | Elf_Rela *stop = (void*)start + sechdrs[i].sh_size; | 1032 | Elf_Rela *stop = (void *)start + sechdrs[i].sh_size; |
1026 | name += strlen(".rela"); | 1033 | name += strlen(".rela"); |
1027 | if (section_ref_ok(name)) | 1034 | if (section_ref_ok(name)) |
1028 | continue; | 1035 | continue; |
@@ -1059,7 +1066,7 @@ static void check_sec_ref(struct module *mod, const char *modname, | |||
1059 | } else if (sechdrs[i].sh_type == SHT_REL) { | 1066 | } else if (sechdrs[i].sh_type == SHT_REL) { |
1060 | Elf_Rel *rel; | 1067 | Elf_Rel *rel; |
1061 | Elf_Rel *start = (void *)hdr + sechdrs[i].sh_offset; | 1068 | Elf_Rel *start = (void *)hdr + sechdrs[i].sh_offset; |
1062 | Elf_Rel *stop = (void*)start + sechdrs[i].sh_size; | 1069 | Elf_Rel *stop = (void *)start + sechdrs[i].sh_size; |
1063 | name += strlen(".rel"); | 1070 | name += strlen(".rel"); |
1064 | if (section_ref_ok(name)) | 1071 | if (section_ref_ok(name)) |
1065 | continue; | 1072 | continue; |
@@ -1088,7 +1095,7 @@ static void check_sec_ref(struct module *mod, const char *modname, | |||
1088 | continue; | 1095 | continue; |
1089 | break; | 1096 | break; |
1090 | case EM_ARM: | 1097 | case EM_ARM: |
1091 | if(addend_arm_rel(elf, i, &r)) | 1098 | if (addend_arm_rel(elf, i, &r)) |
1092 | continue; | 1099 | continue; |
1093 | break; | 1100 | break; |
1094 | case EM_MIPS: | 1101 | case EM_MIPS: |
@@ -1126,32 +1133,32 @@ static int initexit_section_ref_ok(const char *name) | |||
1126 | const char **s; | 1133 | const char **s; |
1127 | /* Absolute section names */ | 1134 | /* Absolute section names */ |
1128 | const char *namelist1[] = { | 1135 | const char *namelist1[] = { |
1129 | "__bug_table", /* used by powerpc for BUG() */ | 1136 | "__bug_table", /* used by powerpc for BUG() */ |
1130 | "__ex_table", | 1137 | "__ex_table", |
1131 | ".altinstructions", | 1138 | ".altinstructions", |
1132 | ".cranges", /* used by sh64 */ | 1139 | ".cranges", /* used by sh64 */ |
1133 | ".fixup", | 1140 | ".fixup", |
1134 | ".machvec", /* ia64 + powerpc uses these */ | 1141 | ".machvec", /* ia64 + powerpc uses these */ |
1135 | ".machine.desc", | 1142 | ".machine.desc", |
1136 | ".opd", /* See comment [OPD] */ | 1143 | ".opd", /* See comment [OPD] */ |
1137 | "__dbe_table", | 1144 | "__dbe_table", |
1138 | ".parainstructions", | 1145 | ".parainstructions", |
1139 | ".pdr", | 1146 | ".pdr", |
1140 | ".plt", /* seen on ARCH=um build on x86_64. Harmless */ | 1147 | ".plt", /* seen on ARCH=um build on x86_64. Harmless */ |
1141 | ".smp_locks", | 1148 | ".smp_locks", |
1142 | ".stab", | 1149 | ".stab", |
1143 | ".m68k_fixup", | 1150 | ".m68k_fixup", |
1144 | ".xt.prop", /* xtensa informational section */ | 1151 | ".xt.prop", /* xtensa informational section */ |
1145 | ".xt.lit", /* xtensa informational section */ | 1152 | ".xt.lit", /* xtensa informational section */ |
1146 | NULL | 1153 | NULL |
1147 | }; | 1154 | }; |
1148 | /* Start of section names */ | 1155 | /* Start of section names */ |
1149 | const char *namelist2[] = { | 1156 | const char *namelist2[] = { |
1150 | ".debug", | 1157 | ".debug", |
1151 | ".eh_frame", | 1158 | ".eh_frame", |
1152 | ".note", /* ignore ELF notes - may contain anything */ | 1159 | ".note", /* ignore ELF notes - may contain anything */ |
1153 | ".got", /* powerpc - global offset table */ | 1160 | ".got", /* powerpc - global offset table */ |
1154 | ".toc", /* powerpc - table of contents */ | 1161 | ".toc", /* powerpc - table of contents */ |
1155 | NULL | 1162 | NULL |
1156 | }; | 1163 | }; |
1157 | /* part of section name */ | 1164 | /* part of section name */ |
@@ -1221,7 +1228,8 @@ static int init_section_ref_ok(const char *name) | |||
1221 | return 1; | 1228 | return 1; |
1222 | 1229 | ||
1223 | /* If section name ends with ".init" we allow references | 1230 | /* If section name ends with ".init" we allow references |
1224 | * as is the case with .initcallN.init, .early_param.init, .taglist.init etc | 1231 | * as is the case with .initcallN.init, .early_param.init, |
1232 | * .taglist.init etc | ||
1225 | */ | 1233 | */ |
1226 | if (strrcmp(name, ".init") == 0) | 1234 | if (strrcmp(name, ".init") == 0) |
1227 | return 1; | 1235 | return 1; |
@@ -1368,7 +1376,7 @@ static void check_for_gpl_usage(enum export exp, const char *m, const char *s) | |||
1368 | } | 1376 | } |
1369 | } | 1377 | } |
1370 | 1378 | ||
1371 | static void check_for_unused(enum export exp, const char* m, const char* s) | 1379 | static void check_for_unused(enum export exp, const char *m, const char *s) |
1372 | { | 1380 | { |
1373 | const char *e = is_vmlinux(m) ?"":".ko"; | 1381 | const char *e = is_vmlinux(m) ?"":".ko"; |
1374 | 1382 | ||
@@ -1401,7 +1409,7 @@ static void check_exports(struct module *mod) | |||
1401 | if (!mod->gpl_compatible) | 1409 | if (!mod->gpl_compatible) |
1402 | check_for_gpl_usage(exp->export, basename, exp->name); | 1410 | check_for_gpl_usage(exp->export, basename, exp->name); |
1403 | check_for_unused(exp->export, basename, exp->name); | 1411 | check_for_unused(exp->export, basename, exp->name); |
1404 | } | 1412 | } |
1405 | } | 1413 | } |
1406 | 1414 | ||
1407 | /** | 1415 | /** |
@@ -1465,9 +1473,8 @@ static int add_versions(struct buffer *b, struct module *mod) | |||
1465 | buf_printf(b, "__attribute__((section(\"__versions\"))) = {\n"); | 1473 | buf_printf(b, "__attribute__((section(\"__versions\"))) = {\n"); |
1466 | 1474 | ||
1467 | for (s = mod->unres; s; s = s->next) { | 1475 | for (s = mod->unres; s; s = s->next) { |
1468 | if (!s->module) { | 1476 | if (!s->module) |
1469 | continue; | 1477 | continue; |
1470 | } | ||
1471 | if (!s->crc_valid) { | 1478 | if (!s->crc_valid) { |
1472 | warn("\"%s\" [%s.ko] has no CRC!\n", | 1479 | warn("\"%s\" [%s.ko] has no CRC!\n", |
1473 | s->name, mod->name); | 1480 | s->name, mod->name); |
@@ -1488,9 +1495,8 @@ static void add_depends(struct buffer *b, struct module *mod, | |||
1488 | struct module *m; | 1495 | struct module *m; |
1489 | int first = 1; | 1496 | int first = 1; |
1490 | 1497 | ||
1491 | for (m = modules; m; m = m->next) { | 1498 | for (m = modules; m; m = m->next) |
1492 | m->seen = is_vmlinux(m->name); | 1499 | m->seen = is_vmlinux(m->name); |
1493 | } | ||
1494 | 1500 | ||
1495 | buf_printf(b, "\n"); | 1501 | buf_printf(b, "\n"); |
1496 | buf_printf(b, "static const char __module_depends[]\n"); | 1502 | buf_printf(b, "static const char __module_depends[]\n"); |
@@ -1506,7 +1512,8 @@ static void add_depends(struct buffer *b, struct module *mod, | |||
1506 | continue; | 1512 | continue; |
1507 | 1513 | ||
1508 | s->module->seen = 1; | 1514 | s->module->seen = 1; |
1509 | if ((p = strrchr(s->module->name, '/')) != NULL) | 1515 | p = strrchr(s->module->name, '/'); |
1516 | if (p) | ||
1510 | p++; | 1517 | p++; |
1511 | else | 1518 | else |
1512 | p = s->module->name; | 1519 | p = s->module->name; |
@@ -1578,7 +1585,7 @@ static void read_dump(const char *fname, unsigned int kernel) | |||
1578 | void *file = grab_file(fname, &size); | 1585 | void *file = grab_file(fname, &size); |
1579 | char *line; | 1586 | char *line; |
1580 | 1587 | ||
1581 | if (!file) | 1588 | if (!file) |
1582 | /* No symbol versions, silently ignore */ | 1589 | /* No symbol versions, silently ignore */ |
1583 | return; | 1590 | return; |
1584 | 1591 | ||
@@ -1601,11 +1608,10 @@ static void read_dump(const char *fname, unsigned int kernel) | |||
1601 | crc = strtoul(line, &d, 16); | 1608 | crc = strtoul(line, &d, 16); |
1602 | if (*symname == '\0' || *modname == '\0' || *d != '\0') | 1609 | if (*symname == '\0' || *modname == '\0' || *d != '\0') |
1603 | goto fail; | 1610 | goto fail; |
1604 | 1611 | mod = find_module(modname); | |
1605 | if (!(mod = find_module(modname))) { | 1612 | if (!mod) { |
1606 | if (is_vmlinux(modname)) { | 1613 | if (is_vmlinux(modname)) |
1607 | have_vmlinux = 1; | 1614 | have_vmlinux = 1; |
1608 | } | ||
1609 | mod = new_module(NOFAIL(strdup(modname))); | 1615 | mod = new_module(NOFAIL(strdup(modname))); |
1610 | mod->skip = 1; | 1616 | mod->skip = 1; |
1611 | } | 1617 | } |
@@ -1662,31 +1668,31 @@ int main(int argc, char **argv) | |||
1662 | int err; | 1668 | int err; |
1663 | 1669 | ||
1664 | while ((opt = getopt(argc, argv, "i:I:mso:aw")) != -1) { | 1670 | while ((opt = getopt(argc, argv, "i:I:mso:aw")) != -1) { |
1665 | switch(opt) { | 1671 | switch (opt) { |
1666 | case 'i': | 1672 | case 'i': |
1667 | kernel_read = optarg; | 1673 | kernel_read = optarg; |
1668 | break; | 1674 | break; |
1669 | case 'I': | 1675 | case 'I': |
1670 | module_read = optarg; | 1676 | module_read = optarg; |
1671 | external_module = 1; | 1677 | external_module = 1; |
1672 | break; | 1678 | break; |
1673 | case 'm': | 1679 | case 'm': |
1674 | modversions = 1; | 1680 | modversions = 1; |
1675 | break; | 1681 | break; |
1676 | case 'o': | 1682 | case 'o': |
1677 | dump_write = optarg; | 1683 | dump_write = optarg; |
1678 | break; | 1684 | break; |
1679 | case 'a': | 1685 | case 'a': |
1680 | all_versions = 1; | 1686 | all_versions = 1; |
1681 | break; | 1687 | break; |
1682 | case 's': | 1688 | case 's': |
1683 | vmlinux_section_warnings = 0; | 1689 | vmlinux_section_warnings = 0; |
1684 | break; | 1690 | break; |
1685 | case 'w': | 1691 | case 'w': |
1686 | warn_unresolved = 1; | 1692 | warn_unresolved = 1; |
1687 | break; | 1693 | break; |
1688 | default: | 1694 | default: |
1689 | exit(1); | 1695 | exit(1); |
1690 | } | 1696 | } |
1691 | } | 1697 | } |
1692 | 1698 | ||
@@ -1695,9 +1701,8 @@ int main(int argc, char **argv) | |||
1695 | if (module_read) | 1701 | if (module_read) |
1696 | read_dump(module_read, 0); | 1702 | read_dump(module_read, 0); |
1697 | 1703 | ||
1698 | while (optind < argc) { | 1704 | while (optind < argc) |
1699 | read_symbols(argv[optind++]); | 1705 | read_symbols(argv[optind++]); |
1700 | } | ||
1701 | 1706 | ||
1702 | for (mod = modules; mod; mod = mod->next) { | 1707 | for (mod = modules; mod; mod = mod->next) { |
1703 | if (mod->skip) | 1708 | if (mod->skip) |