1
2
3
4
5
6
7
8
9
10
11
12
13
14#define _GNU_SOURCE
15#include <stdio.h>
16#include <ctype.h>
17#include <string.h>
18#include <limits.h>
19#include <stdbool.h>
20#include "modpost.h"
21#include "../../include/generated/autoconf.h"
22#include "../../include/linux/license.h"
23#include "../../include/linux/export.h"
24
25
26int modversions = 0;
27
28int have_vmlinux = 0;
29
30static int all_versions = 0;
31
32static int external_module = 0;
33
34static int vmlinux_section_warnings = 1;
35
36static int warn_unresolved = 0;
37
38static int sec_mismatch_count = 0;
39static int sec_mismatch_verbose = 1;
40
41enum export {
42 export_plain, export_unused, export_gpl,
43 export_unused_gpl, export_gpl_future, export_unknown
44};
45
46#define PRINTF __attribute__ ((format (printf, 1, 2)))
47
48PRINTF void fatal(const char *fmt, ...)
49{
50 va_list arglist;
51
52 fprintf(stderr, "FATAL: ");
53
54 va_start(arglist, fmt);
55 vfprintf(stderr, fmt, arglist);
56 va_end(arglist);
57
58 exit(1);
59}
60
61PRINTF void warn(const char *fmt, ...)
62{
63 va_list arglist;
64
65 fprintf(stderr, "WARNING: ");
66
67 va_start(arglist, fmt);
68 vfprintf(stderr, fmt, arglist);
69 va_end(arglist);
70}
71
72PRINTF void merror(const char *fmt, ...)
73{
74 va_list arglist;
75
76 fprintf(stderr, "ERROR: ");
77
78 va_start(arglist, fmt);
79 vfprintf(stderr, fmt, arglist);
80 va_end(arglist);
81}
82
83static inline bool strends(const char *str, const char *postfix)
84{
85 if (strlen(str) < strlen(postfix))
86 return false;
87
88 return strcmp(str + strlen(str) - strlen(postfix), postfix) == 0;
89}
90
91static int is_vmlinux(const char *modname)
92{
93 const char *myname;
94
95 myname = strrchr(modname, '/');
96 if (myname)
97 myname++;
98 else
99 myname = modname;
100
101 return (strcmp(myname, "vmlinux") == 0) ||
102 (strcmp(myname, "vmlinux.o") == 0);
103}
104
105void *do_nofail(void *ptr, const char *expr)
106{
107 if (!ptr)
108 fatal("modpost: Memory allocation failure: %s.\n", expr);
109
110 return ptr;
111}
112
113
114static struct module *modules;
115
116static struct module *find_module(char *modname)
117{
118 struct module *mod;
119
120 for (mod = modules; mod; mod = mod->next)
121 if (strcmp(mod->name, modname) == 0)
122 break;
123 return mod;
124}
125
126static struct module *new_module(const char *modname)
127{
128 struct module *mod;
129 char *p;
130
131 mod = NOFAIL(malloc(sizeof(*mod)));
132 memset(mod, 0, sizeof(*mod));
133 p = NOFAIL(strdup(modname));
134
135
136 if (strends(p, ".o")) {
137 p[strlen(p) - 2] = '\0';
138 mod->is_dot_o = 1;
139 }
140
141
142 mod->name = p;
143 mod->gpl_compatible = -1;
144 mod->next = modules;
145 modules = mod;
146
147 return mod;
148}
149
150
151
152
153#define SYMBOL_HASH_SIZE 1024
154
155struct symbol {
156 struct symbol *next;
157 struct module *module;
158 unsigned int crc;
159 int crc_valid;
160 unsigned int weak:1;
161 unsigned int vmlinux:1;
162 unsigned int kernel:1;
163
164 unsigned int preloaded:1;
165 enum export export;
166 char name[0];
167};
168
169static struct symbol *symbolhash[SYMBOL_HASH_SIZE];
170
171
172static inline unsigned int tdb_hash(const char *name)
173{
174 unsigned value;
175 unsigned i;
176
177
178 for (value = 0x238F13AF * strlen(name), i = 0; name[i]; i++)
179 value = (value + (((unsigned char *)name)[i] << (i*5 % 24)));
180
181 return (1103515243 * value + 12345);
182}
183
184
185
186
187
188static struct symbol *alloc_symbol(const char *name, unsigned int weak,
189 struct symbol *next)
190{
191 struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1));
192
193 memset(s, 0, sizeof(*s));
194 strcpy(s->name, name);
195 s->weak = weak;
196 s->next = next;
197 return s;
198}
199
200
201static struct symbol *new_symbol(const char *name, struct module *module,
202 enum export export)
203{
204 unsigned int hash;
205 struct symbol *new;
206
207 hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
208 new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]);
209 new->module = module;
210 new->export = export;
211 return new;
212}
213
214static struct symbol *find_symbol(const char *name)
215{
216 struct symbol *s;
217
218
219 if (name[0] == '.')
220 name++;
221
222 for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s = s->next) {
223 if (strcmp(s->name, name) == 0)
224 return s;
225 }
226 return NULL;
227}
228
229static struct {
230 const char *str;
231 enum export export;
232} export_list[] = {
233 { .str = "EXPORT_SYMBOL", .export = export_plain },
234 { .str = "EXPORT_UNUSED_SYMBOL", .export = export_unused },
235 { .str = "EXPORT_SYMBOL_GPL", .export = export_gpl },
236 { .str = "EXPORT_UNUSED_SYMBOL_GPL", .export = export_unused_gpl },
237 { .str = "EXPORT_SYMBOL_GPL_FUTURE", .export = export_gpl_future },
238 { .str = "(unknown)", .export = export_unknown },
239};
240
241
242static const char *export_str(enum export ex)
243{
244 return export_list[ex].str;
245}
246
247static enum export export_no(const char *s)
248{
249 int i;
250
251 if (!s)
252 return export_unknown;
253 for (i = 0; export_list[i].export != export_unknown; i++) {
254 if (strcmp(export_list[i].str, s) == 0)
255 return export_list[i].export;
256 }
257 return export_unknown;
258}
259
260static const char *sec_name(struct elf_info *elf, int secindex);
261
262#define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0)
263
264static enum export export_from_secname(struct elf_info *elf, unsigned int sec)
265{
266 const char *secname = sec_name(elf, sec);
267
268 if (strstarts(secname, "___ksymtab+"))
269 return export_plain;
270 else if (strstarts(secname, "___ksymtab_unused+"))
271 return export_unused;
272 else if (strstarts(secname, "___ksymtab_gpl+"))
273 return export_gpl;
274 else if (strstarts(secname, "___ksymtab_unused_gpl+"))
275 return export_unused_gpl;
276 else if (strstarts(secname, "___ksymtab_gpl_future+"))
277 return export_gpl_future;
278 else
279 return export_unknown;
280}
281
282static enum export export_from_sec(struct elf_info *elf, unsigned int sec)
283{
284 if (sec == elf->export_sec)
285 return export_plain;
286 else if (sec == elf->export_unused_sec)
287 return export_unused;
288 else if (sec == elf->export_gpl_sec)
289 return export_gpl;
290 else if (sec == elf->export_unused_gpl_sec)
291 return export_unused_gpl;
292 else if (sec == elf->export_gpl_future_sec)
293 return export_gpl_future;
294 else
295 return export_unknown;
296}
297
298
299
300
301
302static struct symbol *sym_add_exported(const char *name, struct module *mod,
303 enum export export)
304{
305 struct symbol *s = find_symbol(name);
306
307 if (!s) {
308 s = new_symbol(name, mod, export);
309 } else {
310 if (!s->preloaded) {
311 warn("%s: '%s' exported twice. Previous export "
312 "was in %s%s\n", mod->name, name,
313 s->module->name,
314 is_vmlinux(s->module->name) ?"":".ko");
315 } else {
316
317 s->module = mod;
318 }
319 }
320 s->preloaded = 0;
321 s->vmlinux = is_vmlinux(mod->name);
322 s->kernel = 0;
323 s->export = export;
324 return s;
325}
326
327static void sym_update_crc(const char *name, struct module *mod,
328 unsigned int crc, enum export export)
329{
330 struct symbol *s = find_symbol(name);
331
332 if (!s)
333 s = new_symbol(name, mod, export);
334 s->crc = crc;
335 s->crc_valid = 1;
336}
337
338void *grab_file(const char *filename, unsigned long *size)
339{
340 struct stat st;
341 void *map = MAP_FAILED;
342 int fd;
343
344 fd = open(filename, O_RDONLY);
345 if (fd < 0)
346 return NULL;
347 if (fstat(fd, &st))
348 goto failed;
349
350 *size = st.st_size;
351 map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
352
353failed:
354 close(fd);
355 if (map == MAP_FAILED)
356 return NULL;
357 return map;
358}
359
360
361
362
363
364
365char *get_next_line(unsigned long *pos, void *file, unsigned long size)
366{
367 static char line[4096];
368 int skip = 1;
369 size_t len = 0;
370 signed char *p = (signed char *)file + *pos;
371 char *s = line;
372
373 for (; *pos < size ; (*pos)++) {
374 if (skip && isspace(*p)) {
375 p++;
376 continue;
377 }
378 skip = 0;
379 if (*p != '\n' && (*pos < size)) {
380 len++;
381 *s++ = *p++;
382 if (len > 4095)
383 break;
384 } else {
385
386 *s = '\0';
387 return line;
388 }
389 }
390
391 return NULL;
392}
393
394void release_file(void *file, unsigned long size)
395{
396 munmap(file, size);
397}
398
399static int parse_elf(struct elf_info *info, const char *filename)
400{
401 unsigned int i;
402 Elf_Ehdr *hdr;
403 Elf_Shdr *sechdrs;
404 Elf_Sym *sym;
405 const char *secstrings;
406 unsigned int symtab_idx = ~0U, symtab_shndx_idx = ~0U;
407
408 hdr = grab_file(filename, &info->size);
409 if (!hdr) {
410 perror(filename);
411 exit(1);
412 }
413 info->hdr = hdr;
414 if (info->size < sizeof(*hdr)) {
415
416 return 0;
417 }
418
419 if ((hdr->e_ident[EI_MAG0] != ELFMAG0) ||
420 (hdr->e_ident[EI_MAG1] != ELFMAG1) ||
421 (hdr->e_ident[EI_MAG2] != ELFMAG2) ||
422 (hdr->e_ident[EI_MAG3] != ELFMAG3)) {
423
424 return 0;
425 }
426
427 hdr->e_type = TO_NATIVE(hdr->e_type);
428 hdr->e_machine = TO_NATIVE(hdr->e_machine);
429 hdr->e_version = TO_NATIVE(hdr->e_version);
430 hdr->e_entry = TO_NATIVE(hdr->e_entry);
431 hdr->e_phoff = TO_NATIVE(hdr->e_phoff);
432 hdr->e_shoff = TO_NATIVE(hdr->e_shoff);
433 hdr->e_flags = TO_NATIVE(hdr->e_flags);
434 hdr->e_ehsize = TO_NATIVE(hdr->e_ehsize);
435 hdr->e_phentsize = TO_NATIVE(hdr->e_phentsize);
436 hdr->e_phnum = TO_NATIVE(hdr->e_phnum);
437 hdr->e_shentsize = TO_NATIVE(hdr->e_shentsize);
438 hdr->e_shnum = TO_NATIVE(hdr->e_shnum);
439 hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx);
440 sechdrs = (void *)hdr + hdr->e_shoff;
441 info->sechdrs = sechdrs;
442
443
444 if (hdr->e_shoff > info->size) {
445 fatal("section header offset=%lu in file '%s' is bigger than "
446 "filesize=%lu\n", (unsigned long)hdr->e_shoff,
447 filename, info->size);
448 return 0;
449 }
450
451 if (hdr->e_shnum == SHN_UNDEF) {
452
453
454
455
456 info->num_sections = TO_NATIVE(sechdrs[0].sh_size);
457 }
458 else {
459 info->num_sections = hdr->e_shnum;
460 }
461 if (hdr->e_shstrndx == SHN_XINDEX) {
462 info->secindex_strings = TO_NATIVE(sechdrs[0].sh_link);
463 }
464 else {
465 info->secindex_strings = hdr->e_shstrndx;
466 }
467
468
469 for (i = 0; i < info->num_sections; i++) {
470 sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name);
471 sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type);
472 sechdrs[i].sh_flags = TO_NATIVE(sechdrs[i].sh_flags);
473 sechdrs[i].sh_addr = TO_NATIVE(sechdrs[i].sh_addr);
474 sechdrs[i].sh_offset = TO_NATIVE(sechdrs[i].sh_offset);
475 sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size);
476 sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link);
477 sechdrs[i].sh_info = TO_NATIVE(sechdrs[i].sh_info);
478 sechdrs[i].sh_addralign = TO_NATIVE(sechdrs[i].sh_addralign);
479 sechdrs[i].sh_entsize = TO_NATIVE(sechdrs[i].sh_entsize);
480 }
481
482 secstrings = (void *)hdr + sechdrs[info->secindex_strings].sh_offset;
483 for (i = 1; i < info->num_sections; i++) {
484 const char *secname;
485 int nobits = sechdrs[i].sh_type == SHT_NOBITS;
486
487 if (!nobits && sechdrs[i].sh_offset > info->size) {
488 fatal("%s is truncated. sechdrs[i].sh_offset=%lu > "
489 "sizeof(*hrd)=%zu\n", filename,
490 (unsigned long)sechdrs[i].sh_offset,
491 sizeof(*hdr));
492 return 0;
493 }
494 secname = secstrings + sechdrs[i].sh_name;
495 if (strcmp(secname, ".modinfo") == 0) {
496 if (nobits)
497 fatal("%s has NOBITS .modinfo\n", filename);
498 info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
499 info->modinfo_len = sechdrs[i].sh_size;
500 } else if (strcmp(secname, "__ksymtab") == 0)
501 info->export_sec = i;
502 else if (strcmp(secname, "__ksymtab_unused") == 0)
503 info->export_unused_sec = i;
504 else if (strcmp(secname, "__ksymtab_gpl") == 0)
505 info->export_gpl_sec = i;
506 else if (strcmp(secname, "__ksymtab_unused_gpl") == 0)
507 info->export_unused_gpl_sec = i;
508 else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
509 info->export_gpl_future_sec = i;
510
511 if (sechdrs[i].sh_type == SHT_SYMTAB) {
512 unsigned int sh_link_idx;
513 symtab_idx = i;
514 info->symtab_start = (void *)hdr +
515 sechdrs[i].sh_offset;
516 info->symtab_stop = (void *)hdr +
517 sechdrs[i].sh_offset + sechdrs[i].sh_size;
518 sh_link_idx = sechdrs[i].sh_link;
519 info->strtab = (void *)hdr +
520 sechdrs[sh_link_idx].sh_offset;
521 }
522
523
524 if (sechdrs[i].sh_type == SHT_SYMTAB_SHNDX) {
525 symtab_shndx_idx = i;
526 info->symtab_shndx_start = (void *)hdr +
527 sechdrs[i].sh_offset;
528 info->symtab_shndx_stop = (void *)hdr +
529 sechdrs[i].sh_offset + sechdrs[i].sh_size;
530 }
531 }
532 if (!info->symtab_start)
533 fatal("%s has no symtab?\n", filename);
534
535
536 for (sym = info->symtab_start; sym < info->symtab_stop; sym++) {
537 sym->st_shndx = TO_NATIVE(sym->st_shndx);
538 sym->st_name = TO_NATIVE(sym->st_name);
539 sym->st_value = TO_NATIVE(sym->st_value);
540 sym->st_size = TO_NATIVE(sym->st_size);
541 }
542
543 if (symtab_shndx_idx != ~0U) {
544 Elf32_Word *p;
545 if (symtab_idx != sechdrs[symtab_shndx_idx].sh_link)
546 fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n",
547 filename, sechdrs[symtab_shndx_idx].sh_link,
548 symtab_idx);
549
550 for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop;
551 p++)
552 *p = TO_NATIVE(*p);
553 }
554
555 return 1;
556}
557
558static void parse_elf_finish(struct elf_info *info)
559{
560 release_file(info->hdr, info->size);
561}
562
563static int ignore_undef_symbol(struct elf_info *info, const char *symname)
564{
565
566 if (strcmp(symname, VMLINUX_SYMBOL_STR(__this_module)) == 0)
567 return 1;
568
569 if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0)
570 return 1;
571 if (info->hdr->e_machine == EM_PPC)
572
573 if (strncmp(symname, "_restgpr_", sizeof("_restgpr_") - 1) == 0 ||
574 strncmp(symname, "_savegpr_", sizeof("_savegpr_") - 1) == 0 ||
575 strncmp(symname, "_rest32gpr_", sizeof("_rest32gpr_") - 1) == 0 ||
576 strncmp(symname, "_save32gpr_", sizeof("_save32gpr_") - 1) == 0)
577 return 1;
578 if (info->hdr->e_machine == EM_PPC64)
579
580 if (strncmp(symname, "_restgpr0_", sizeof("_restgpr0_") - 1) == 0 ||
581 strncmp(symname, "_savegpr0_", sizeof("_savegpr0_") - 1) == 0)
582 return 1;
583
584 return 0;
585}
586
587#define CRC_PFX VMLINUX_SYMBOL_STR(__crc_)
588#define KSYMTAB_PFX VMLINUX_SYMBOL_STR(__ksymtab_)
589
590static void handle_modversions(struct module *mod, struct elf_info *info,
591 Elf_Sym *sym, const char *symname)
592{
593 unsigned int crc;
594 enum export export;
595
596 if ((!is_vmlinux(mod->name) || mod->is_dot_o) &&
597 strncmp(symname, "__ksymtab", 9) == 0)
598 export = export_from_secname(info, get_secindex(info, sym));
599 else
600 export = export_from_sec(info, get_secindex(info, sym));
601
602 switch (sym->st_shndx) {
603 case SHN_COMMON:
604 warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name);
605 break;
606 case SHN_ABS:
607
608 if (strncmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
609 crc = (unsigned int) sym->st_value;
610 sym_update_crc(symname + strlen(CRC_PFX), mod, crc,
611 export);
612 }
613 break;
614 case SHN_UNDEF:
615
616 if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL &&
617 ELF_ST_BIND(sym->st_info) != STB_WEAK)
618 break;
619 if (ignore_undef_symbol(info, symname))
620 break;
621
622#if defined(STT_REGISTER) || defined(STT_SPARC_REGISTER)
623
624#ifndef STT_SPARC_REGISTER
625#define STT_SPARC_REGISTER STT_REGISTER
626#endif
627 if (info->hdr->e_machine == EM_SPARC ||
628 info->hdr->e_machine == EM_SPARCV9) {
629
630 if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)
631 break;
632 if (symname[0] == '.') {
633 char *munged = strdup(symname);
634 munged[0] = '_';
635 munged[1] = toupper(munged[1]);
636 symname = munged;
637 }
638 }
639#endif
640
641#ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX
642 if (symname[0] != '_')
643 break;
644 else
645 symname++;
646#endif
647 mod->unres = alloc_symbol(symname,
648 ELF_ST_BIND(sym->st_info) == STB_WEAK,
649 mod->unres);
650 break;
651 default:
652
653 if (strncmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
654 sym_add_exported(symname + strlen(KSYMTAB_PFX), mod,
655 export);
656 }
657 if (strcmp(symname, VMLINUX_SYMBOL_STR(init_module)) == 0)
658 mod->has_init = 1;
659 if (strcmp(symname, VMLINUX_SYMBOL_STR(cleanup_module)) == 0)
660 mod->has_cleanup = 1;
661 break;
662 }
663}
664
665
666
667
668static char *next_string(char *string, unsigned long *secsize)
669{
670
671 while (string[0]) {
672 string++;
673 if ((*secsize)-- <= 1)
674 return NULL;
675 }
676
677
678 while (!string[0]) {
679 string++;
680 if ((*secsize)-- <= 1)
681 return NULL;
682 }
683 return string;
684}
685
686static char *get_next_modinfo(void *modinfo, unsigned long modinfo_len,
687 const char *tag, char *info)
688{
689 char *p;
690 unsigned int taglen = strlen(tag);
691 unsigned long size = modinfo_len;
692
693 if (info) {
694 size -= info - (char *)modinfo;
695 modinfo = next_string(info, &size);
696 }
697
698 for (p = modinfo; p; p = next_string(p, &size)) {
699 if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
700 return p + taglen + 1;
701 }
702 return NULL;
703}
704
705static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
706 const char *tag)
707
708{
709 return get_next_modinfo(modinfo, modinfo_len, tag, NULL);
710}
711
712
713
714
715
716static int strrcmp(const char *s, const char *sub)
717{
718 int slen, sublen;
719
720 if (!s || !sub)
721 return 1;
722
723 slen = strlen(s);
724 sublen = strlen(sub);
725
726 if ((slen == 0) || (sublen == 0))
727 return 1;
728
729 if (sublen > slen)
730 return 1;
731
732 return memcmp(s + slen - sublen, sub, sublen);
733}
734
735static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
736{
737 if (sym)
738 return elf->strtab + sym->st_name;
739 else
740 return "(unknown)";
741}
742
743static const char *sec_name(struct elf_info *elf, int secindex)
744{
745 Elf_Shdr *sechdrs = elf->sechdrs;
746 return (void *)elf->hdr +
747 elf->sechdrs[elf->secindex_strings].sh_offset +
748 sechdrs[secindex].sh_name;
749}
750
751static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr)
752{
753 return (void *)elf->hdr +
754 elf->sechdrs[elf->secindex_strings].sh_offset +
755 sechdr->sh_name;
756}
757
758
759
760
761
762static int number_prefix(const char *sym)
763{
764 if (*sym++ == '\0')
765 return 1;
766 if (*sym != '.')
767 return 0;
768 do {
769 char c = *sym++;
770 if (c < '0' || c > '9')
771 return 0;
772 } while (*sym);
773 return 1;
774}
775
776
777
778
779
780
781
782
783
784
785static int match(const char *sym, const char * const pat[])
786{
787 const char *p;
788 while (*pat) {
789 p = *pat++;
790 const char *endp = p + strlen(p) - 1;
791
792
793 if (*p == '*') {
794 if (strrcmp(sym, p + 1) == 0)
795 return 1;
796 }
797
798 else if (*endp == '*') {
799 if (strncmp(sym, p, strlen(p) - 1) == 0)
800 return 1;
801 }
802
803 else if (*endp == '$') {
804 if (strncmp(sym, p, strlen(p) - 1) == 0) {
805 if (number_prefix(sym + strlen(p) - 1))
806 return 1;
807 }
808 }
809
810 else {
811 if (strcmp(p, sym) == 0)
812 return 1;
813 }
814 }
815
816 return 0;
817}
818
819
820static const char *section_white_list[] =
821{
822 ".comment*",
823 ".debug*",
824 ".zdebug*",
825 ".GCC-command-line",
826 ".GCC.command.line",
827 ".mdebug*",
828 ".pdr",
829 ".stab*",
830 ".note*",
831 ".got*",
832 ".toc*",
833 ".xt.prop",
834 ".xt.lit",
835 ".arcextmap*",
836 ".gnu.linkonce.arcext*",
837 NULL
838};
839
840
841
842
843
844
845static void check_section(const char *modname, struct elf_info *elf,
846 Elf_Shdr *sechdr)
847{
848 const char *sec = sech_name(elf, sechdr);
849
850 if (sechdr->sh_type == SHT_PROGBITS &&
851 !(sechdr->sh_flags & SHF_ALLOC) &&
852 !match(sec, section_white_list)) {
853 warn("%s (%s): unexpected non-allocatable section.\n"
854 "Did you forget to use \"ax\"/\"aw\" in a .S file?\n"
855 "Note that for example <linux/init.h> contains\n"
856 "section definitions for use in .S files.\n\n",
857 modname, sec);
858 }
859}
860
861
862
863#define ALL_INIT_DATA_SECTIONS \
864 ".init.setup$", ".init.rodata$", ".meminit.rodata$", \
865 ".init.data$", ".meminit.data$"
866#define ALL_EXIT_DATA_SECTIONS \
867 ".exit.data$", ".memexit.data$"
868
869#define ALL_INIT_TEXT_SECTIONS \
870 ".init.text$", ".meminit.text$"
871#define ALL_EXIT_TEXT_SECTIONS \
872 ".exit.text$", ".memexit.text$"
873
874#define ALL_PCI_INIT_SECTIONS \
875 ".pci_fixup_early$", ".pci_fixup_header$", ".pci_fixup_final$", \
876 ".pci_fixup_enable$", ".pci_fixup_resume$", \
877 ".pci_fixup_resume_early$", ".pci_fixup_suspend$"
878
879#define ALL_XXXINIT_SECTIONS MEM_INIT_SECTIONS
880#define ALL_XXXEXIT_SECTIONS MEM_EXIT_SECTIONS
881
882#define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS
883#define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS
884
885#define DATA_SECTIONS ".data$", ".data.rel$"
886#define TEXT_SECTIONS ".text$", ".text.unlikely$"
887
888#define INIT_SECTIONS ".init.*"
889#define MEM_INIT_SECTIONS ".meminit.*"
890
891#define EXIT_SECTIONS ".exit.*"
892#define MEM_EXIT_SECTIONS ".memexit.*"
893
894
895static const char *init_data_sections[] = { ALL_INIT_DATA_SECTIONS, NULL };
896
897
898static const char *init_sections[] = { ALL_INIT_SECTIONS, NULL };
899
900
901static const char *init_exit_sections[] =
902 {ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL };
903
904
905static const char *data_sections[] = { DATA_SECTIONS, NULL };
906
907
908
909#define DEFAULT_SYMBOL_WHITE_LIST \
910 "*driver", \
911 "*_template", \
912 "*_timer", \
913 "*_sht", \
914 "*_ops", \
915 "*_probe", \
916 "*_probe_one", \
917 "*_console"
918
919static const char *head_sections[] = { ".head.text*", NULL };
920static const char *linker_symbols[] =
921 { "__init_begin", "_sinittext", "_einittext", NULL };
922
923enum mismatch {
924 TEXT_TO_ANY_INIT,
925 DATA_TO_ANY_INIT,
926 TEXT_TO_ANY_EXIT,
927 DATA_TO_ANY_EXIT,
928 XXXINIT_TO_SOME_INIT,
929 XXXEXIT_TO_SOME_EXIT,
930 ANY_INIT_TO_ANY_EXIT,
931 ANY_EXIT_TO_ANY_INIT,
932 EXPORT_TO_INIT_EXIT,
933};
934
935struct sectioncheck {
936 const char *fromsec[20];
937 const char *tosec[20];
938 enum mismatch mismatch;
939 const char *symbol_white_list[20];
940};
941
942const struct sectioncheck sectioncheck[] = {
943
944
945
946{
947 .fromsec = { TEXT_SECTIONS, NULL },
948 .tosec = { ALL_INIT_SECTIONS, NULL },
949 .mismatch = TEXT_TO_ANY_INIT,
950 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
951},
952{
953 .fromsec = { DATA_SECTIONS, NULL },
954 .tosec = { ALL_XXXINIT_SECTIONS, NULL },
955 .mismatch = DATA_TO_ANY_INIT,
956 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
957},
958{
959 .fromsec = { DATA_SECTIONS, NULL },
960 .tosec = { INIT_SECTIONS, NULL },
961 .mismatch = DATA_TO_ANY_INIT,
962 .symbol_white_list = {
963 "*_template", "*_timer", "*_sht", "*_ops",
964 "*_probe", "*_probe_one", "*_console", NULL
965 },
966},
967{
968 .fromsec = { TEXT_SECTIONS, NULL },
969 .tosec = { ALL_EXIT_SECTIONS, NULL },
970 .mismatch = TEXT_TO_ANY_EXIT,
971 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
972},
973{
974 .fromsec = { DATA_SECTIONS, NULL },
975 .tosec = { ALL_EXIT_SECTIONS, NULL },
976 .mismatch = DATA_TO_ANY_EXIT,
977 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
978},
979
980{
981 .fromsec = { ALL_XXXINIT_SECTIONS, NULL },
982 .tosec = { INIT_SECTIONS, NULL },
983 .mismatch = XXXINIT_TO_SOME_INIT,
984 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
985},
986
987{
988 .fromsec = { ALL_XXXEXIT_SECTIONS, NULL },
989 .tosec = { EXIT_SECTIONS, NULL },
990 .mismatch = XXXEXIT_TO_SOME_EXIT,
991 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
992},
993
994{
995 .fromsec = { ALL_INIT_SECTIONS, NULL },
996 .tosec = { ALL_EXIT_SECTIONS, NULL },
997 .mismatch = ANY_INIT_TO_ANY_EXIT,
998 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
999},
1000
1001{
1002 .fromsec = { ALL_EXIT_SECTIONS, NULL },
1003 .tosec = { ALL_INIT_SECTIONS, NULL },
1004 .mismatch = ANY_EXIT_TO_ANY_INIT,
1005 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
1006},
1007{
1008 .fromsec = { ALL_PCI_INIT_SECTIONS, NULL },
1009 .tosec = { INIT_SECTIONS, NULL },
1010 .mismatch = ANY_INIT_TO_ANY_EXIT,
1011 .symbol_white_list = { NULL },
1012},
1013
1014{
1015 .fromsec = { "__ksymtab*", NULL },
1016 .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
1017 .mismatch = EXPORT_TO_INIT_EXIT,
1018 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
1019}
1020};
1021
1022static const struct sectioncheck *section_mismatch(
1023 const char *fromsec, const char *tosec)
1024{
1025 int i;
1026 int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck);
1027 const struct sectioncheck *check = §ioncheck[0];
1028
1029 for (i = 0; i < elems; i++) {
1030 if (match(fromsec, check->fromsec) &&
1031 match(tosec, check->tosec))
1032 return check;
1033 check++;
1034 }
1035 return NULL;
1036}
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080static int secref_whitelist(const struct sectioncheck *mismatch,
1081 const char *fromsec, const char *fromsym,
1082 const char *tosec, const char *tosym)
1083{
1084
1085 if (match(tosec, init_data_sections) &&
1086 match(fromsec, data_sections) &&
1087 (strncmp(fromsym, "__param", strlen("__param")) == 0))
1088 return 0;
1089
1090
1091 if (strcmp(tosec, ".init.text") == 0 &&
1092 match(fromsec, data_sections) &&
1093 (strncmp(fromsym, "__param_ops_", strlen("__param_ops_")) == 0))
1094 return 0;
1095
1096
1097 if (match(tosec, init_exit_sections) &&
1098 match(fromsec, data_sections) &&
1099 match(fromsym, mismatch->symbol_white_list))
1100 return 0;
1101
1102
1103 if (match(fromsec, head_sections) &&
1104 match(tosec, init_sections))
1105 return 0;
1106
1107
1108 if (match(tosym, linker_symbols))
1109 return 0;
1110
1111 return 1;
1112}
1113
1114
1115
1116
1117
1118
1119
1120
1121static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,
1122 Elf_Sym *relsym)
1123{
1124 Elf_Sym *sym;
1125 Elf_Sym *near = NULL;
1126 Elf64_Sword distance = 20;
1127 Elf64_Sword d;
1128 unsigned int relsym_secindex;
1129
1130 if (relsym->st_name != 0)
1131 return relsym;
1132
1133 relsym_secindex = get_secindex(elf, relsym);
1134 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
1135 if (get_secindex(elf, sym) != relsym_secindex)
1136 continue;
1137 if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
1138 continue;
1139 if (sym->st_value == addr)
1140 return sym;
1141
1142 d = sym->st_value - addr;
1143 if (d < 0)
1144 d = addr - sym->st_value;
1145 if (d < distance) {
1146 distance = d;
1147 near = sym;
1148 }
1149 }
1150
1151 if (distance < 20)
1152 return near;
1153 else
1154 return NULL;
1155}
1156
1157static inline int is_arm_mapping_symbol(const char *str)
1158{
1159 return str[0] == '$' && strchr("atd", str[1])
1160 && (str[2] == '\0' || str[2] == '.');
1161}
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172static inline int is_valid_name(struct elf_info *elf, Elf_Sym *sym)
1173{
1174 const char *name = elf->strtab + sym->st_name;
1175
1176 if (!name || !strlen(name))
1177 return 0;
1178 return !is_arm_mapping_symbol(name);
1179}
1180
1181
1182
1183
1184
1185
1186
1187static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
1188 const char *sec)
1189{
1190 Elf_Sym *sym;
1191 Elf_Sym *near = NULL;
1192 Elf_Addr distance = ~0;
1193
1194 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
1195 const char *symsec;
1196
1197 if (is_shndx_special(sym->st_shndx))
1198 continue;
1199 symsec = sec_name(elf, get_secindex(elf, sym));
1200 if (strcmp(symsec, sec) != 0)
1201 continue;
1202 if (!is_valid_name(elf, sym))
1203 continue;
1204 if (sym->st_value <= addr) {
1205 if ((addr - sym->st_value) < distance) {
1206 distance = addr - sym->st_value;
1207 near = sym;
1208 } else if ((addr - sym->st_value) == distance) {
1209 near = sym;
1210 }
1211 }
1212 }
1213 return near;
1214}
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225static char *sec2annotation(const char *s)
1226{
1227 if (match(s, init_exit_sections)) {
1228 char *p = malloc(20);
1229 char *r = p;
1230
1231 *p++ = '_';
1232 *p++ = '_';
1233 if (*s == '.')
1234 s++;
1235 while (*s && *s != '.')
1236 *p++ = *s++;
1237 *p = '\0';
1238 if (*s == '.')
1239 s++;
1240 if (strstr(s, "rodata") != NULL)
1241 strcat(p, "const ");
1242 else if (strstr(s, "data") != NULL)
1243 strcat(p, "data ");
1244 else
1245 strcat(p, " ");
1246 return r;
1247 } else {
1248 return strdup("");
1249 }
1250}
1251
1252static int is_function(Elf_Sym *sym)
1253{
1254 if (sym)
1255 return ELF_ST_TYPE(sym->st_info) == STT_FUNC;
1256 else
1257 return -1;
1258}
1259
1260static void print_section_list(const char * const list[20])
1261{
1262 const char *const *s = list;
1263
1264 while (*s) {
1265 fprintf(stderr, "%s", *s);
1266 s++;
1267 if (*s)
1268 fprintf(stderr, ", ");
1269 }
1270 fprintf(stderr, "\n");
1271}
1272
1273
1274
1275
1276
1277
1278static void report_sec_mismatch(const char *modname,
1279 const struct sectioncheck *mismatch,
1280 const char *fromsec,
1281 unsigned long long fromaddr,
1282 const char *fromsym,
1283 int from_is_func,
1284 const char *tosec, const char *tosym,
1285 int to_is_func)
1286{
1287 const char *from, *from_p;
1288 const char *to, *to_p;
1289 char *prl_from;
1290 char *prl_to;
1291
1292 switch (from_is_func) {
1293 case 0: from = "variable"; from_p = ""; break;
1294 case 1: from = "function"; from_p = "()"; break;
1295 default: from = "(unknown reference)"; from_p = ""; break;
1296 }
1297 switch (to_is_func) {
1298 case 0: to = "variable"; to_p = ""; break;
1299 case 1: to = "function"; to_p = "()"; break;
1300 default: to = "(unknown reference)"; to_p = ""; break;
1301 }
1302
1303 sec_mismatch_count++;
1304 if (!sec_mismatch_verbose)
1305 return;
1306
1307 warn("%s(%s+0x%llx): Section mismatch in reference from the %s %s%s "
1308 "to the %s %s:%s%s\n",
1309 modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec,
1310 tosym, to_p);
1311
1312 switch (mismatch->mismatch) {
1313 case TEXT_TO_ANY_INIT:
1314 prl_from = sec2annotation(fromsec);
1315 prl_to = sec2annotation(tosec);
1316 fprintf(stderr,
1317 "The function %s%s() references\n"
1318 "the %s %s%s%s.\n"
1319 "This is often because %s lacks a %s\n"
1320 "annotation or the annotation of %s is wrong.\n",
1321 prl_from, fromsym,
1322 to, prl_to, tosym, to_p,
1323 fromsym, prl_to, tosym);
1324 free(prl_from);
1325 free(prl_to);
1326 break;
1327 case DATA_TO_ANY_INIT: {
1328 prl_to = sec2annotation(tosec);
1329 fprintf(stderr,
1330 "The variable %s references\n"
1331 "the %s %s%s%s\n"
1332 "If the reference is valid then annotate the\n"
1333 "variable with __init* or __refdata (see linux/init.h) "
1334 "or name the variable:\n",
1335 fromsym, to, prl_to, tosym, to_p);
1336 print_section_list(mismatch->symbol_white_list);
1337 free(prl_to);
1338 break;
1339 }
1340 case TEXT_TO_ANY_EXIT:
1341 prl_to = sec2annotation(tosec);
1342 fprintf(stderr,
1343 "The function %s() references a %s in an exit section.\n"
1344 "Often the %s %s%s has valid usage outside the exit section\n"
1345 "and the fix is to remove the %sannotation of %s.\n",
1346 fromsym, to, to, tosym, to_p, prl_to, tosym);
1347 free(prl_to);
1348 break;
1349 case DATA_TO_ANY_EXIT: {
1350 prl_to = sec2annotation(tosec);
1351 fprintf(stderr,
1352 "The variable %s references\n"
1353 "the %s %s%s%s\n"
1354 "If the reference is valid then annotate the\n"
1355 "variable with __exit* (see linux/init.h) or "
1356 "name the variable:\n",
1357 fromsym, to, prl_to, tosym, to_p);
1358 print_section_list(mismatch->symbol_white_list);
1359 free(prl_to);
1360 break;
1361 }
1362 case XXXINIT_TO_SOME_INIT:
1363 case XXXEXIT_TO_SOME_EXIT:
1364 prl_from = sec2annotation(fromsec);
1365 prl_to = sec2annotation(tosec);
1366 fprintf(stderr,
1367 "The %s %s%s%s references\n"
1368 "a %s %s%s%s.\n"
1369 "If %s is only used by %s then\n"
1370 "annotate %s with a matching annotation.\n",
1371 from, prl_from, fromsym, from_p,
1372 to, prl_to, tosym, to_p,
1373 tosym, fromsym, tosym);
1374 free(prl_from);
1375 free(prl_to);
1376 break;
1377 case ANY_INIT_TO_ANY_EXIT:
1378 prl_from = sec2annotation(fromsec);
1379 prl_to = sec2annotation(tosec);
1380 fprintf(stderr,
1381 "The %s %s%s%s references\n"
1382 "a %s %s%s%s.\n"
1383 "This is often seen when error handling "
1384 "in the init function\n"
1385 "uses functionality in the exit path.\n"
1386 "The fix is often to remove the %sannotation of\n"
1387 "%s%s so it may be used outside an exit section.\n",
1388 from, prl_from, fromsym, from_p,
1389 to, prl_to, tosym, to_p,
1390 prl_to, tosym, to_p);
1391 free(prl_from);
1392 free(prl_to);
1393 break;
1394 case ANY_EXIT_TO_ANY_INIT:
1395 prl_from = sec2annotation(fromsec);
1396 prl_to = sec2annotation(tosec);
1397 fprintf(stderr,
1398 "The %s %s%s%s references\n"
1399 "a %s %s%s%s.\n"
1400 "This is often seen when error handling "
1401 "in the exit function\n"
1402 "uses functionality in the init path.\n"
1403 "The fix is often to remove the %sannotation of\n"
1404 "%s%s so it may be used outside an init section.\n",
1405 from, prl_from, fromsym, from_p,
1406 to, prl_to, tosym, to_p,
1407 prl_to, tosym, to_p);
1408 free(prl_from);
1409 free(prl_to);
1410 break;
1411 case EXPORT_TO_INIT_EXIT:
1412 prl_to = sec2annotation(tosec);
1413 fprintf(stderr,
1414 "The symbol %s is exported and annotated %s\n"
1415 "Fix this by removing the %sannotation of %s "
1416 "or drop the export.\n",
1417 tosym, prl_to, prl_to, tosym);
1418 free(prl_to);
1419 break;
1420 }
1421 fprintf(stderr, "\n");
1422}
1423
1424static void check_section_mismatch(const char *modname, struct elf_info *elf,
1425 Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
1426{
1427 const char *tosec;
1428 const struct sectioncheck *mismatch;
1429
1430 tosec = sec_name(elf, get_secindex(elf, sym));
1431 mismatch = section_mismatch(fromsec, tosec);
1432 if (mismatch) {
1433 Elf_Sym *to;
1434 Elf_Sym *from;
1435 const char *tosym;
1436 const char *fromsym;
1437
1438 from = find_elf_symbol2(elf, r->r_offset, fromsec);
1439 fromsym = sym_name(elf, from);
1440 to = find_elf_symbol(elf, r->r_addend, sym);
1441 tosym = sym_name(elf, to);
1442
1443
1444 if (secref_whitelist(mismatch,
1445 fromsec, fromsym, tosec, tosym)) {
1446 report_sec_mismatch(modname, mismatch,
1447 fromsec, r->r_offset, fromsym,
1448 is_function(from), tosec, tosym,
1449 is_function(to));
1450 }
1451 }
1452}
1453
1454static unsigned int *reloc_location(struct elf_info *elf,
1455 Elf_Shdr *sechdr, Elf_Rela *r)
1456{
1457 Elf_Shdr *sechdrs = elf->sechdrs;
1458 int section = sechdr->sh_info;
1459
1460 return (void *)elf->hdr + sechdrs[section].sh_offset +
1461 r->r_offset;
1462}
1463
1464static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
1465{
1466 unsigned int r_typ = ELF_R_TYPE(r->r_info);
1467 unsigned int *location = reloc_location(elf, sechdr, r);
1468
1469 switch (r_typ) {
1470 case R_386_32:
1471 r->r_addend = TO_NATIVE(*location);
1472 break;
1473 case R_386_PC32:
1474 r->r_addend = TO_NATIVE(*location) + 4;
1475
1476 if (elf->hdr->e_type == ET_EXEC)
1477 r->r_addend += r->r_offset;
1478 break;
1479 }
1480 return 0;
1481}
1482
1483#ifndef R_ARM_CALL
1484#define R_ARM_CALL 28
1485#endif
1486#ifndef R_ARM_JUMP24
1487#define R_ARM_JUMP24 29
1488#endif
1489
1490static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
1491{
1492 unsigned int r_typ = ELF_R_TYPE(r->r_info);
1493
1494 switch (r_typ) {
1495 case R_ARM_ABS32:
1496
1497 r->r_addend = (int)(long)
1498 (elf->symtab_start + ELF_R_SYM(r->r_info));
1499 break;
1500 case R_ARM_PC24:
1501 case R_ARM_CALL:
1502 case R_ARM_JUMP24:
1503
1504 r->r_addend = (int)(long)(elf->hdr +
1505 sechdr->sh_offset +
1506 (r->r_offset - sechdr->sh_addr));
1507 break;
1508 default:
1509 return 1;
1510 }
1511 return 0;
1512}
1513
1514static int addend_mips_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
1515{
1516 unsigned int r_typ = ELF_R_TYPE(r->r_info);
1517 unsigned int *location = reloc_location(elf, sechdr, r);
1518 unsigned int inst;
1519
1520 if (r_typ == R_MIPS_HI16)
1521 return 1;
1522 inst = TO_NATIVE(*location);
1523 switch (r_typ) {
1524 case R_MIPS_LO16:
1525 r->r_addend = inst & 0xffff;
1526 break;
1527 case R_MIPS_26:
1528 r->r_addend = (inst & 0x03ffffff) << 2;
1529 break;
1530 case R_MIPS_32:
1531 r->r_addend = inst;
1532 break;
1533 }
1534 return 0;
1535}
1536
1537static void section_rela(const char *modname, struct elf_info *elf,
1538 Elf_Shdr *sechdr)
1539{
1540 Elf_Sym *sym;
1541 Elf_Rela *rela;
1542 Elf_Rela r;
1543 unsigned int r_sym;
1544 const char *fromsec;
1545
1546 Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset;
1547 Elf_Rela *stop = (void *)start + sechdr->sh_size;
1548
1549 fromsec = sech_name(elf, sechdr);
1550 fromsec += strlen(".rela");
1551
1552 if (match(fromsec, section_white_list))
1553 return;
1554
1555 for (rela = start; rela < stop; rela++) {
1556 r.r_offset = TO_NATIVE(rela->r_offset);
1557#if KERNEL_ELFCLASS == ELFCLASS64
1558 if (elf->hdr->e_machine == EM_MIPS) {
1559 unsigned int r_typ;
1560 r_sym = ELF64_MIPS_R_SYM(rela->r_info);
1561 r_sym = TO_NATIVE(r_sym);
1562 r_typ = ELF64_MIPS_R_TYPE(rela->r_info);
1563 r.r_info = ELF64_R_INFO(r_sym, r_typ);
1564 } else {
1565 r.r_info = TO_NATIVE(rela->r_info);
1566 r_sym = ELF_R_SYM(r.r_info);
1567 }
1568#else
1569 r.r_info = TO_NATIVE(rela->r_info);
1570 r_sym = ELF_R_SYM(r.r_info);
1571#endif
1572 r.r_addend = TO_NATIVE(rela->r_addend);
1573 sym = elf->symtab_start + r_sym;
1574
1575 if (is_shndx_special(sym->st_shndx))
1576 continue;
1577 check_section_mismatch(modname, elf, &r, sym, fromsec);
1578 }
1579}
1580
1581static void section_rel(const char *modname, struct elf_info *elf,
1582 Elf_Shdr *sechdr)
1583{
1584 Elf_Sym *sym;
1585 Elf_Rel *rel;
1586 Elf_Rela r;
1587 unsigned int r_sym;
1588 const char *fromsec;
1589
1590 Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset;
1591 Elf_Rel *stop = (void *)start + sechdr->sh_size;
1592
1593 fromsec = sech_name(elf, sechdr);
1594 fromsec += strlen(".rel");
1595
1596 if (match(fromsec, section_white_list))
1597 return;
1598
1599 for (rel = start; rel < stop; rel++) {
1600 r.r_offset = TO_NATIVE(rel->r_offset);
1601#if KERNEL_ELFCLASS == ELFCLASS64
1602 if (elf->hdr->e_machine == EM_MIPS) {
1603 unsigned int r_typ;
1604 r_sym = ELF64_MIPS_R_SYM(rel->r_info);
1605 r_sym = TO_NATIVE(r_sym);
1606 r_typ = ELF64_MIPS_R_TYPE(rel->r_info);
1607 r.r_info = ELF64_R_INFO(r_sym, r_typ);
1608 } else {
1609 r.r_info = TO_NATIVE(rel->r_info);
1610 r_sym = ELF_R_SYM(r.r_info);
1611 }
1612#else
1613 r.r_info = TO_NATIVE(rel->r_info);
1614 r_sym = ELF_R_SYM(r.r_info);
1615#endif
1616 r.r_addend = 0;
1617 switch (elf->hdr->e_machine) {
1618 case EM_386:
1619 if (addend_386_rel(elf, sechdr, &r))
1620 continue;
1621 break;
1622 case EM_ARM:
1623 if (addend_arm_rel(elf, sechdr, &r))
1624 continue;
1625 break;
1626 case EM_MIPS:
1627 if (addend_mips_rel(elf, sechdr, &r))
1628 continue;
1629 break;
1630 }
1631 sym = elf->symtab_start + r_sym;
1632
1633 if (is_shndx_special(sym->st_shndx))
1634 continue;
1635 check_section_mismatch(modname, elf, &r, sym, fromsec);
1636 }
1637}
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651static void check_sec_ref(struct module *mod, const char *modname,
1652 struct elf_info *elf)
1653{
1654 int i;
1655 Elf_Shdr *sechdrs = elf->sechdrs;
1656
1657
1658 for (i = 0; i < elf->num_sections; i++) {
1659 check_section(modname, elf, &elf->sechdrs[i]);
1660
1661 if (sechdrs[i].sh_type == SHT_RELA)
1662 section_rela(modname, elf, &elf->sechdrs[i]);
1663 else if (sechdrs[i].sh_type == SHT_REL)
1664 section_rel(modname, elf, &elf->sechdrs[i]);
1665 }
1666}
1667
1668static void read_symbols(char *modname)
1669{
1670 const char *symname;
1671 char *version;
1672 char *license;
1673 struct module *mod;
1674 struct elf_info info = { };
1675 Elf_Sym *sym;
1676
1677 if (!parse_elf(&info, modname))
1678 return;
1679
1680 mod = new_module(modname);
1681
1682
1683
1684 if (is_vmlinux(modname)) {
1685 have_vmlinux = 1;
1686 mod->skip = 1;
1687 }
1688
1689 license = get_modinfo(info.modinfo, info.modinfo_len, "license");
1690 if (info.modinfo && !license && !is_vmlinux(modname))
1691 warn("modpost: missing MODULE_LICENSE() in %s\n"
1692 "see include/linux/module.h for "
1693 "more information\n", modname);
1694 while (license) {
1695 if (license_is_gpl_compatible(license))
1696 mod->gpl_compatible = 1;
1697 else {
1698 mod->gpl_compatible = 0;
1699 break;
1700 }
1701 license = get_next_modinfo(info.modinfo, info.modinfo_len,
1702 "license", license);
1703 }
1704
1705 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
1706 symname = info.strtab + sym->st_name;
1707
1708 handle_modversions(mod, &info, sym, symname);
1709 handle_moddevtable(mod, &info, sym, symname);
1710 }
1711 if (!is_vmlinux(modname) ||
1712 (is_vmlinux(modname) && vmlinux_section_warnings))
1713 check_sec_ref(mod, modname, &info);
1714
1715 version = get_modinfo(info.modinfo, info.modinfo_len, "version");
1716 if (version)
1717 maybe_frob_rcs_version(modname, version, info.modinfo,
1718 version - (char *)info.hdr);
1719 if (version || (all_versions && !is_vmlinux(modname)))
1720 get_src_version(modname, mod->srcversion,
1721 sizeof(mod->srcversion)-1);
1722
1723 parse_elf_finish(&info);
1724
1725
1726
1727
1728
1729 if (modversions)
1730 mod->unres = alloc_symbol("module_layout", 0, mod->unres);
1731}
1732
1733static void read_symbols_from_files(const char *filename)
1734{
1735 FILE *in = stdin;
1736 char fname[PATH_MAX];
1737
1738 if (strcmp(filename, "-") != 0) {
1739 in = fopen(filename, "r");
1740 if (!in)
1741 fatal("Can't open filenames file %s: %m", filename);
1742 }
1743
1744 while (fgets(fname, PATH_MAX, in) != NULL) {
1745 if (strends(fname, "\n"))
1746 fname[strlen(fname)-1] = '\0';
1747 read_symbols(fname);
1748 }
1749
1750 if (in != stdin)
1751 fclose(in);
1752}
1753
1754#define SZ 500
1755
1756
1757
1758
1759
1760void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf,
1761 const char *fmt, ...)
1762{
1763 char tmp[SZ];
1764 int len;
1765 va_list ap;
1766
1767 va_start(ap, fmt);
1768 len = vsnprintf(tmp, SZ, fmt, ap);
1769 buf_write(buf, tmp, len);
1770 va_end(ap);
1771}
1772
1773void buf_write(struct buffer *buf, const char *s, int len)
1774{
1775 if (buf->size - buf->pos < len) {
1776 buf->size += len + SZ;
1777 buf->p = realloc(buf->p, buf->size);
1778 }
1779 strncpy(buf->p + buf->pos, s, len);
1780 buf->pos += len;
1781}
1782
1783static void check_for_gpl_usage(enum export exp, const char *m, const char *s)
1784{
1785 const char *e = is_vmlinux(m) ?"":".ko";
1786
1787 switch (exp) {
1788 case export_gpl:
1789 fatal("modpost: GPL-incompatible module %s%s "
1790 "uses GPL-only symbol '%s'\n", m, e, s);
1791 break;
1792 case export_unused_gpl:
1793 fatal("modpost: GPL-incompatible module %s%s "
1794 "uses GPL-only symbol marked UNUSED '%s'\n", m, e, s);
1795 break;
1796 case export_gpl_future:
1797 warn("modpost: GPL-incompatible module %s%s "
1798 "uses future GPL-only symbol '%s'\n", m, e, s);
1799 break;
1800 case export_plain:
1801 case export_unused:
1802 case export_unknown:
1803
1804 break;
1805 }
1806}
1807
1808static void check_for_unused(enum export exp, const char *m, const char *s)
1809{
1810 const char *e = is_vmlinux(m) ?"":".ko";
1811
1812 switch (exp) {
1813 case export_unused:
1814 case export_unused_gpl:
1815 warn("modpost: module %s%s "
1816 "uses symbol '%s' marked UNUSED\n", m, e, s);
1817 break;
1818 default:
1819
1820 break;
1821 }
1822}
1823
1824static void check_exports(struct module *mod)
1825{
1826 struct symbol *s, *exp;
1827
1828 for (s = mod->unres; s; s = s->next) {
1829 const char *basename;
1830 exp = find_symbol(s->name);
1831 if (!exp || exp->module == mod)
1832 continue;
1833 basename = strrchr(mod->name, '/');
1834 if (basename)
1835 basename++;
1836 else
1837 basename = mod->name;
1838 if (!mod->gpl_compatible)
1839 check_for_gpl_usage(exp->export, basename, exp->name);
1840 check_for_unused(exp->export, basename, exp->name);
1841 }
1842}
1843
1844
1845
1846
1847static void add_header(struct buffer *b, struct module *mod)
1848{
1849 buf_printf(b, "#include <linux/module.h>\n");
1850 buf_printf(b, "#include <linux/vermagic.h>\n");
1851 buf_printf(b, "#include <linux/compiler.h>\n");
1852 buf_printf(b, "\n");
1853 buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
1854 buf_printf(b, "\n");
1855 buf_printf(b, "struct module __this_module\n");
1856 buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");
1857 buf_printf(b, "\t.name = KBUILD_MODNAME,\n");
1858 if (mod->has_init)
1859 buf_printf(b, "\t.init = init_module,\n");
1860 if (mod->has_cleanup)
1861 buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n"
1862 "\t.exit = cleanup_module,\n"
1863 "#endif\n");
1864 buf_printf(b, "\t.arch = MODULE_ARCH_INIT,\n");
1865 buf_printf(b, "};\n");
1866}
1867
1868static void add_intree_flag(struct buffer *b, int is_intree)
1869{
1870 if (is_intree)
1871 buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n");
1872}
1873
1874static void add_staging_flag(struct buffer *b, const char *name)
1875{
1876 static const char *staging_dir = "drivers/staging";
1877
1878 if (strncmp(staging_dir, name, strlen(staging_dir)) == 0)
1879 buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
1880}
1881
1882
1883
1884
1885static int add_versions(struct buffer *b, struct module *mod)
1886{
1887 struct symbol *s, *exp;
1888 int err = 0;
1889
1890 for (s = mod->unres; s; s = s->next) {
1891 exp = find_symbol(s->name);
1892 if (!exp || exp->module == mod) {
1893 if (have_vmlinux && !s->weak) {
1894 if (warn_unresolved) {
1895 warn("\"%s\" [%s.ko] undefined!\n",
1896 s->name, mod->name);
1897 } else {
1898 merror("\"%s\" [%s.ko] undefined!\n",
1899 s->name, mod->name);
1900 err = 1;
1901 }
1902 }
1903 continue;
1904 }
1905 s->module = exp->module;
1906 s->crc_valid = exp->crc_valid;
1907 s->crc = exp->crc;
1908 }
1909
1910 if (!modversions)
1911 return err;
1912
1913 buf_printf(b, "\n");
1914 buf_printf(b, "static const struct modversion_info ____versions[]\n");
1915 buf_printf(b, "__used\n");
1916 buf_printf(b, "__attribute__((section(\"__versions\"))) = {\n");
1917
1918 for (s = mod->unres; s; s = s->next) {
1919 if (!s->module)
1920 continue;
1921 if (!s->crc_valid) {
1922 warn("\"%s\" [%s.ko] has no CRC!\n",
1923 s->name, mod->name);
1924 continue;
1925 }
1926 buf_printf(b, "\t{ %#8x, __VMLINUX_SYMBOL_STR(%s) },\n",
1927 s->crc, s->name);
1928 }
1929
1930 buf_printf(b, "};\n");
1931
1932 return err;
1933}
1934
1935static void add_depends(struct buffer *b, struct module *mod,
1936 struct module *modules)
1937{
1938 struct symbol *s;
1939 struct module *m;
1940 int first = 1;
1941
1942 for (m = modules; m; m = m->next)
1943 m->seen = is_vmlinux(m->name);
1944
1945 buf_printf(b, "\n");
1946 buf_printf(b, "static const char __module_depends[]\n");
1947 buf_printf(b, "__used\n");
1948 buf_printf(b, "__attribute__((section(\".modinfo\"))) =\n");
1949 buf_printf(b, "\"depends=");
1950 for (s = mod->unres; s; s = s->next) {
1951 const char *p;
1952 if (!s->module)
1953 continue;
1954
1955 if (s->module->seen)
1956 continue;
1957
1958 s->module->seen = 1;
1959 p = strrchr(s->module->name, '/');
1960 if (p)
1961 p++;
1962 else
1963 p = s->module->name;
1964 buf_printf(b, "%s%s", first ? "" : ",", p);
1965 first = 0;
1966 }
1967 buf_printf(b, "\";\n");
1968}
1969
1970static void add_srcversion(struct buffer *b, struct module *mod)
1971{
1972 if (mod->srcversion[0]) {
1973 buf_printf(b, "\n");
1974 buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n",
1975 mod->srcversion);
1976 }
1977}
1978
1979static void write_if_changed(struct buffer *b, const char *fname)
1980{
1981 char *tmp;
1982 FILE *file;
1983 struct stat st;
1984
1985 file = fopen(fname, "r");
1986 if (!file)
1987 goto write;
1988
1989 if (fstat(fileno(file), &st) < 0)
1990 goto close_write;
1991
1992 if (st.st_size != b->pos)
1993 goto close_write;
1994
1995 tmp = NOFAIL(malloc(b->pos));
1996 if (fread(tmp, 1, b->pos, file) != b->pos)
1997 goto free_write;
1998
1999 if (memcmp(tmp, b->p, b->pos) != 0)
2000 goto free_write;
2001
2002 free(tmp);
2003 fclose(file);
2004 return;
2005
2006 free_write:
2007 free(tmp);
2008 close_write:
2009 fclose(file);
2010 write:
2011 file = fopen(fname, "w");
2012 if (!file) {
2013 perror(fname);
2014 exit(1);
2015 }
2016 if (fwrite(b->p, 1, b->pos, file) != b->pos) {
2017 perror(fname);
2018 exit(1);
2019 }
2020 fclose(file);
2021}
2022
2023
2024
2025
2026static void read_dump(const char *fname, unsigned int kernel)
2027{
2028 unsigned long size, pos = 0;
2029 void *file = grab_file(fname, &size);
2030 char *line;
2031
2032 if (!file)
2033
2034 return;
2035
2036 while ((line = get_next_line(&pos, file, size))) {
2037 char *symname, *modname, *d, *export, *end;
2038 unsigned int crc;
2039 struct module *mod;
2040 struct symbol *s;
2041
2042 if (!(symname = strchr(line, '\t')))
2043 goto fail;
2044 *symname++ = '\0';
2045 if (!(modname = strchr(symname, '\t')))
2046 goto fail;
2047 *modname++ = '\0';
2048 if ((export = strchr(modname, '\t')) != NULL)
2049 *export++ = '\0';
2050 if (export && ((end = strchr(export, '\t')) != NULL))
2051 *end = '\0';
2052 crc = strtoul(line, &d, 16);
2053 if (*symname == '\0' || *modname == '\0' || *d != '\0')
2054 goto fail;
2055 mod = find_module(modname);
2056 if (!mod) {
2057 if (is_vmlinux(modname))
2058 have_vmlinux = 1;
2059 mod = new_module(modname);
2060 mod->skip = 1;
2061 }
2062 s = sym_add_exported(symname, mod, export_no(export));
2063 s->kernel = kernel;
2064 s->preloaded = 1;
2065 sym_update_crc(symname, mod, crc, export_no(export));
2066 }
2067 return;
2068fail:
2069 fatal("parse error in symbol dump file\n");
2070}
2071
2072
2073
2074
2075
2076static int dump_sym(struct symbol *sym)
2077{
2078 if (!external_module)
2079 return 1;
2080 if (sym->vmlinux || sym->kernel)
2081 return 0;
2082 return 1;
2083}
2084
2085static void write_dump(const char *fname)
2086{
2087 struct buffer buf = { };
2088 struct symbol *symbol;
2089 int n;
2090
2091 for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
2092 symbol = symbolhash[n];
2093 while (symbol) {
2094 if (dump_sym(symbol))
2095 buf_printf(&buf, "0x%08x\t%s\t%s\t%s\n",
2096 symbol->crc, symbol->name,
2097 symbol->module->name,
2098 export_str(symbol->export));
2099 symbol = symbol->next;
2100 }
2101 }
2102 write_if_changed(&buf, fname);
2103}
2104
2105struct ext_sym_list {
2106 struct ext_sym_list *next;
2107 const char *file;
2108};
2109
2110int main(int argc, char **argv)
2111{
2112 struct module *mod;
2113 struct buffer buf = { };
2114 char *kernel_read = NULL, *module_read = NULL;
2115 char *dump_write = NULL, *files_source = NULL;
2116 int opt;
2117 int err;
2118 struct ext_sym_list *extsym_iter;
2119 struct ext_sym_list *extsym_start = NULL;
2120
2121 while ((opt = getopt(argc, argv, "i:I:e:msST:o:awM:K:")) != -1) {
2122 switch (opt) {
2123 case 'i':
2124 kernel_read = optarg;
2125 break;
2126 case 'I':
2127 module_read = optarg;
2128 external_module = 1;
2129 break;
2130 case 'e':
2131 external_module = 1;
2132 extsym_iter =
2133 NOFAIL(malloc(sizeof(*extsym_iter)));
2134 extsym_iter->next = extsym_start;
2135 extsym_iter->file = optarg;
2136 extsym_start = extsym_iter;
2137 break;
2138 case 'm':
2139 modversions = 1;
2140 break;
2141 case 'o':
2142 dump_write = optarg;
2143 break;
2144 case 'a':
2145 all_versions = 1;
2146 break;
2147 case 's':
2148 vmlinux_section_warnings = 0;
2149 break;
2150 case 'S':
2151 sec_mismatch_verbose = 0;
2152 break;
2153 case 'T':
2154 files_source = optarg;
2155 break;
2156 case 'w':
2157 warn_unresolved = 1;
2158 break;
2159 default:
2160 exit(1);
2161 }
2162 }
2163
2164 if (kernel_read)
2165 read_dump(kernel_read, 1);
2166 if (module_read)
2167 read_dump(module_read, 0);
2168 while (extsym_start) {
2169 read_dump(extsym_start->file, 0);
2170 extsym_iter = extsym_start->next;
2171 free(extsym_start);
2172 extsym_start = extsym_iter;
2173 }
2174
2175 while (optind < argc)
2176 read_symbols(argv[optind++]);
2177
2178 if (files_source)
2179 read_symbols_from_files(files_source);
2180
2181 for (mod = modules; mod; mod = mod->next) {
2182 if (mod->skip)
2183 continue;
2184 check_exports(mod);
2185 }
2186
2187 err = 0;
2188
2189 for (mod = modules; mod; mod = mod->next) {
2190 char fname[strlen(mod->name) + 10];
2191
2192 if (mod->skip)
2193 continue;
2194
2195 buf.pos = 0;
2196
2197 add_header(&buf, mod);
2198 add_intree_flag(&buf, !external_module);
2199 add_staging_flag(&buf, mod->name);
2200 err |= add_versions(&buf, mod);
2201 add_depends(&buf, mod, modules);
2202 add_moddevtable(&buf, mod);
2203 add_srcversion(&buf, mod);
2204
2205 sprintf(fname, "%s.mod.c", mod->name);
2206 write_if_changed(&buf, fname);
2207 }
2208
2209 if (dump_write)
2210 write_dump(dump_write);
2211 if (sec_mismatch_count && !sec_mismatch_verbose)
2212 warn("modpost: Found %d section mismatch(es).\n"
2213 "To see full details build your kernel with:\n"
2214 "'make CONFIG_DEBUG_SECTION_MISMATCH=y'\n",
2215 sec_mismatch_count);
2216
2217 return err;
2218}
2219