1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <ctype.h>
15#include "modpost.h"
16#include "../../include/linux/license.h"
17
18
19int modversions = 0;
20
21int have_vmlinux = 0;
22
23static int all_versions = 0;
24
25static int external_module = 0;
26
27static int vmlinux_section_warnings = 1;
28
29static int warn_unresolved = 0;
30
31enum export {
32 export_plain, export_unused, export_gpl,
33 export_unused_gpl, export_gpl_future, export_unknown
34};
35
36void fatal(const char *fmt, ...)
37{
38 va_list arglist;
39
40 fprintf(stderr, "FATAL: ");
41
42 va_start(arglist, fmt);
43 vfprintf(stderr, fmt, arglist);
44 va_end(arglist);
45
46 exit(1);
47}
48
49void warn(const char *fmt, ...)
50{
51 va_list arglist;
52
53 fprintf(stderr, "WARNING: ");
54
55 va_start(arglist, fmt);
56 vfprintf(stderr, fmt, arglist);
57 va_end(arglist);
58}
59
60void merror(const char *fmt, ...)
61{
62 va_list arglist;
63
64 fprintf(stderr, "ERROR: ");
65
66 va_start(arglist, fmt);
67 vfprintf(stderr, fmt, arglist);
68 va_end(arglist);
69}
70
71static int is_vmlinux(const char *modname)
72{
73 const char *myname;
74
75 if ((myname = strrchr(modname, '/')))
76 myname++;
77 else
78 myname = modname;
79
80 return (strcmp(myname, "vmlinux") == 0) ||
81 (strcmp(myname, "vmlinux.o") == 0);
82}
83
84void *do_nofail(void *ptr, const char *expr)
85{
86 if (!ptr) {
87 fatal("modpost: Memory allocation failure: %s.\n", expr);
88 }
89 return ptr;
90}
91
92
93
94static struct module *modules;
95
96static struct module *find_module(char *modname)
97{
98 struct module *mod;
99
100 for (mod = modules; mod; mod = mod->next)
101 if (strcmp(mod->name, modname) == 0)
102 break;
103 return mod;
104}
105
106static struct module *new_module(char *modname)
107{
108 struct module *mod;
109 char *p, *s;
110
111 mod = NOFAIL(malloc(sizeof(*mod)));
112 memset(mod, 0, sizeof(*mod));
113 p = NOFAIL(strdup(modname));
114
115
116 if ((s = strrchr(p, '.')) != NULL)
117 if (strcmp(s, ".o") == 0)
118 *s = '\0';
119
120
121 mod->name = p;
122 mod->gpl_compatible = -1;
123 mod->next = modules;
124 modules = mod;
125
126 return mod;
127}
128
129
130
131
132#define SYMBOL_HASH_SIZE 1024
133
134struct symbol {
135 struct symbol *next;
136 struct module *module;
137 unsigned int crc;
138 int crc_valid;
139 unsigned int weak:1;
140 unsigned int vmlinux:1;
141 unsigned int kernel:1;
142
143 unsigned int preloaded:1;
144 enum export export;
145 char name[0];
146};
147
148static struct symbol *symbolhash[SYMBOL_HASH_SIZE];
149
150
151static inline unsigned int tdb_hash(const char *name)
152{
153 unsigned value;
154 unsigned i;
155
156
157 for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++)
158 value = (value + (((unsigned char *)name)[i] << (i*5 % 24)));
159
160 return (1103515243 * value + 12345);
161}
162
163
164
165
166
167static struct symbol *alloc_symbol(const char *name, unsigned int weak,
168 struct symbol *next)
169{
170 struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1));
171
172 memset(s, 0, sizeof(*s));
173 strcpy(s->name, name);
174 s->weak = weak;
175 s->next = next;
176 return s;
177}
178
179
180static struct symbol *new_symbol(const char *name, struct module *module,
181 enum export export)
182{
183 unsigned int hash;
184 struct symbol *new;
185
186 hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
187 new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]);
188 new->module = module;
189 new->export = export;
190 return new;
191}
192
193static struct symbol *find_symbol(const char *name)
194{
195 struct symbol *s;
196
197
198 if (name[0] == '.')
199 name++;
200
201 for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s=s->next) {
202 if (strcmp(s->name, name) == 0)
203 return s;
204 }
205 return NULL;
206}
207
208static struct {
209 const char *str;
210 enum export export;
211} export_list[] = {
212 { .str = "EXPORT_SYMBOL", .export = export_plain },
213 { .str = "EXPORT_UNUSED_SYMBOL", .export = export_unused },
214 { .str = "EXPORT_SYMBOL_GPL", .export = export_gpl },
215 { .str = "EXPORT_UNUSED_SYMBOL_GPL", .export = export_unused_gpl },
216 { .str = "EXPORT_SYMBOL_GPL_FUTURE", .export = export_gpl_future },
217 { .str = "(unknown)", .export = export_unknown },
218};
219
220
221static const char *export_str(enum export ex)
222{
223 return export_list[ex].str;
224}
225
226static enum export export_no(const char * s)
227{
228 int i;
229 if (!s)
230 return export_unknown;
231 for (i = 0; export_list[i].export != export_unknown; i++) {
232 if (strcmp(export_list[i].str, s) == 0)
233 return export_list[i].export;
234 }
235 return export_unknown;
236}
237
238static enum export export_from_sec(struct elf_info *elf, Elf_Section sec)
239{
240 if (sec == elf->export_sec)
241 return export_plain;
242 else if (sec == elf->export_unused_sec)
243 return export_unused;
244 else if (sec == elf->export_gpl_sec)
245 return export_gpl;
246 else if (sec == elf->export_unused_gpl_sec)
247 return export_unused_gpl;
248 else if (sec == elf->export_gpl_future_sec)
249 return export_gpl_future;
250 else
251 return export_unknown;
252}
253
254
255
256
257
258static struct symbol *sym_add_exported(const char *name, struct module *mod,
259 enum export export)
260{
261 struct symbol *s = find_symbol(name);
262
263 if (!s) {
264 s = new_symbol(name, mod, export);
265 } else {
266 if (!s->preloaded) {
267 warn("%s: '%s' exported twice. Previous export "
268 "was in %s%s\n", mod->name, name,
269 s->module->name,
270 is_vmlinux(s->module->name) ?"":".ko");
271 } else {
272
273 s->module = mod;
274 }
275 }
276 s->preloaded = 0;
277 s->vmlinux = is_vmlinux(mod->name);
278 s->kernel = 0;
279 s->export = export;
280 return s;
281}
282
283static void sym_update_crc(const char *name, struct module *mod,
284 unsigned int crc, enum export export)
285{
286 struct symbol *s = find_symbol(name);
287
288 if (!s)
289 s = new_symbol(name, mod, export);
290 s->crc = crc;
291 s->crc_valid = 1;
292}
293
294void *grab_file(const char *filename, unsigned long *size)
295{
296 struct stat st;
297 void *map;
298 int fd;
299
300 fd = open(filename, O_RDONLY);
301 if (fd < 0 || fstat(fd, &st) != 0)
302 return NULL;
303
304 *size = st.st_size;
305 map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
306 close(fd);
307
308 if (map == MAP_FAILED)
309 return NULL;
310 return map;
311}
312
313
314
315
316
317
318char* get_next_line(unsigned long *pos, void *file, unsigned long size)
319{
320 static char line[4096];
321 int skip = 1;
322 size_t len = 0;
323 signed char *p = (signed char *)file + *pos;
324 char *s = line;
325
326 for (; *pos < size ; (*pos)++)
327 {
328 if (skip && isspace(*p)) {
329 p++;
330 continue;
331 }
332 skip = 0;
333 if (*p != '\n' && (*pos < size)) {
334 len++;
335 *s++ = *p++;
336 if (len > 4095)
337 break;
338 } else {
339
340 *s = '\0';
341 return line;
342 }
343 }
344
345 return NULL;
346}
347
348void release_file(void *file, unsigned long size)
349{
350 munmap(file, size);
351}
352
353static int parse_elf(struct elf_info *info, const char *filename)
354{
355 unsigned int i;
356 Elf_Ehdr *hdr;
357 Elf_Shdr *sechdrs;
358 Elf_Sym *sym;
359
360 hdr = grab_file(filename, &info->size);
361 if (!hdr) {
362 perror(filename);
363 exit(1);
364 }
365 info->hdr = hdr;
366 if (info->size < sizeof(*hdr)) {
367
368 return 0;
369 }
370
371 if ((hdr->e_ident[EI_MAG0] != ELFMAG0) ||
372 (hdr->e_ident[EI_MAG1] != ELFMAG1) ||
373 (hdr->e_ident[EI_MAG2] != ELFMAG2) ||
374 (hdr->e_ident[EI_MAG3] != ELFMAG3)) {
375
376 return 0;
377 }
378
379 hdr->e_shoff = TO_NATIVE(hdr->e_shoff);
380 hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx);
381 hdr->e_shnum = TO_NATIVE(hdr->e_shnum);
382 hdr->e_machine = TO_NATIVE(hdr->e_machine);
383 hdr->e_type = TO_NATIVE(hdr->e_type);
384 sechdrs = (void *)hdr + hdr->e_shoff;
385 info->sechdrs = sechdrs;
386
387
388 if (hdr->e_shoff > info->size) {
389 fatal("section header offset=%u in file '%s' is bigger then filesize=%lu\n", hdr->e_shoff, filename, info->size);
390 return 0;
391 }
392
393
394 for (i = 0; i < hdr->e_shnum; i++) {
395 sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type);
396 sechdrs[i].sh_offset = TO_NATIVE(sechdrs[i].sh_offset);
397 sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size);
398 sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link);
399 sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name);
400 sechdrs[i].sh_info = TO_NATIVE(sechdrs[i].sh_info);
401 sechdrs[i].sh_addr = TO_NATIVE(sechdrs[i].sh_addr);
402 }
403
404 for (i = 1; i < hdr->e_shnum; i++) {
405 const char *secstrings
406 = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
407 const char *secname;
408
409 if (sechdrs[i].sh_offset > info->size) {
410 fatal("%s is truncated. sechdrs[i].sh_offset=%u > sizeof(*hrd)=%ul\n", filename, (unsigned int)sechdrs[i].sh_offset, sizeof(*hdr));
411 return 0;
412 }
413 secname = secstrings + sechdrs[i].sh_name;
414 if (strcmp(secname, ".modinfo") == 0) {
415 info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
416 info->modinfo_len = sechdrs[i].sh_size;
417 } else if (strcmp(secname, "__ksymtab") == 0)
418 info->export_sec = i;
419 else if (strcmp(secname, "__ksymtab_unused") == 0)
420 info->export_unused_sec = i;
421 else if (strcmp(secname, "__ksymtab_gpl") == 0)
422 info->export_gpl_sec = i;
423 else if (strcmp(secname, "__ksymtab_unused_gpl") == 0)
424 info->export_unused_gpl_sec = i;
425 else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
426 info->export_gpl_future_sec = i;
427
428 if (sechdrs[i].sh_type != SHT_SYMTAB)
429 continue;
430
431 info->symtab_start = (void *)hdr + sechdrs[i].sh_offset;
432 info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset
433 + sechdrs[i].sh_size;
434 info->strtab = (void *)hdr +
435 sechdrs[sechdrs[i].sh_link].sh_offset;
436 }
437 if (!info->symtab_start) {
438 fatal("%s has no symtab?\n", filename);
439 }
440
441 for (sym = info->symtab_start; sym < info->symtab_stop; sym++) {
442 sym->st_shndx = TO_NATIVE(sym->st_shndx);
443 sym->st_name = TO_NATIVE(sym->st_name);
444 sym->st_value = TO_NATIVE(sym->st_value);
445 sym->st_size = TO_NATIVE(sym->st_size);
446 }
447 return 1;
448}
449
450static void parse_elf_finish(struct elf_info *info)
451{
452 release_file(info->hdr, info->size);
453}
454
455#define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_"
456#define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_"
457
458static void handle_modversions(struct module *mod, struct elf_info *info,
459 Elf_Sym *sym, const char *symname)
460{
461 unsigned int crc;
462 enum export export = export_from_sec(info, sym->st_shndx);
463
464 switch (sym->st_shndx) {
465 case SHN_COMMON:
466 warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name);
467 break;
468 case SHN_ABS:
469
470 if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
471 crc = (unsigned int) sym->st_value;
472 sym_update_crc(symname + strlen(CRC_PFX), mod, crc,
473 export);
474 }
475 break;
476 case SHN_UNDEF:
477
478 if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL &&
479 ELF_ST_BIND(sym->st_info) != STB_WEAK)
480 break;
481
482 if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0)
483 break;
484
485 if (strcmp(symname, MODULE_SYMBOL_PREFIX "__this_module") == 0)
486 break;
487
488#if defined(STT_REGISTER) || defined(STT_SPARC_REGISTER)
489
490#ifndef STT_SPARC_REGISTER
491#define STT_SPARC_REGISTER STT_REGISTER
492#endif
493 if (info->hdr->e_machine == EM_SPARC ||
494 info->hdr->e_machine == EM_SPARCV9) {
495
496 if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)
497 break;
498 if (symname[0] == '.') {
499 char *munged = strdup(symname);
500 munged[0] = '_';
501 munged[1] = toupper(munged[1]);
502 symname = munged;
503 }
504 }
505#endif
506
507 if (memcmp(symname, MODULE_SYMBOL_PREFIX,
508 strlen(MODULE_SYMBOL_PREFIX)) == 0)
509 mod->unres = alloc_symbol(symname +
510 strlen(MODULE_SYMBOL_PREFIX),
511 ELF_ST_BIND(sym->st_info) == STB_WEAK,
512 mod->unres);
513 break;
514 default:
515
516 if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
517 sym_add_exported(symname + strlen(KSYMTAB_PFX), mod,
518 export);
519 }
520 if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0)
521 mod->has_init = 1;
522 if (strcmp(symname, MODULE_SYMBOL_PREFIX "cleanup_module") == 0)
523 mod->has_cleanup = 1;
524 break;
525 }
526}
527
528
529
530
531static char *next_string(char *string, unsigned long *secsize)
532{
533
534 while (string[0]) {
535 string++;
536 if ((*secsize)-- <= 1)
537 return NULL;
538 }
539
540
541 while (!string[0]) {
542 string++;
543 if ((*secsize)-- <= 1)
544 return NULL;
545 }
546 return string;
547}
548
549static char *get_next_modinfo(void *modinfo, unsigned long modinfo_len,
550 const char *tag, char *info)
551{
552 char *p;
553 unsigned int taglen = strlen(tag);
554 unsigned long size = modinfo_len;
555
556 if (info) {
557 size -= info - (char *)modinfo;
558 modinfo = next_string(info, &size);
559 }
560
561 for (p = modinfo; p; p = next_string(p, &size)) {
562 if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
563 return p + taglen + 1;
564 }
565 return NULL;
566}
567
568static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
569 const char *tag)
570
571{
572 return get_next_modinfo(modinfo, modinfo_len, tag, NULL);
573}
574
575
576
577
578
579static int strrcmp(const char *s, const char *sub)
580{
581 int slen, sublen;
582
583 if (!s || !sub)
584 return 1;
585
586 slen = strlen(s);
587 sublen = strlen(sub);
588
589 if ((slen == 0) || (sublen == 0))
590 return 1;
591
592 if (sublen > slen)
593 return 1;
594
595 return memcmp(s + slen - sublen, sub, sublen);
596}
597
598
599
600
601
602
603
604
605static int init_section(const char *name)
606{
607 if (strcmp(name, ".init") == 0)
608 return 1;
609 if (strncmp(name, ".init.", strlen(".init.")) == 0)
610 return 1;
611 return 0;
612}
613
614
615
616
617
618
619
620
621static int exit_section(const char *name)
622{
623 if (strcmp(name, ".exit.text") == 0)
624 return 1;
625 if (strcmp(name, ".exit.data") == 0)
626 return 1;
627 return 0;
628
629}
630
631
632
633
634
635
636static int data_section(const char *name)
637{
638 if ((strcmp(name, ".data") == 0) ||
639 (strcmp(name, ".data.rel") == 0) ||
640 (strncmp(name, ".data.rel.", strlen(".data.rel.")) == 0))
641 return 1;
642 else
643 return 0;
644}
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694static int secref_whitelist(const char *modname, const char *tosec,
695 const char *fromsec, const char *atsym,
696 const char *refsymname)
697{
698 int len;
699 const char **s;
700 const char *pat2sym[] = {
701 "driver",
702 "_template",
703 "_timer",
704 "_sht",
705 "_ops",
706 "_probe",
707 "_probe_one",
708 "_console",
709 NULL
710 };
711
712 const char *pat3refsym[] = {
713 "__init_begin",
714 "_sinittext",
715 "_einittext",
716 NULL
717 };
718
719
720 if ((strncmp(fromsec, ".text.init.refok", strlen(".text.init.refok")) == 0) ||
721 (strncmp(fromsec, ".exit.text.refok", strlen(".exit.text.refok")) == 0) ||
722 (strncmp(fromsec, ".data.init.refok", strlen(".data.init.refok")) == 0))
723 return 1;
724
725
726 if ((strcmp(tosec, ".init.data") == 0) &&
727 (strncmp(fromsec, ".data", strlen(".data")) == 0) &&
728 (strncmp(atsym, "__param", strlen("__param")) == 0))
729 return 1;
730
731
732 if ((init_section(tosec) || exit_section(tosec)) && data_section(fromsec))
733 for (s = pat2sym; *s; s++)
734 if (strrcmp(atsym, *s) == 0)
735 return 1;
736
737
738 if ((strcmp(fromsec, ".text.head") == 0) &&
739 ((strcmp(tosec, ".init.data") == 0) ||
740 (strcmp(tosec, ".init.text") == 0)))
741 return 1;
742
743
744 for (s = pat3refsym; *s; s++)
745 if (strcmp(refsymname, *s) == 0)
746 return 1;
747
748
749 if (strrcmp(tosec, ".text") == 0)
750 len = strlen(tosec) - strlen(".text");
751 else
752 len = strlen(tosec);
753 if ((strncmp(tosec, fromsec, len) == 0) && (strlen(fromsec) > len) &&
754 (strcmp(fromsec + len, ".literal") == 0))
755 return 1;
756
757 return 0;
758}
759
760
761
762
763
764
765
766
767static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf_Addr addr,
768 Elf_Sym *relsym)
769{
770 Elf_Sym *sym;
771
772 if (relsym->st_name != 0)
773 return relsym;
774 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
775 if (sym->st_shndx != relsym->st_shndx)
776 continue;
777 if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
778 continue;
779 if (sym->st_value == addr)
780 return sym;
781 }
782 return NULL;
783}
784
785static inline int is_arm_mapping_symbol(const char *str)
786{
787 return str[0] == '$' && strchr("atd", str[1])
788 && (str[2] == '\0' || str[2] == '.');
789}
790
791
792
793
794
795
796
797
798
799
800static inline int is_valid_name(struct elf_info *elf, Elf_Sym *sym)
801{
802 const char *name = elf->strtab + sym->st_name;
803
804 if (!name || !strlen(name))
805 return 0;
806 return !is_arm_mapping_symbol(name);
807}
808
809
810
811
812
813
814
815static void find_symbols_between(struct elf_info *elf, Elf_Addr addr,
816 const char *sec,
817 Elf_Sym **before, Elf_Sym **after)
818{
819 Elf_Sym *sym;
820 Elf_Ehdr *hdr = elf->hdr;
821 Elf_Addr beforediff = ~0;
822 Elf_Addr afterdiff = ~0;
823 const char *secstrings = (void *)hdr +
824 elf->sechdrs[hdr->e_shstrndx].sh_offset;
825
826 *before = NULL;
827 *after = NULL;
828
829 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
830 const char *symsec;
831
832 if (sym->st_shndx >= SHN_LORESERVE)
833 continue;
834 symsec = secstrings + elf->sechdrs[sym->st_shndx].sh_name;
835 if (strcmp(symsec, sec) != 0)
836 continue;
837 if (!is_valid_name(elf, sym))
838 continue;
839 if (sym->st_value <= addr) {
840 if ((addr - sym->st_value) < beforediff) {
841 beforediff = addr - sym->st_value;
842 *before = sym;
843 }
844 else if ((addr - sym->st_value) == beforediff) {
845 *before = sym;
846 }
847 }
848 else
849 {
850 if ((sym->st_value - addr) < afterdiff) {
851 afterdiff = sym->st_value - addr;
852 *after = sym;
853 }
854 else if ((sym->st_value - addr) == afterdiff) {
855 *after = sym;
856 }
857 }
858 }
859}
860
861
862
863
864
865
866static void warn_sec_mismatch(const char *modname, const char *fromsec,
867 struct elf_info *elf, Elf_Sym *sym, Elf_Rela r)
868{
869 const char *refsymname = "";
870 Elf_Sym *before, *after;
871 Elf_Sym *refsym;
872 Elf_Ehdr *hdr = elf->hdr;
873 Elf_Shdr *sechdrs = elf->sechdrs;
874 const char *secstrings = (void *)hdr +
875 sechdrs[hdr->e_shstrndx].sh_offset;
876 const char *secname = secstrings + sechdrs[sym->st_shndx].sh_name;
877
878 find_symbols_between(elf, r.r_offset, fromsec, &before, &after);
879
880 refsym = find_elf_symbol(elf, r.r_addend, sym);
881 if (refsym && strlen(elf->strtab + refsym->st_name))
882 refsymname = elf->strtab + refsym->st_name;
883
884
885 if (secref_whitelist(modname, secname, fromsec,
886 before ? elf->strtab + before->st_name : "",
887 refsymname))
888 return;
889
890 if (before && after) {
891 warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s "
892 "(between '%s' and '%s')\n",
893 modname, fromsec, (unsigned long long)r.r_offset,
894 secname, refsymname,
895 elf->strtab + before->st_name,
896 elf->strtab + after->st_name);
897 } else if (before) {
898 warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s "
899 "(after '%s')\n",
900 modname, fromsec, (unsigned long long)r.r_offset,
901 secname, refsymname,
902 elf->strtab + before->st_name);
903 } else if (after) {
904 warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s "
905 "before '%s' (at offset -0x%llx)\n",
906 modname, fromsec, (unsigned long long)r.r_offset,
907 secname, refsymname,
908 elf->strtab + after->st_name);
909 } else {
910 warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s\n",
911 modname, fromsec, (unsigned long long)r.r_offset,
912 secname, refsymname);
913 }
914}
915
916static unsigned int *reloc_location(struct elf_info *elf,
917 int rsection, Elf_Rela *r)
918{
919 Elf_Shdr *sechdrs = elf->sechdrs;
920 int section = sechdrs[rsection].sh_info;
921
922 return (void *)elf->hdr + sechdrs[section].sh_offset +
923 (r->r_offset - sechdrs[section].sh_addr);
924}
925
926static int addend_386_rel(struct elf_info *elf, int rsection, Elf_Rela *r)
927{
928 unsigned int r_typ = ELF_R_TYPE(r->r_info);
929 unsigned int *location = reloc_location(elf, rsection, r);
930
931 switch (r_typ) {
932 case R_386_32:
933 r->r_addend = TO_NATIVE(*location);
934 break;
935 case R_386_PC32:
936 r->r_addend = TO_NATIVE(*location) + 4;
937
938 if (elf->hdr->e_type == ET_EXEC)
939 r->r_addend += r->r_offset;
940 break;
941 }
942 return 0;
943}
944
945static int addend_arm_rel(struct elf_info *elf, int rsection, Elf_Rela *r)
946{
947 unsigned int r_typ = ELF_R_TYPE(r->r_info);
948
949 switch (r_typ) {
950 case R_ARM_ABS32:
951
952 r->r_addend = (int)(long)(elf->symtab_start + ELF_R_SYM(r->r_info));
953 break;
954 case R_ARM_PC24:
955
956 r->r_addend = (int)(long)(elf->hdr + elf->sechdrs[rsection].sh_offset +
957 (r->r_offset - elf->sechdrs[rsection].sh_addr));
958 break;
959 default:
960 return 1;
961 }
962 return 0;
963}
964
965static int addend_mips_rel(struct elf_info *elf, int rsection, Elf_Rela *r)
966{
967 unsigned int r_typ = ELF_R_TYPE(r->r_info);
968 unsigned int *location = reloc_location(elf, rsection, r);
969 unsigned int inst;
970
971 if (r_typ == R_MIPS_HI16)
972 return 1;
973 inst = TO_NATIVE(*location);
974 switch (r_typ) {
975 case R_MIPS_LO16:
976 r->r_addend = inst & 0xffff;
977 break;
978 case R_MIPS_26:
979 r->r_addend = (inst & 0x03ffffff) << 2;
980 break;
981 case R_MIPS_32:
982 r->r_addend = inst;
983 break;
984 }
985 return 0;
986}
987
988
989
990
991
992
993
994
995
996
997
998
999
1000static void check_sec_ref(struct module *mod, const char *modname,
1001 struct elf_info *elf,
1002 int section(const char*),
1003 int section_ref_ok(const char *))
1004{
1005 int i;
1006 Elf_Sym *sym;
1007 Elf_Ehdr *hdr = elf->hdr;
1008 Elf_Shdr *sechdrs = elf->sechdrs;
1009 const char *secstrings = (void *)hdr +
1010 sechdrs[hdr->e_shstrndx].sh_offset;
1011
1012
1013 for (i = 0; i < hdr->e_shnum; i++) {
1014 const char *name = secstrings + sechdrs[i].sh_name;
1015 const char *secname;
1016 Elf_Rela r;
1017 unsigned int r_sym;
1018
1019 if (sechdrs[i].sh_type == SHT_RELA) {
1020 Elf_Rela *rela;
1021 Elf_Rela *start = (void *)hdr + sechdrs[i].sh_offset;
1022 Elf_Rela *stop = (void*)start + sechdrs[i].sh_size;
1023 name += strlen(".rela");
1024 if (section_ref_ok(name))
1025 continue;
1026
1027 for (rela = start; rela < stop; rela++) {
1028 r.r_offset = TO_NATIVE(rela->r_offset);
1029#if KERNEL_ELFCLASS == ELFCLASS64
1030 if (hdr->e_machine == EM_MIPS) {
1031 unsigned int r_typ;
1032 r_sym = ELF64_MIPS_R_SYM(rela->r_info);
1033 r_sym = TO_NATIVE(r_sym);
1034 r_typ = ELF64_MIPS_R_TYPE(rela->r_info);
1035 r.r_info = ELF64_R_INFO(r_sym, r_typ);
1036 } else {
1037 r.r_info = TO_NATIVE(rela->r_info);
1038 r_sym = ELF_R_SYM(r.r_info);
1039 }
1040#else
1041 r.r_info = TO_NATIVE(rela->r_info);
1042 r_sym = ELF_R_SYM(r.r_info);
1043#endif
1044 r.r_addend = TO_NATIVE(rela->r_addend);
1045 sym = elf->symtab_start + r_sym;
1046
1047 if (sym->st_shndx >= SHN_LORESERVE)
1048 continue;
1049
1050 secname = secstrings +
1051 sechdrs[sym->st_shndx].sh_name;
1052 if (section(secname))
1053 warn_sec_mismatch(modname, name,
1054 elf, sym, r);
1055 }
1056 } else if (sechdrs[i].sh_type == SHT_REL) {
1057 Elf_Rel *rel;
1058 Elf_Rel *start = (void *)hdr + sechdrs[i].sh_offset;
1059 Elf_Rel *stop = (void*)start + sechdrs[i].sh_size;
1060 name += strlen(".rel");
1061 if (section_ref_ok(name))
1062 continue;
1063
1064 for (rel = start; rel < stop; rel++) {
1065 r.r_offset = TO_NATIVE(rel->r_offset);
1066#if KERNEL_ELFCLASS == ELFCLASS64
1067 if (hdr->e_machine == EM_MIPS) {
1068 unsigned int r_typ;
1069 r_sym = ELF64_MIPS_R_SYM(rel->r_info);
1070 r_sym = TO_NATIVE(r_sym);
1071 r_typ = ELF64_MIPS_R_TYPE(rel->r_info);
1072 r.r_info = ELF64_R_INFO(r_sym, r_typ);
1073 } else {
1074 r.r_info = TO_NATIVE(rel->r_info);
1075 r_sym = ELF_R_SYM(r.r_info);
1076 }
1077#else
1078 r.r_info = TO_NATIVE(rel->r_info);
1079 r_sym = ELF_R_SYM(r.r_info);
1080#endif
1081 r.r_addend = 0;
1082 switch (hdr->e_machine) {
1083 case EM_386:
1084 if (addend_386_rel(elf, i, &r))
1085 continue;
1086 break;
1087 case EM_ARM:
1088 if(addend_arm_rel(elf, i, &r))
1089 continue;
1090 break;
1091 case EM_MIPS:
1092 if (addend_mips_rel(elf, i, &r))
1093 continue;
1094 break;
1095 }
1096 sym = elf->symtab_start + r_sym;
1097
1098 if (sym->st_shndx >= SHN_LORESERVE)
1099 continue;
1100
1101 secname = secstrings +
1102 sechdrs[sym->st_shndx].sh_name;
1103 if (section(secname))
1104 warn_sec_mismatch(modname, name,
1105 elf, sym, r);
1106 }
1107 }
1108 }
1109}
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121static int initexit_section_ref_ok(const char *name)
1122{
1123 const char **s;
1124
1125 const char *namelist1[] = {
1126 "__bug_table",
1127 "__ex_table",
1128 ".altinstructions",
1129 ".cranges",
1130 ".fixup",
1131 ".machvec",
1132 ".machine.desc",
1133 ".opd",
1134 "__dbe_table",
1135 ".parainstructions",
1136 ".pdr",
1137 ".plt",
1138 ".smp_locks",
1139 ".stab",
1140 ".m68k_fixup",
1141 ".xt.prop",
1142 ".xt.lit",
1143 NULL
1144 };
1145
1146 const char *namelist2[] = {
1147 ".debug",
1148 ".eh_frame",
1149 ".note",
1150 ".got",
1151 ".toc",
1152 NULL
1153 };
1154
1155 const char *namelist3 [] = {
1156 ".unwind",
1157 NULL
1158 };
1159
1160 for (s = namelist1; *s; s++)
1161 if (strcmp(*s, name) == 0)
1162 return 1;
1163 for (s = namelist2; *s; s++)
1164 if (strncmp(*s, name, strlen(*s)) == 0)
1165 return 1;
1166 for (s = namelist3; *s; s++)
1167 if (strstr(name, *s) != NULL)
1168 return 1;
1169 return 0;
1170}
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188static int init_section_ref_ok(const char *name)
1189{
1190 const char **s;
1191
1192 const char *namelist1[] = {
1193 "__dbe_table",
1194 "__ftr_fixup",
1195 "__fw_ftr_fixup",
1196 "__param",
1197 ".data.rel.ro",
1198 ".init",
1199 ".text.lock",
1200 NULL
1201 };
1202
1203 const char *namelist2[] = {
1204 ".init.",
1205 ".pci_fixup",
1206 ".rodata",
1207 NULL
1208 };
1209
1210 if (initexit_section_ref_ok(name))
1211 return 1;
1212
1213 for (s = namelist1; *s; s++)
1214 if (strcmp(*s, name) == 0)
1215 return 1;
1216 for (s = namelist2; *s; s++)
1217 if (strncmp(*s, name, strlen(*s)) == 0)
1218 return 1;
1219
1220
1221
1222
1223 if (strrcmp(name, ".init") == 0)
1224 return 1;
1225 return 0;
1226}
1227
1228
1229
1230
1231static int exit_section_ref_ok(const char *name)
1232{
1233 const char **s;
1234
1235 const char *namelist1[] = {
1236 ".exit.data",
1237 ".exit.text",
1238 ".exitcall.exit",
1239 ".rodata",
1240 NULL
1241 };
1242
1243 if (initexit_section_ref_ok(name))
1244 return 1;
1245
1246 for (s = namelist1; *s; s++)
1247 if (strcmp(*s, name) == 0)
1248 return 1;
1249 return 0;
1250}
1251
1252static void read_symbols(char *modname)
1253{
1254 const char *symname;
1255 char *version;
1256 char *license;
1257 struct module *mod;
1258 struct elf_info info = { };
1259 Elf_Sym *sym;
1260
1261 if (!parse_elf(&info, modname))
1262 return;
1263
1264 mod = new_module(modname);
1265
1266
1267
1268 if (is_vmlinux(modname)) {
1269 have_vmlinux = 1;
1270 mod->skip = 1;
1271 }
1272
1273 license = get_modinfo(info.modinfo, info.modinfo_len, "license");
1274 while (license) {
1275 if (license_is_gpl_compatible(license))
1276 mod->gpl_compatible = 1;
1277 else {
1278 mod->gpl_compatible = 0;
1279 break;
1280 }
1281 license = get_next_modinfo(info.modinfo, info.modinfo_len,
1282 "license", license);
1283 }
1284
1285 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
1286 symname = info.strtab + sym->st_name;
1287
1288 handle_modversions(mod, &info, sym, symname);
1289 handle_moddevtable(mod, &info, sym, symname);
1290 }
1291 if (is_vmlinux(modname) && vmlinux_section_warnings) {
1292 check_sec_ref(mod, modname, &info, init_section, init_section_ref_ok);
1293 check_sec_ref(mod, modname, &info, exit_section, exit_section_ref_ok);
1294 }
1295
1296 version = get_modinfo(info.modinfo, info.modinfo_len, "version");
1297 if (version)
1298 maybe_frob_rcs_version(modname, version, info.modinfo,
1299 version - (char *)info.hdr);
1300 if (version || (all_versions && !is_vmlinux(modname)))
1301 get_src_version(modname, mod->srcversion,
1302 sizeof(mod->srcversion)-1);
1303
1304 parse_elf_finish(&info);
1305
1306
1307
1308
1309
1310 if (modversions)
1311 mod->unres = alloc_symbol("struct_module", 0, mod->unres);
1312}
1313
1314#define SZ 500
1315
1316
1317
1318
1319
1320void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf,
1321 const char *fmt, ...)
1322{
1323 char tmp[SZ];
1324 int len;
1325 va_list ap;
1326
1327 va_start(ap, fmt);
1328 len = vsnprintf(tmp, SZ, fmt, ap);
1329 buf_write(buf, tmp, len);
1330 va_end(ap);
1331}
1332
1333void buf_write(struct buffer *buf, const char *s, int len)
1334{
1335 if (buf->size - buf->pos < len) {
1336 buf->size += len + SZ;
1337 buf->p = realloc(buf->p, buf->size);
1338 }
1339 strncpy(buf->p + buf->pos, s, len);
1340 buf->pos += len;
1341}
1342
1343static void check_for_gpl_usage(enum export exp, const char *m, const char *s)
1344{
1345 const char *e = is_vmlinux(m) ?"":".ko";
1346
1347 switch (exp) {
1348 case export_gpl:
1349 fatal("modpost: GPL-incompatible module %s%s "
1350 "uses GPL-only symbol '%s'\n", m, e, s);
1351 break;
1352 case export_unused_gpl:
1353 fatal("modpost: GPL-incompatible module %s%s "
1354 "uses GPL-only symbol marked UNUSED '%s'\n", m, e, s);
1355 break;
1356 case export_gpl_future:
1357 warn("modpost: GPL-incompatible module %s%s "
1358 "uses future GPL-only symbol '%s'\n", m, e, s);
1359 break;
1360 case export_plain:
1361 case export_unused:
1362 case export_unknown:
1363
1364 break;
1365 }
1366}
1367
1368static void check_for_unused(enum export exp, const char* m, const char* s)
1369{
1370 const char *e = is_vmlinux(m) ?"":".ko";
1371
1372 switch (exp) {
1373 case export_unused:
1374 case export_unused_gpl:
1375 warn("modpost: module %s%s "
1376 "uses symbol '%s' marked UNUSED\n", m, e, s);
1377 break;
1378 default:
1379
1380 break;
1381 }
1382}
1383
1384static void check_exports(struct module *mod)
1385{
1386 struct symbol *s, *exp;
1387
1388 for (s = mod->unres; s; s = s->next) {
1389 const char *basename;
1390 exp = find_symbol(s->name);
1391 if (!exp || exp->module == mod)
1392 continue;
1393 basename = strrchr(mod->name, '/');
1394 if (basename)
1395 basename++;
1396 else
1397 basename = mod->name;
1398 if (!mod->gpl_compatible)
1399 check_for_gpl_usage(exp->export, basename, exp->name);
1400 check_for_unused(exp->export, basename, exp->name);
1401 }
1402}
1403
1404
1405
1406
1407static void add_header(struct buffer *b, struct module *mod)
1408{
1409 buf_printf(b, "#include <linux/module.h>\n");
1410 buf_printf(b, "#include <linux/vermagic.h>\n");
1411 buf_printf(b, "#include <linux/compiler.h>\n");
1412 buf_printf(b, "\n");
1413 buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
1414 buf_printf(b, "\n");
1415 buf_printf(b, "struct module __this_module\n");
1416 buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");
1417 buf_printf(b, " .name = KBUILD_MODNAME,\n");
1418 if (mod->has_init)
1419 buf_printf(b, " .init = init_module,\n");
1420 if (mod->has_cleanup)
1421 buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n"
1422 " .exit = cleanup_module,\n"
1423 "#endif\n");
1424 buf_printf(b, " .arch = MODULE_ARCH_INIT,\n");
1425 buf_printf(b, "};\n");
1426}
1427
1428
1429
1430
1431static int add_versions(struct buffer *b, struct module *mod)
1432{
1433 struct symbol *s, *exp;
1434 int err = 0;
1435
1436 for (s = mod->unres; s; s = s->next) {
1437 exp = find_symbol(s->name);
1438 if (!exp || exp->module == mod) {
1439 if (have_vmlinux && !s->weak) {
1440 if (warn_unresolved) {
1441 warn("\"%s\" [%s.ko] undefined!\n",
1442 s->name, mod->name);
1443 } else {
1444 merror("\"%s\" [%s.ko] undefined!\n",
1445 s->name, mod->name);
1446 err = 1;
1447 }
1448 }
1449 continue;
1450 }
1451 s->module = exp->module;
1452 s->crc_valid = exp->crc_valid;
1453 s->crc = exp->crc;
1454 }
1455
1456 if (!modversions)
1457 return err;
1458
1459 buf_printf(b, "\n");
1460 buf_printf(b, "static const struct modversion_info ____versions[]\n");
1461 buf_printf(b, "__attribute_used__\n");
1462 buf_printf(b, "__attribute__((section(\"__versions\"))) = {\n");
1463
1464 for (s = mod->unres; s; s = s->next) {
1465 if (!s->module) {
1466 continue;
1467 }
1468 if (!s->crc_valid) {
1469 warn("\"%s\" [%s.ko] has no CRC!\n",
1470 s->name, mod->name);
1471 continue;
1472 }
1473 buf_printf(b, "\t{ %#8x, \"%s\" },\n", s->crc, s->name);
1474 }
1475
1476 buf_printf(b, "};\n");
1477
1478 return err;
1479}
1480
1481static void add_depends(struct buffer *b, struct module *mod,
1482 struct module *modules)
1483{
1484 struct symbol *s;
1485 struct module *m;
1486 int first = 1;
1487
1488 for (m = modules; m; m = m->next) {
1489 m->seen = is_vmlinux(m->name);
1490 }
1491
1492 buf_printf(b, "\n");
1493 buf_printf(b, "static const char __module_depends[]\n");
1494 buf_printf(b, "__attribute_used__\n");
1495 buf_printf(b, "__attribute__((section(\".modinfo\"))) =\n");
1496 buf_printf(b, "\"depends=");
1497 for (s = mod->unres; s; s = s->next) {
1498 const char *p;
1499 if (!s->module)
1500 continue;
1501
1502 if (s->module->seen)
1503 continue;
1504
1505 s->module->seen = 1;
1506 if ((p = strrchr(s->module->name, '/')) != NULL)
1507 p++;
1508 else
1509 p = s->module->name;
1510 buf_printf(b, "%s%s", first ? "" : ",", p);
1511 first = 0;
1512 }
1513 buf_printf(b, "\";\n");
1514}
1515
1516static void add_srcversion(struct buffer *b, struct module *mod)
1517{
1518 if (mod->srcversion[0]) {
1519 buf_printf(b, "\n");
1520 buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n",
1521 mod->srcversion);
1522 }
1523}
1524
1525static void write_if_changed(struct buffer *b, const char *fname)
1526{
1527 char *tmp;
1528 FILE *file;
1529 struct stat st;
1530
1531 file = fopen(fname, "r");
1532 if (!file)
1533 goto write;
1534
1535 if (fstat(fileno(file), &st) < 0)
1536 goto close_write;
1537
1538 if (st.st_size != b->pos)
1539 goto close_write;
1540
1541 tmp = NOFAIL(malloc(b->pos));
1542 if (fread(tmp, 1, b->pos, file) != b->pos)
1543 goto free_write;
1544
1545 if (memcmp(tmp, b->p, b->pos) != 0)
1546 goto free_write;
1547
1548 free(tmp);
1549 fclose(file);
1550 return;
1551
1552 free_write:
1553 free(tmp);
1554 close_write:
1555 fclose(file);
1556 write:
1557 file = fopen(fname, "w");
1558 if (!file) {
1559 perror(fname);
1560 exit(1);
1561 }
1562 if (fwrite(b->p, 1, b->pos, file) != b->pos) {
1563 perror(fname);
1564 exit(1);
1565 }
1566 fclose(file);
1567}
1568
1569
1570
1571
1572static void read_dump(const char *fname, unsigned int kernel)
1573{
1574 unsigned long size, pos = 0;
1575 void *file = grab_file(fname, &size);
1576 char *line;
1577
1578 if (!file)
1579
1580 return;
1581
1582 while ((line = get_next_line(&pos, file, size))) {
1583 char *symname, *modname, *d, *export, *end;
1584 unsigned int crc;
1585 struct module *mod;
1586 struct symbol *s;
1587
1588 if (!(symname = strchr(line, '\t')))
1589 goto fail;
1590 *symname++ = '\0';
1591 if (!(modname = strchr(symname, '\t')))
1592 goto fail;
1593 *modname++ = '\0';
1594 if ((export = strchr(modname, '\t')) != NULL)
1595 *export++ = '\0';
1596 if (export && ((end = strchr(export, '\t')) != NULL))
1597 *end = '\0';
1598 crc = strtoul(line, &d, 16);
1599 if (*symname == '\0' || *modname == '\0' || *d != '\0')
1600 goto fail;
1601
1602 if (!(mod = find_module(modname))) {
1603 if (is_vmlinux(modname)) {
1604 have_vmlinux = 1;
1605 }
1606 mod = new_module(NOFAIL(strdup(modname)));
1607 mod->skip = 1;
1608 }
1609 s = sym_add_exported(symname, mod, export_no(export));
1610 s->kernel = kernel;
1611 s->preloaded = 1;
1612 sym_update_crc(symname, mod, crc, export_no(export));
1613 }
1614 return;
1615fail:
1616 fatal("parse error in symbol dump file\n");
1617}
1618
1619
1620
1621
1622
1623static int dump_sym(struct symbol *sym)
1624{
1625 if (!external_module)
1626 return 1;
1627 if (sym->vmlinux || sym->kernel)
1628 return 0;
1629 return 1;
1630}
1631
1632static void write_dump(const char *fname)
1633{
1634 struct buffer buf = { };
1635 struct symbol *symbol;
1636 int n;
1637
1638 for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
1639 symbol = symbolhash[n];
1640 while (symbol) {
1641 if (dump_sym(symbol))
1642 buf_printf(&buf, "0x%08x\t%s\t%s\t%s\n",
1643 symbol->crc, symbol->name,
1644 symbol->module->name,
1645 export_str(symbol->export));
1646 symbol = symbol->next;
1647 }
1648 }
1649 write_if_changed(&buf, fname);
1650}
1651
1652int main(int argc, char **argv)
1653{
1654 struct module *mod;
1655 struct buffer buf = { };
1656 char fname[SZ];
1657 char *kernel_read = NULL, *module_read = NULL;
1658 char *dump_write = NULL;
1659 int opt;
1660 int err;
1661
1662 while ((opt = getopt(argc, argv, "i:I:mso:aw")) != -1) {
1663 switch(opt) {
1664 case 'i':
1665 kernel_read = optarg;
1666 break;
1667 case 'I':
1668 module_read = optarg;
1669 external_module = 1;
1670 break;
1671 case 'm':
1672 modversions = 1;
1673 break;
1674 case 'o':
1675 dump_write = optarg;
1676 break;
1677 case 'a':
1678 all_versions = 1;
1679 break;
1680 case 's':
1681 vmlinux_section_warnings = 0;
1682 break;
1683 case 'w':
1684 warn_unresolved = 1;
1685 break;
1686 default:
1687 exit(1);
1688 }
1689 }
1690
1691 if (kernel_read)
1692 read_dump(kernel_read, 1);
1693 if (module_read)
1694 read_dump(module_read, 0);
1695
1696 while (optind < argc) {
1697 read_symbols(argv[optind++]);
1698 }
1699
1700 for (mod = modules; mod; mod = mod->next) {
1701 if (mod->skip)
1702 continue;
1703 check_exports(mod);
1704 }
1705
1706 err = 0;
1707
1708 for (mod = modules; mod; mod = mod->next) {
1709 if (mod->skip)
1710 continue;
1711
1712 buf.pos = 0;
1713
1714 add_header(&buf, mod);
1715 err |= add_versions(&buf, mod);
1716 add_depends(&buf, mod, modules);
1717 add_moddevtable(&buf, mod);
1718 add_srcversion(&buf, mod);
1719
1720 sprintf(fname, "%s.mod.c", mod->name);
1721 write_if_changed(&buf, fname);
1722 }
1723
1724 if (dump_write)
1725 write_dump(dump_write);
1726
1727 return err;
1728}
1729