1 | /* Postprocess module symbol versions |
2 | * |
3 | * Copyright 2003 Kai Germaschewski |
4 | * Copyright 2002-2004 Rusty Russell, IBM Corporation |
5 | * Copyright 2006-2008 Sam Ravnborg |
6 | * Based in part on module-init-tools/depmod.c,file2alias |
7 | * |
8 | * This software may be used and distributed according to the terms |
9 | * of the GNU General Public License, incorporated herein by reference. |
10 | * |
11 | * Usage: modpost vmlinux module1.o module2.o ... |
12 | */ |
13 | |
14 | #define _GNU_SOURCE |
15 | #include <elf.h> |
16 | #include <fnmatch.h> |
17 | #include <stdio.h> |
18 | #include <ctype.h> |
19 | #include <string.h> |
20 | #include <limits.h> |
21 | #include <stdbool.h> |
22 | #include <errno.h> |
23 | #include "modpost.h" |
24 | #include "../../include/linux/license.h" |
25 | |
26 | static bool module_enabled; |
27 | /* Are we using CONFIG_MODVERSIONS? */ |
28 | static bool modversions; |
29 | /* Is CONFIG_MODULE_SRCVERSION_ALL set? */ |
30 | static bool all_versions; |
31 | /* If we are modposting external module set to 1 */ |
32 | static bool external_module; |
33 | /* Only warn about unresolved symbols */ |
34 | static bool warn_unresolved; |
35 | |
36 | static int sec_mismatch_count; |
37 | static bool sec_mismatch_warn_only = true; |
38 | /* Trim EXPORT_SYMBOLs that are unused by in-tree modules */ |
39 | static bool trim_unused_exports; |
40 | |
41 | /* ignore missing files */ |
42 | static bool ignore_missing_files; |
43 | /* If set to 1, only warn (instead of error) about missing ns imports */ |
44 | static bool allow_missing_ns_imports; |
45 | |
46 | static bool error_occurred; |
47 | |
48 | static bool ; |
49 | |
50 | /* |
51 | * Cut off the warnings when there are too many. This typically occurs when |
52 | * vmlinux is missing. ('make modules' without building vmlinux.) |
53 | */ |
54 | #define MAX_UNRESOLVED_REPORTS 10 |
55 | static unsigned int nr_unresolved; |
56 | |
57 | /* In kernel, this size is defined in linux/module.h; |
58 | * here we use Elf_Addr instead of long for covering cross-compile |
59 | */ |
60 | |
61 | #define MODULE_NAME_LEN (64 - sizeof(Elf_Addr)) |
62 | |
63 | void __attribute__((format(printf, 2, 3))) |
64 | modpost_log(enum loglevel loglevel, const char *fmt, ...) |
65 | { |
66 | va_list arglist; |
67 | |
68 | switch (loglevel) { |
69 | case LOG_WARN: |
70 | fprintf(stderr, format: "WARNING: " ); |
71 | break; |
72 | case LOG_ERROR: |
73 | fprintf(stderr, format: "ERROR: " ); |
74 | break; |
75 | case LOG_FATAL: |
76 | fprintf(stderr, format: "FATAL: " ); |
77 | break; |
78 | default: /* invalid loglevel, ignore */ |
79 | break; |
80 | } |
81 | |
82 | fprintf(stderr, format: "modpost: " ); |
83 | |
84 | va_start(arglist, fmt); |
85 | vfprintf(stderr, format: fmt, arg: arglist); |
86 | va_end(arglist); |
87 | |
88 | if (loglevel == LOG_FATAL) |
89 | exit(status: 1); |
90 | if (loglevel == LOG_ERROR) |
91 | error_occurred = true; |
92 | } |
93 | |
94 | static inline bool strends(const char *str, const char *postfix) |
95 | { |
96 | if (strlen(s: str) < strlen(s: postfix)) |
97 | return false; |
98 | |
99 | return strcmp(s1: str + strlen(s: str) - strlen(s: postfix), s2: postfix) == 0; |
100 | } |
101 | |
102 | void *do_nofail(void *ptr, const char *expr) |
103 | { |
104 | if (!ptr) |
105 | fatal("Memory allocation failure: %s.\n" , expr); |
106 | |
107 | return ptr; |
108 | } |
109 | |
110 | char *read_text_file(const char *filename) |
111 | { |
112 | struct stat st; |
113 | size_t nbytes; |
114 | int fd; |
115 | char *buf; |
116 | |
117 | fd = open(file: filename, O_RDONLY); |
118 | if (fd < 0) { |
119 | perror(s: filename); |
120 | exit(status: 1); |
121 | } |
122 | |
123 | if (fstat(fd: fd, buf: &st) < 0) { |
124 | perror(s: filename); |
125 | exit(status: 1); |
126 | } |
127 | |
128 | buf = NOFAIL(malloc(st.st_size + 1)); |
129 | |
130 | nbytes = st.st_size; |
131 | |
132 | while (nbytes) { |
133 | ssize_t bytes_read; |
134 | |
135 | bytes_read = read(fd: fd, buf: buf, nbytes: nbytes); |
136 | if (bytes_read < 0) { |
137 | perror(s: filename); |
138 | exit(status: 1); |
139 | } |
140 | |
141 | nbytes -= bytes_read; |
142 | } |
143 | buf[st.st_size] = '\0'; |
144 | |
145 | close(fd: fd); |
146 | |
147 | return buf; |
148 | } |
149 | |
150 | char *get_line(char **stringp) |
151 | { |
152 | char *orig = *stringp, *next; |
153 | |
154 | /* do not return the unwanted extra line at EOF */ |
155 | if (!orig || *orig == '\0') |
156 | return NULL; |
157 | |
158 | /* don't use strsep here, it is not available everywhere */ |
159 | next = strchr(s: orig, c: '\n'); |
160 | if (next) |
161 | *next++ = '\0'; |
162 | |
163 | *stringp = next; |
164 | |
165 | return orig; |
166 | } |
167 | |
168 | /* A list of all modules we processed */ |
169 | LIST_HEAD(modules); |
170 | |
171 | static struct module *find_module(const char *modname) |
172 | { |
173 | struct module *mod; |
174 | |
175 | list_for_each_entry(mod, &modules, list) { |
176 | if (strcmp(s1: mod->name, s2: modname) == 0) |
177 | return mod; |
178 | } |
179 | return NULL; |
180 | } |
181 | |
182 | static struct module *new_module(const char *name, size_t namelen) |
183 | { |
184 | struct module *mod; |
185 | |
186 | mod = NOFAIL(malloc(sizeof(*mod) + namelen + 1)); |
187 | memset(s: mod, c: 0, n: sizeof(*mod)); |
188 | |
189 | INIT_LIST_HEAD(list: &mod->exported_symbols); |
190 | INIT_LIST_HEAD(list: &mod->unresolved_symbols); |
191 | INIT_LIST_HEAD(list: &mod->missing_namespaces); |
192 | INIT_LIST_HEAD(list: &mod->imported_namespaces); |
193 | |
194 | memcpy(dest: mod->name, src: name, n: namelen); |
195 | mod->name[namelen] = '\0'; |
196 | mod->is_vmlinux = (strcmp(s1: mod->name, s2: "vmlinux" ) == 0); |
197 | |
198 | /* |
199 | * Set mod->is_gpl_compatible to true by default. If MODULE_LICENSE() |
200 | * is missing, do not check the use for EXPORT_SYMBOL_GPL() becasue |
201 | * modpost will exit wiht error anyway. |
202 | */ |
203 | mod->is_gpl_compatible = true; |
204 | |
205 | list_add_tail(new: &mod->list, head: &modules); |
206 | |
207 | return mod; |
208 | } |
209 | |
210 | /* A hash of all exported symbols, |
211 | * struct symbol is also used for lists of unresolved symbols */ |
212 | |
213 | #define SYMBOL_HASH_SIZE 1024 |
214 | |
215 | struct symbol { |
216 | struct symbol *next; |
217 | struct list_head list; /* link to module::exported_symbols or module::unresolved_symbols */ |
218 | struct module *module; |
219 | char *namespace; |
220 | unsigned int crc; |
221 | bool crc_valid; |
222 | bool weak; |
223 | bool is_func; |
224 | bool is_gpl_only; /* exported by EXPORT_SYMBOL_GPL */ |
225 | bool used; /* there exists a user of this symbol */ |
226 | char name[]; |
227 | }; |
228 | |
229 | static struct symbol *symbolhash[SYMBOL_HASH_SIZE]; |
230 | |
231 | /* This is based on the hash algorithm from gdbm, via tdb */ |
232 | static inline unsigned int tdb_hash(const char *name) |
233 | { |
234 | unsigned value; /* Used to compute the hash value. */ |
235 | unsigned i; /* Used to cycle through random values. */ |
236 | |
237 | /* Set the initial value from the key size. */ |
238 | for (value = 0x238F13AF * strlen(s: name), i = 0; name[i]; i++) |
239 | value = (value + (((unsigned char *)name)[i] << (i*5 % 24))); |
240 | |
241 | return (1103515243 * value + 12345); |
242 | } |
243 | |
244 | /** |
245 | * Allocate a new symbols for use in the hash of exported symbols or |
246 | * the list of unresolved symbols per module |
247 | **/ |
248 | static struct symbol *alloc_symbol(const char *name) |
249 | { |
250 | struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1)); |
251 | |
252 | memset(s: s, c: 0, n: sizeof(*s)); |
253 | strcpy(dest: s->name, src: name); |
254 | |
255 | return s; |
256 | } |
257 | |
258 | /* For the hash of exported symbols */ |
259 | static void hash_add_symbol(struct symbol *sym) |
260 | { |
261 | unsigned int hash; |
262 | |
263 | hash = tdb_hash(name: sym->name) % SYMBOL_HASH_SIZE; |
264 | sym->next = symbolhash[hash]; |
265 | symbolhash[hash] = sym; |
266 | } |
267 | |
268 | static void sym_add_unresolved(const char *name, struct module *mod, bool weak) |
269 | { |
270 | struct symbol *sym; |
271 | |
272 | sym = alloc_symbol(name); |
273 | sym->weak = weak; |
274 | |
275 | list_add_tail(new: &sym->list, head: &mod->unresolved_symbols); |
276 | } |
277 | |
278 | static struct symbol *sym_find_with_module(const char *name, struct module *mod) |
279 | { |
280 | struct symbol *s; |
281 | |
282 | /* For our purposes, .foo matches foo. PPC64 needs this. */ |
283 | if (name[0] == '.') |
284 | name++; |
285 | |
286 | for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s = s->next) { |
287 | if (strcmp(s1: s->name, s2: name) == 0 && (!mod || s->module == mod)) |
288 | return s; |
289 | } |
290 | return NULL; |
291 | } |
292 | |
293 | static struct symbol *find_symbol(const char *name) |
294 | { |
295 | return sym_find_with_module(name, NULL); |
296 | } |
297 | |
298 | struct namespace_list { |
299 | struct list_head list; |
300 | char namespace[]; |
301 | }; |
302 | |
303 | static bool contains_namespace(struct list_head *head, const char *namespace) |
304 | { |
305 | struct namespace_list *list; |
306 | |
307 | /* |
308 | * The default namespace is null string "", which is always implicitly |
309 | * contained. |
310 | */ |
311 | if (!namespace[0]) |
312 | return true; |
313 | |
314 | list_for_each_entry(list, head, list) { |
315 | if (!strcmp(s1: list->namespace, s2: namespace)) |
316 | return true; |
317 | } |
318 | |
319 | return false; |
320 | } |
321 | |
322 | static void add_namespace(struct list_head *head, const char *namespace) |
323 | { |
324 | struct namespace_list *ns_entry; |
325 | |
326 | if (!contains_namespace(head, namespace)) { |
327 | ns_entry = NOFAIL(malloc(sizeof(*ns_entry) + |
328 | strlen(namespace) + 1)); |
329 | strcpy(dest: ns_entry->namespace, src: namespace); |
330 | list_add_tail(new: &ns_entry->list, head); |
331 | } |
332 | } |
333 | |
334 | static void *sym_get_data_by_offset(const struct elf_info *info, |
335 | unsigned int secindex, unsigned long offset) |
336 | { |
337 | Elf_Shdr *sechdr = &info->sechdrs[secindex]; |
338 | |
339 | return (void *)info->hdr + sechdr->sh_offset + offset; |
340 | } |
341 | |
342 | void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym) |
343 | { |
344 | return sym_get_data_by_offset(info, secindex: get_secindex(info, sym), |
345 | offset: sym->st_value); |
346 | } |
347 | |
348 | static const char *sech_name(const struct elf_info *info, Elf_Shdr *sechdr) |
349 | { |
350 | return sym_get_data_by_offset(info, secindex: info->secindex_strings, |
351 | offset: sechdr->sh_name); |
352 | } |
353 | |
354 | static const char *sec_name(const struct elf_info *info, unsigned int secindex) |
355 | { |
356 | /* |
357 | * If sym->st_shndx is a special section index, there is no |
358 | * corresponding section header. |
359 | * Return "" if the index is out of range of info->sechdrs[] array. |
360 | */ |
361 | if (secindex >= info->num_sections) |
362 | return "" ; |
363 | |
364 | return sech_name(info, sechdr: &info->sechdrs[secindex]); |
365 | } |
366 | |
367 | #define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0) |
368 | |
369 | static struct symbol *sym_add_exported(const char *name, struct module *mod, |
370 | bool gpl_only, const char *namespace) |
371 | { |
372 | struct symbol *s = find_symbol(name); |
373 | |
374 | if (s && (!external_module || s->module->is_vmlinux || s->module == mod)) { |
375 | error("%s: '%s' exported twice. Previous export was in %s%s\n" , |
376 | mod->name, name, s->module->name, |
377 | s->module->is_vmlinux ? "" : ".ko" ); |
378 | } |
379 | |
380 | s = alloc_symbol(name); |
381 | s->module = mod; |
382 | s->is_gpl_only = gpl_only; |
383 | s->namespace = NOFAIL(strdup(namespace)); |
384 | list_add_tail(new: &s->list, head: &mod->exported_symbols); |
385 | hash_add_symbol(sym: s); |
386 | |
387 | return s; |
388 | } |
389 | |
390 | static void sym_set_crc(struct symbol *sym, unsigned int crc) |
391 | { |
392 | sym->crc = crc; |
393 | sym->crc_valid = true; |
394 | } |
395 | |
396 | static void *grab_file(const char *filename, size_t *size) |
397 | { |
398 | struct stat st; |
399 | void *map = MAP_FAILED; |
400 | int fd; |
401 | |
402 | fd = open(file: filename, O_RDONLY); |
403 | if (fd < 0) |
404 | return NULL; |
405 | if (fstat(fd: fd, buf: &st)) |
406 | goto failed; |
407 | |
408 | *size = st.st_size; |
409 | map = mmap(NULL, len: *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd: fd, offset: 0); |
410 | |
411 | failed: |
412 | close(fd: fd); |
413 | if (map == MAP_FAILED) |
414 | return NULL; |
415 | return map; |
416 | } |
417 | |
418 | static void release_file(void *file, size_t size) |
419 | { |
420 | munmap(addr: file, len: size); |
421 | } |
422 | |
423 | static int parse_elf(struct elf_info *info, const char *filename) |
424 | { |
425 | unsigned int i; |
426 | Elf_Ehdr *hdr; |
427 | Elf_Shdr *sechdrs; |
428 | Elf_Sym *sym; |
429 | const char *secstrings; |
430 | unsigned int symtab_idx = ~0U, symtab_shndx_idx = ~0U; |
431 | |
432 | hdr = grab_file(filename, size: &info->size); |
433 | if (!hdr) { |
434 | if (ignore_missing_files) { |
435 | fprintf(stderr, format: "%s: %s (ignored)\n" , filename, |
436 | strerror(errno)); |
437 | return 0; |
438 | } |
439 | perror(s: filename); |
440 | exit(status: 1); |
441 | } |
442 | info->hdr = hdr; |
443 | if (info->size < sizeof(*hdr)) { |
444 | /* file too small, assume this is an empty .o file */ |
445 | return 0; |
446 | } |
447 | /* Is this a valid ELF file? */ |
448 | if ((hdr->e_ident[EI_MAG0] != ELFMAG0) || |
449 | (hdr->e_ident[EI_MAG1] != ELFMAG1) || |
450 | (hdr->e_ident[EI_MAG2] != ELFMAG2) || |
451 | (hdr->e_ident[EI_MAG3] != ELFMAG3)) { |
452 | /* Not an ELF file - silently ignore it */ |
453 | return 0; |
454 | } |
455 | /* Fix endianness in ELF header */ |
456 | hdr->e_type = TO_NATIVE(hdr->e_type); |
457 | hdr->e_machine = TO_NATIVE(hdr->e_machine); |
458 | hdr->e_version = TO_NATIVE(hdr->e_version); |
459 | hdr->e_entry = TO_NATIVE(hdr->e_entry); |
460 | hdr->e_phoff = TO_NATIVE(hdr->e_phoff); |
461 | hdr->e_shoff = TO_NATIVE(hdr->e_shoff); |
462 | hdr->e_flags = TO_NATIVE(hdr->e_flags); |
463 | hdr->e_ehsize = TO_NATIVE(hdr->e_ehsize); |
464 | hdr->e_phentsize = TO_NATIVE(hdr->e_phentsize); |
465 | hdr->e_phnum = TO_NATIVE(hdr->e_phnum); |
466 | hdr->e_shentsize = TO_NATIVE(hdr->e_shentsize); |
467 | hdr->e_shnum = TO_NATIVE(hdr->e_shnum); |
468 | hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx); |
469 | sechdrs = (void *)hdr + hdr->e_shoff; |
470 | info->sechdrs = sechdrs; |
471 | |
472 | /* modpost only works for relocatable objects */ |
473 | if (hdr->e_type != ET_REL) |
474 | fatal("%s: not relocatable object." , filename); |
475 | |
476 | /* Check if file offset is correct */ |
477 | if (hdr->e_shoff > info->size) { |
478 | fatal("section header offset=%lu in file '%s' is bigger than filesize=%zu\n" , |
479 | (unsigned long)hdr->e_shoff, filename, info->size); |
480 | return 0; |
481 | } |
482 | |
483 | if (hdr->e_shnum == SHN_UNDEF) { |
484 | /* |
485 | * There are more than 64k sections, |
486 | * read count from .sh_size. |
487 | */ |
488 | info->num_sections = TO_NATIVE(sechdrs[0].sh_size); |
489 | } |
490 | else { |
491 | info->num_sections = hdr->e_shnum; |
492 | } |
493 | if (hdr->e_shstrndx == SHN_XINDEX) { |
494 | info->secindex_strings = TO_NATIVE(sechdrs[0].sh_link); |
495 | } |
496 | else { |
497 | info->secindex_strings = hdr->e_shstrndx; |
498 | } |
499 | |
500 | /* Fix endianness in section headers */ |
501 | for (i = 0; i < info->num_sections; i++) { |
502 | sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name); |
503 | sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type); |
504 | sechdrs[i].sh_flags = TO_NATIVE(sechdrs[i].sh_flags); |
505 | sechdrs[i].sh_addr = TO_NATIVE(sechdrs[i].sh_addr); |
506 | sechdrs[i].sh_offset = TO_NATIVE(sechdrs[i].sh_offset); |
507 | sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size); |
508 | sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link); |
509 | sechdrs[i].sh_info = TO_NATIVE(sechdrs[i].sh_info); |
510 | sechdrs[i].sh_addralign = TO_NATIVE(sechdrs[i].sh_addralign); |
511 | sechdrs[i].sh_entsize = TO_NATIVE(sechdrs[i].sh_entsize); |
512 | } |
513 | /* Find symbol table. */ |
514 | secstrings = (void *)hdr + sechdrs[info->secindex_strings].sh_offset; |
515 | for (i = 1; i < info->num_sections; i++) { |
516 | const char *secname; |
517 | int nobits = sechdrs[i].sh_type == SHT_NOBITS; |
518 | |
519 | if (!nobits && sechdrs[i].sh_offset > info->size) { |
520 | fatal("%s is truncated. sechdrs[i].sh_offset=%lu > sizeof(*hrd)=%zu\n" , |
521 | filename, (unsigned long)sechdrs[i].sh_offset, |
522 | sizeof(*hdr)); |
523 | return 0; |
524 | } |
525 | secname = secstrings + sechdrs[i].sh_name; |
526 | if (strcmp(s1: secname, s2: ".modinfo" ) == 0) { |
527 | if (nobits) |
528 | fatal("%s has NOBITS .modinfo\n" , filename); |
529 | info->modinfo = (void *)hdr + sechdrs[i].sh_offset; |
530 | info->modinfo_len = sechdrs[i].sh_size; |
531 | } else if (!strcmp(s1: secname, s2: ".export_symbol" )) { |
532 | info->export_symbol_secndx = i; |
533 | } |
534 | |
535 | if (sechdrs[i].sh_type == SHT_SYMTAB) { |
536 | unsigned int sh_link_idx; |
537 | symtab_idx = i; |
538 | info->symtab_start = (void *)hdr + |
539 | sechdrs[i].sh_offset; |
540 | info->symtab_stop = (void *)hdr + |
541 | sechdrs[i].sh_offset + sechdrs[i].sh_size; |
542 | sh_link_idx = sechdrs[i].sh_link; |
543 | info->strtab = (void *)hdr + |
544 | sechdrs[sh_link_idx].sh_offset; |
545 | } |
546 | |
547 | /* 32bit section no. table? ("more than 64k sections") */ |
548 | if (sechdrs[i].sh_type == SHT_SYMTAB_SHNDX) { |
549 | symtab_shndx_idx = i; |
550 | info->symtab_shndx_start = (void *)hdr + |
551 | sechdrs[i].sh_offset; |
552 | info->symtab_shndx_stop = (void *)hdr + |
553 | sechdrs[i].sh_offset + sechdrs[i].sh_size; |
554 | } |
555 | } |
556 | if (!info->symtab_start) |
557 | fatal("%s has no symtab?\n" , filename); |
558 | |
559 | /* Fix endianness in symbols */ |
560 | for (sym = info->symtab_start; sym < info->symtab_stop; sym++) { |
561 | sym->st_shndx = TO_NATIVE(sym->st_shndx); |
562 | sym->st_name = TO_NATIVE(sym->st_name); |
563 | sym->st_value = TO_NATIVE(sym->st_value); |
564 | sym->st_size = TO_NATIVE(sym->st_size); |
565 | } |
566 | |
567 | if (symtab_shndx_idx != ~0U) { |
568 | Elf32_Word *p; |
569 | if (symtab_idx != sechdrs[symtab_shndx_idx].sh_link) |
570 | fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n" , |
571 | filename, sechdrs[symtab_shndx_idx].sh_link, |
572 | symtab_idx); |
573 | /* Fix endianness */ |
574 | for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop; |
575 | p++) |
576 | *p = TO_NATIVE(*p); |
577 | } |
578 | |
579 | symsearch_init(elf: info); |
580 | |
581 | return 1; |
582 | } |
583 | |
584 | static void parse_elf_finish(struct elf_info *info) |
585 | { |
586 | symsearch_finish(elf: info); |
587 | release_file(file: info->hdr, size: info->size); |
588 | } |
589 | |
590 | static int ignore_undef_symbol(struct elf_info *info, const char *symname) |
591 | { |
592 | /* ignore __this_module, it will be resolved shortly */ |
593 | if (strcmp(s1: symname, s2: "__this_module" ) == 0) |
594 | return 1; |
595 | /* ignore global offset table */ |
596 | if (strcmp(s1: symname, s2: "_GLOBAL_OFFSET_TABLE_" ) == 0) |
597 | return 1; |
598 | if (info->hdr->e_machine == EM_PPC) |
599 | /* Special register function linked on all modules during final link of .ko */ |
600 | if (strstarts(symname, "_restgpr_" ) || |
601 | strstarts(symname, "_savegpr_" ) || |
602 | strstarts(symname, "_rest32gpr_" ) || |
603 | strstarts(symname, "_save32gpr_" ) || |
604 | strstarts(symname, "_restvr_" ) || |
605 | strstarts(symname, "_savevr_" )) |
606 | return 1; |
607 | if (info->hdr->e_machine == EM_PPC64) |
608 | /* Special register function linked on all modules during final link of .ko */ |
609 | if (strstarts(symname, "_restgpr0_" ) || |
610 | strstarts(symname, "_savegpr0_" ) || |
611 | strstarts(symname, "_restvr_" ) || |
612 | strstarts(symname, "_savevr_" ) || |
613 | strcmp(s1: symname, s2: ".TOC." ) == 0) |
614 | return 1; |
615 | |
616 | if (info->hdr->e_machine == EM_S390) |
617 | /* Expoline thunks are linked on all kernel modules during final link of .ko */ |
618 | if (strstarts(symname, "__s390_indirect_jump_r" )) |
619 | return 1; |
620 | /* Do not ignore this symbol */ |
621 | return 0; |
622 | } |
623 | |
624 | static void handle_symbol(struct module *mod, struct elf_info *info, |
625 | const Elf_Sym *sym, const char *symname) |
626 | { |
627 | switch (sym->st_shndx) { |
628 | case SHN_COMMON: |
629 | if (strstarts(symname, "__gnu_lto_" )) { |
630 | /* Should warn here, but modpost runs before the linker */ |
631 | } else |
632 | warn("\"%s\" [%s] is COMMON symbol\n" , symname, mod->name); |
633 | break; |
634 | case SHN_UNDEF: |
635 | /* undefined symbol */ |
636 | if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL && |
637 | ELF_ST_BIND(sym->st_info) != STB_WEAK) |
638 | break; |
639 | if (ignore_undef_symbol(info, symname)) |
640 | break; |
641 | if (info->hdr->e_machine == EM_SPARC || |
642 | info->hdr->e_machine == EM_SPARCV9) { |
643 | /* Ignore register directives. */ |
644 | if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER) |
645 | break; |
646 | if (symname[0] == '.') { |
647 | char *munged = NOFAIL(strdup(symname)); |
648 | munged[0] = '_'; |
649 | munged[1] = toupper(munged[1]); |
650 | symname = munged; |
651 | } |
652 | } |
653 | |
654 | sym_add_unresolved(name: symname, mod, |
655 | ELF_ST_BIND(sym->st_info) == STB_WEAK); |
656 | break; |
657 | default: |
658 | if (strcmp(s1: symname, s2: "init_module" ) == 0) |
659 | mod->has_init = true; |
660 | if (strcmp(s1: symname, s2: "cleanup_module" ) == 0) |
661 | mod->has_cleanup = true; |
662 | break; |
663 | } |
664 | } |
665 | |
666 | /** |
667 | * Parse tag=value strings from .modinfo section |
668 | **/ |
669 | static char *next_string(char *string, unsigned long *secsize) |
670 | { |
671 | /* Skip non-zero chars */ |
672 | while (string[0]) { |
673 | string++; |
674 | if ((*secsize)-- <= 1) |
675 | return NULL; |
676 | } |
677 | |
678 | /* Skip any zero padding. */ |
679 | while (!string[0]) { |
680 | string++; |
681 | if ((*secsize)-- <= 1) |
682 | return NULL; |
683 | } |
684 | return string; |
685 | } |
686 | |
687 | static char *get_next_modinfo(struct elf_info *info, const char *tag, |
688 | char *prev) |
689 | { |
690 | char *p; |
691 | unsigned int taglen = strlen(s: tag); |
692 | char *modinfo = info->modinfo; |
693 | unsigned long size = info->modinfo_len; |
694 | |
695 | if (prev) { |
696 | size -= prev - modinfo; |
697 | modinfo = next_string(string: prev, secsize: &size); |
698 | } |
699 | |
700 | for (p = modinfo; p; p = next_string(string: p, secsize: &size)) { |
701 | if (strncmp(s1: p, s2: tag, n: taglen) == 0 && p[taglen] == '=') |
702 | return p + taglen + 1; |
703 | } |
704 | return NULL; |
705 | } |
706 | |
707 | static char *get_modinfo(struct elf_info *info, const char *tag) |
708 | |
709 | { |
710 | return get_next_modinfo(info, tag, NULL); |
711 | } |
712 | |
713 | static const char *sym_name(struct elf_info *elf, Elf_Sym *sym) |
714 | { |
715 | if (sym) |
716 | return elf->strtab + sym->st_name; |
717 | else |
718 | return "(unknown)" ; |
719 | } |
720 | |
721 | /* |
722 | * Check whether the 'string' argument matches one of the 'patterns', |
723 | * an array of shell wildcard patterns (glob). |
724 | * |
725 | * Return true is there is a match. |
726 | */ |
727 | static bool match(const char *string, const char *const patterns[]) |
728 | { |
729 | const char *pattern; |
730 | |
731 | while ((pattern = *patterns++)) { |
732 | if (!fnmatch(pattern: pattern, name: string, flags: 0)) |
733 | return true; |
734 | } |
735 | |
736 | return false; |
737 | } |
738 | |
739 | /* useful to pass patterns to match() directly */ |
740 | #define PATTERNS(...) \ |
741 | ({ \ |
742 | static const char *const patterns[] = {__VA_ARGS__, NULL}; \ |
743 | patterns; \ |
744 | }) |
745 | |
746 | /* sections that we do not want to do full section mismatch check on */ |
747 | static const char *const section_white_list[] = |
748 | { |
749 | ".comment*" , |
750 | ".debug*" , |
751 | ".zdebug*" , /* Compressed debug sections. */ |
752 | ".GCC.command.line" , /* record-gcc-switches */ |
753 | ".mdebug*" , /* alpha, score, mips etc. */ |
754 | ".pdr" , /* alpha, score, mips etc. */ |
755 | ".stab*" , |
756 | ".note*" , |
757 | ".got*" , |
758 | ".toc*" , |
759 | ".xt.prop" , /* xtensa */ |
760 | ".xt.lit" , /* xtensa */ |
761 | ".arcextmap*" , /* arc */ |
762 | ".gnu.linkonce.arcext*" , /* arc : modules */ |
763 | ".cmem*" , /* EZchip */ |
764 | ".fmt_slot*" , /* EZchip */ |
765 | ".gnu.lto*" , |
766 | ".discard.*" , |
767 | ".llvm.call-graph-profile" , /* call graph */ |
768 | NULL |
769 | }; |
770 | |
771 | /* |
772 | * This is used to find sections missing the SHF_ALLOC flag. |
773 | * The cause of this is often a section specified in assembler |
774 | * without "ax" / "aw". |
775 | */ |
776 | static void check_section(const char *modname, struct elf_info *elf, |
777 | Elf_Shdr *sechdr) |
778 | { |
779 | const char *sec = sech_name(info: elf, sechdr); |
780 | |
781 | if (sechdr->sh_type == SHT_PROGBITS && |
782 | !(sechdr->sh_flags & SHF_ALLOC) && |
783 | !match(string: sec, patterns: section_white_list)) { |
784 | warn("%s (%s): unexpected non-allocatable section.\n" |
785 | "Did you forget to use \"ax\"/\"aw\" in a .S file?\n" |
786 | "Note that for example <linux/init.h> contains\n" |
787 | "section definitions for use in .S files.\n\n" , |
788 | modname, sec); |
789 | } |
790 | } |
791 | |
792 | |
793 | |
794 | #define ALL_INIT_DATA_SECTIONS \ |
795 | ".init.setup", ".init.rodata", ".meminit.rodata", \ |
796 | ".init.data", ".meminit.data" |
797 | |
798 | #define ALL_PCI_INIT_SECTIONS \ |
799 | ".pci_fixup_early", ".pci_fixup_header", ".pci_fixup_final", \ |
800 | ".pci_fixup_enable", ".pci_fixup_resume", \ |
801 | ".pci_fixup_resume_early", ".pci_fixup_suspend" |
802 | |
803 | #define ALL_XXXINIT_SECTIONS ".meminit.*" |
804 | |
805 | #define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS |
806 | #define ALL_EXIT_SECTIONS ".exit.*" |
807 | |
808 | #define DATA_SECTIONS ".data", ".data.rel" |
809 | #define TEXT_SECTIONS ".text", ".text.*", ".sched.text", \ |
810 | ".kprobes.text", ".cpuidle.text", ".noinstr.text" |
811 | #define OTHER_TEXT_SECTIONS ".ref.text", ".head.text", ".spinlock.text", \ |
812 | ".fixup", ".entry.text", ".exception.text", \ |
813 | ".coldtext", ".softirqentry.text" |
814 | |
815 | #define INIT_SECTIONS ".init.*" |
816 | |
817 | #define ALL_TEXT_SECTIONS ".init.text", ".meminit.text", ".exit.text", \ |
818 | TEXT_SECTIONS, OTHER_TEXT_SECTIONS |
819 | |
820 | enum mismatch { |
821 | TEXTDATA_TO_ANY_INIT_EXIT, |
822 | XXXINIT_TO_SOME_INIT, |
823 | ANY_INIT_TO_ANY_EXIT, |
824 | ANY_EXIT_TO_ANY_INIT, |
825 | EXTABLE_TO_NON_TEXT, |
826 | }; |
827 | |
828 | /** |
829 | * Describe how to match sections on different criteria: |
830 | * |
831 | * @fromsec: Array of sections to be matched. |
832 | * |
833 | * @bad_tosec: Relocations applied to a section in @fromsec to a section in |
834 | * this array is forbidden (black-list). Can be empty. |
835 | * |
836 | * @good_tosec: Relocations applied to a section in @fromsec must be |
837 | * targeting sections in this array (white-list). Can be empty. |
838 | * |
839 | * @mismatch: Type of mismatch. |
840 | */ |
841 | struct sectioncheck { |
842 | const char *fromsec[20]; |
843 | const char *bad_tosec[20]; |
844 | const char *good_tosec[20]; |
845 | enum mismatch mismatch; |
846 | }; |
847 | |
848 | static const struct sectioncheck sectioncheck[] = { |
849 | /* Do not reference init/exit code/data from |
850 | * normal code and data |
851 | */ |
852 | { |
853 | .fromsec = { TEXT_SECTIONS, DATA_SECTIONS, NULL }, |
854 | .bad_tosec = { ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL }, |
855 | .mismatch = TEXTDATA_TO_ANY_INIT_EXIT, |
856 | }, |
857 | /* Do not reference init code/data from meminit code/data */ |
858 | { |
859 | .fromsec = { ALL_XXXINIT_SECTIONS, NULL }, |
860 | .bad_tosec = { INIT_SECTIONS, NULL }, |
861 | .mismatch = XXXINIT_TO_SOME_INIT, |
862 | }, |
863 | /* Do not use exit code/data from init code */ |
864 | { |
865 | .fromsec = { ALL_INIT_SECTIONS, NULL }, |
866 | .bad_tosec = { ALL_EXIT_SECTIONS, NULL }, |
867 | .mismatch = ANY_INIT_TO_ANY_EXIT, |
868 | }, |
869 | /* Do not use init code/data from exit code */ |
870 | { |
871 | .fromsec = { ALL_EXIT_SECTIONS, NULL }, |
872 | .bad_tosec = { ALL_INIT_SECTIONS, NULL }, |
873 | .mismatch = ANY_EXIT_TO_ANY_INIT, |
874 | }, |
875 | { |
876 | .fromsec = { ALL_PCI_INIT_SECTIONS, NULL }, |
877 | .bad_tosec = { INIT_SECTIONS, NULL }, |
878 | .mismatch = ANY_INIT_TO_ANY_EXIT, |
879 | }, |
880 | { |
881 | .fromsec = { "__ex_table" , NULL }, |
882 | /* If you're adding any new black-listed sections in here, consider |
883 | * adding a special 'printer' for them in scripts/check_extable. |
884 | */ |
885 | .bad_tosec = { ".altinstr_replacement" , NULL }, |
886 | .good_tosec = {ALL_TEXT_SECTIONS , NULL}, |
887 | .mismatch = EXTABLE_TO_NON_TEXT, |
888 | } |
889 | }; |
890 | |
891 | static const struct sectioncheck *section_mismatch( |
892 | const char *fromsec, const char *tosec) |
893 | { |
894 | int i; |
895 | |
896 | /* |
897 | * The target section could be the SHT_NUL section when we're |
898 | * handling relocations to un-resolved symbols, trying to match it |
899 | * doesn't make much sense and causes build failures on parisc |
900 | * architectures. |
901 | */ |
902 | if (*tosec == '\0') |
903 | return NULL; |
904 | |
905 | for (i = 0; i < ARRAY_SIZE(sectioncheck); i++) { |
906 | const struct sectioncheck *check = §ioncheck[i]; |
907 | |
908 | if (match(string: fromsec, patterns: check->fromsec)) { |
909 | if (check->bad_tosec[0] && match(string: tosec, patterns: check->bad_tosec)) |
910 | return check; |
911 | if (check->good_tosec[0] && !match(string: tosec, patterns: check->good_tosec)) |
912 | return check; |
913 | } |
914 | } |
915 | return NULL; |
916 | } |
917 | |
918 | /** |
919 | * Whitelist to allow certain references to pass with no warning. |
920 | * |
921 | * Pattern 1: |
922 | * If a module parameter is declared __initdata and permissions=0 |
923 | * then this is legal despite the warning generated. |
924 | * We cannot see value of permissions here, so just ignore |
925 | * this pattern. |
926 | * The pattern is identified by: |
927 | * tosec = .init.data |
928 | * fromsec = .data* |
929 | * atsym =__param* |
930 | * |
931 | * Pattern 1a: |
932 | * module_param_call() ops can refer to __init set function if permissions=0 |
933 | * The pattern is identified by: |
934 | * tosec = .init.text |
935 | * fromsec = .data* |
936 | * atsym = __param_ops_* |
937 | * |
938 | * Pattern 3: |
939 | * Whitelist all references from .head.text to any init section |
940 | * |
941 | * Pattern 4: |
942 | * Some symbols belong to init section but still it is ok to reference |
943 | * these from non-init sections as these symbols don't have any memory |
944 | * allocated for them and symbol address and value are same. So even |
945 | * if init section is freed, its ok to reference those symbols. |
946 | * For ex. symbols marking the init section boundaries. |
947 | * This pattern is identified by |
948 | * refsymname = __init_begin, _sinittext, _einittext |
949 | * |
950 | * Pattern 5: |
951 | * GCC may optimize static inlines when fed constant arg(s) resulting |
952 | * in functions like cpumask_empty() -- generating an associated symbol |
953 | * cpumask_empty.constprop.3 that appears in the audit. If the const that |
954 | * is passed in comes from __init, like say nmi_ipi_mask, we get a |
955 | * meaningless section warning. May need to add isra symbols too... |
956 | * This pattern is identified by |
957 | * tosec = init section |
958 | * fromsec = text section |
959 | * refsymname = *.constprop.* |
960 | * |
961 | **/ |
962 | static int secref_whitelist(const char *fromsec, const char *fromsym, |
963 | const char *tosec, const char *tosym) |
964 | { |
965 | /* Check for pattern 1 */ |
966 | if (match(string: tosec, PATTERNS(ALL_INIT_DATA_SECTIONS)) && |
967 | match(string: fromsec, PATTERNS(DATA_SECTIONS)) && |
968 | strstarts(fromsym, "__param" )) |
969 | return 0; |
970 | |
971 | /* Check for pattern 1a */ |
972 | if (strcmp(s1: tosec, s2: ".init.text" ) == 0 && |
973 | match(string: fromsec, PATTERNS(DATA_SECTIONS)) && |
974 | strstarts(fromsym, "__param_ops_" )) |
975 | return 0; |
976 | |
977 | /* symbols in data sections that may refer to any init/exit sections */ |
978 | if (match(string: fromsec, PATTERNS(DATA_SECTIONS)) && |
979 | match(string: tosec, PATTERNS(ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS)) && |
980 | match(string: fromsym, PATTERNS("*_ops" , "*_probe" , "*_console" ))) |
981 | return 0; |
982 | |
983 | /* |
984 | * symbols in data sections must not refer to .exit.*, but there are |
985 | * quite a few offenders, so hide these unless for W=1 builds until |
986 | * these are fixed. |
987 | */ |
988 | if (!extra_warn && |
989 | match(string: fromsec, PATTERNS(DATA_SECTIONS)) && |
990 | match(string: tosec, PATTERNS(ALL_EXIT_SECTIONS)) && |
991 | match(string: fromsym, PATTERNS("*driver" ))) |
992 | return 0; |
993 | |
994 | /* Check for pattern 3 */ |
995 | if (strstarts(fromsec, ".head.text" ) && |
996 | match(string: tosec, PATTERNS(ALL_INIT_SECTIONS))) |
997 | return 0; |
998 | |
999 | /* Check for pattern 4 */ |
1000 | if (match(string: tosym, PATTERNS("__init_begin" , "_sinittext" , "_einittext" ))) |
1001 | return 0; |
1002 | |
1003 | /* Check for pattern 5 */ |
1004 | if (match(string: fromsec, PATTERNS(ALL_TEXT_SECTIONS)) && |
1005 | match(string: tosec, PATTERNS(ALL_INIT_SECTIONS)) && |
1006 | match(string: fromsym, PATTERNS("*.constprop.*" ))) |
1007 | return 0; |
1008 | |
1009 | return 1; |
1010 | } |
1011 | |
1012 | static Elf_Sym *find_fromsym(struct elf_info *elf, Elf_Addr addr, |
1013 | unsigned int secndx) |
1014 | { |
1015 | return symsearch_find_nearest(elf, addr, secndx, false, min_distance: ~0); |
1016 | } |
1017 | |
1018 | static Elf_Sym *find_tosym(struct elf_info *elf, Elf_Addr addr, Elf_Sym *sym) |
1019 | { |
1020 | /* If the supplied symbol has a valid name, return it */ |
1021 | if (is_valid_name(elf, sym)) |
1022 | return sym; |
1023 | |
1024 | /* |
1025 | * Strive to find a better symbol name, but the resulting name may not |
1026 | * match the symbol referenced in the original code. |
1027 | */ |
1028 | return symsearch_find_nearest(elf, addr, secndx: get_secindex(info: elf, sym), |
1029 | true, min_distance: 20); |
1030 | } |
1031 | |
1032 | static bool is_executable_section(struct elf_info *elf, unsigned int secndx) |
1033 | { |
1034 | if (secndx >= elf->num_sections) |
1035 | return false; |
1036 | |
1037 | return (elf->sechdrs[secndx].sh_flags & SHF_EXECINSTR) != 0; |
1038 | } |
1039 | |
1040 | static void default_mismatch_handler(const char *modname, struct elf_info *elf, |
1041 | const struct sectioncheck* const mismatch, |
1042 | Elf_Sym *tsym, |
1043 | unsigned int fsecndx, const char *fromsec, Elf_Addr faddr, |
1044 | const char *tosec, Elf_Addr taddr) |
1045 | { |
1046 | Elf_Sym *from; |
1047 | const char *tosym; |
1048 | const char *fromsym; |
1049 | |
1050 | from = find_fromsym(elf, addr: faddr, secndx: fsecndx); |
1051 | fromsym = sym_name(elf, sym: from); |
1052 | |
1053 | tsym = find_tosym(elf, addr: taddr, sym: tsym); |
1054 | tosym = sym_name(elf, sym: tsym); |
1055 | |
1056 | /* check whitelist - we may ignore it */ |
1057 | if (!secref_whitelist(fromsec, fromsym, tosec, tosym)) |
1058 | return; |
1059 | |
1060 | sec_mismatch_count++; |
1061 | |
1062 | warn("%s: section mismatch in reference: %s+0x%x (section: %s) -> %s (section: %s)\n" , |
1063 | modname, fromsym, (unsigned int)(faddr - from->st_value), fromsec, tosym, tosec); |
1064 | |
1065 | if (mismatch->mismatch == EXTABLE_TO_NON_TEXT) { |
1066 | if (match(string: tosec, patterns: mismatch->bad_tosec)) |
1067 | fatal("The relocation at %s+0x%lx references\n" |
1068 | "section \"%s\" which is black-listed.\n" |
1069 | "Something is seriously wrong and should be fixed.\n" |
1070 | "You might get more information about where this is\n" |
1071 | "coming from by using scripts/check_extable.sh %s\n" , |
1072 | fromsec, (long)faddr, tosec, modname); |
1073 | else if (is_executable_section(elf, secndx: get_secindex(info: elf, sym: tsym))) |
1074 | warn("The relocation at %s+0x%lx references\n" |
1075 | "section \"%s\" which is not in the list of\n" |
1076 | "authorized sections. If you're adding a new section\n" |
1077 | "and/or if this reference is valid, add \"%s\" to the\n" |
1078 | "list of authorized sections to jump to on fault.\n" |
1079 | "This can be achieved by adding \"%s\" to\n" |
1080 | "OTHER_TEXT_SECTIONS in scripts/mod/modpost.c.\n" , |
1081 | fromsec, (long)faddr, tosec, tosec, tosec); |
1082 | else |
1083 | error("%s+0x%lx references non-executable section '%s'\n" , |
1084 | fromsec, (long)faddr, tosec); |
1085 | } |
1086 | } |
1087 | |
1088 | static void check_export_symbol(struct module *mod, struct elf_info *elf, |
1089 | Elf_Addr faddr, const char *secname, |
1090 | Elf_Sym *sym) |
1091 | { |
1092 | static const char *prefix = "__export_symbol_" ; |
1093 | const char *label_name, *name, *data; |
1094 | Elf_Sym *label; |
1095 | struct symbol *s; |
1096 | bool is_gpl; |
1097 | |
1098 | label = find_fromsym(elf, addr: faddr, secndx: elf->export_symbol_secndx); |
1099 | label_name = sym_name(elf, sym: label); |
1100 | |
1101 | if (!strstarts(label_name, prefix)) { |
1102 | error("%s: .export_symbol section contains strange symbol '%s'\n" , |
1103 | mod->name, label_name); |
1104 | return; |
1105 | } |
1106 | |
1107 | if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL && |
1108 | ELF_ST_BIND(sym->st_info) != STB_WEAK) { |
1109 | error("%s: local symbol '%s' was exported\n" , mod->name, |
1110 | label_name + strlen(prefix)); |
1111 | return; |
1112 | } |
1113 | |
1114 | name = sym_name(elf, sym); |
1115 | if (strcmp(s1: label_name + strlen(s: prefix), s2: name)) { |
1116 | error("%s: .export_symbol section references '%s', but it does not seem to be an export symbol\n" , |
1117 | mod->name, name); |
1118 | return; |
1119 | } |
1120 | |
1121 | data = sym_get_data(info: elf, sym: label); /* license */ |
1122 | if (!strcmp(s1: data, s2: "GPL" )) { |
1123 | is_gpl = true; |
1124 | } else if (!strcmp(s1: data, s2: "" )) { |
1125 | is_gpl = false; |
1126 | } else { |
1127 | error("%s: unknown license '%s' was specified for '%s'\n" , |
1128 | mod->name, data, name); |
1129 | return; |
1130 | } |
1131 | |
1132 | data += strlen(s: data) + 1; /* namespace */ |
1133 | s = sym_add_exported(name, mod, gpl_only: is_gpl, namespace: data); |
1134 | |
1135 | /* |
1136 | * We need to be aware whether we are exporting a function or |
1137 | * a data on some architectures. |
1138 | */ |
1139 | s->is_func = (ELF_ST_TYPE(sym->st_info) == STT_FUNC); |
1140 | |
1141 | /* |
1142 | * For parisc64, symbols prefixed $$ from the library have the symbol type |
1143 | * STT_LOPROC. They should be handled as functions too. |
1144 | */ |
1145 | if (elf->hdr->e_ident[EI_CLASS] == ELFCLASS64 && |
1146 | elf->hdr->e_machine == EM_PARISC && |
1147 | ELF_ST_TYPE(sym->st_info) == STT_LOPROC) |
1148 | s->is_func = true; |
1149 | |
1150 | if (match(string: secname, PATTERNS(ALL_INIT_SECTIONS))) |
1151 | warn("%s: %s: EXPORT_SYMBOL used for init symbol. Remove __init or EXPORT_SYMBOL.\n" , |
1152 | mod->name, name); |
1153 | else if (match(string: secname, PATTERNS(ALL_EXIT_SECTIONS))) |
1154 | warn("%s: %s: EXPORT_SYMBOL used for exit symbol. Remove __exit or EXPORT_SYMBOL.\n" , |
1155 | mod->name, name); |
1156 | } |
1157 | |
1158 | static void check_section_mismatch(struct module *mod, struct elf_info *elf, |
1159 | Elf_Sym *sym, |
1160 | unsigned int fsecndx, const char *fromsec, |
1161 | Elf_Addr faddr, Elf_Addr taddr) |
1162 | { |
1163 | const char *tosec = sec_name(info: elf, secindex: get_secindex(info: elf, sym)); |
1164 | const struct sectioncheck *mismatch; |
1165 | |
1166 | if (module_enabled && elf->export_symbol_secndx == fsecndx) { |
1167 | check_export_symbol(mod, elf, faddr, secname: tosec, sym); |
1168 | return; |
1169 | } |
1170 | |
1171 | mismatch = section_mismatch(fromsec, tosec); |
1172 | if (!mismatch) |
1173 | return; |
1174 | |
1175 | default_mismatch_handler(modname: mod->name, elf, mismatch, tsym: sym, |
1176 | fsecndx, fromsec, faddr, |
1177 | tosec, taddr); |
1178 | } |
1179 | |
1180 | static Elf_Addr addend_386_rel(uint32_t *location, unsigned int r_type) |
1181 | { |
1182 | switch (r_type) { |
1183 | case R_386_32: |
1184 | return TO_NATIVE(*location); |
1185 | case R_386_PC32: |
1186 | return TO_NATIVE(*location) + 4; |
1187 | } |
1188 | |
1189 | return (Elf_Addr)(-1); |
1190 | } |
1191 | |
1192 | #ifndef R_ARM_CALL |
1193 | #define R_ARM_CALL 28 |
1194 | #endif |
1195 | #ifndef R_ARM_JUMP24 |
1196 | #define R_ARM_JUMP24 29 |
1197 | #endif |
1198 | |
1199 | #ifndef R_ARM_THM_CALL |
1200 | #define R_ARM_THM_CALL 10 |
1201 | #endif |
1202 | #ifndef R_ARM_THM_JUMP24 |
1203 | #define R_ARM_THM_JUMP24 30 |
1204 | #endif |
1205 | |
1206 | #ifndef R_ARM_MOVW_ABS_NC |
1207 | #define R_ARM_MOVW_ABS_NC 43 |
1208 | #endif |
1209 | |
1210 | #ifndef R_ARM_MOVT_ABS |
1211 | #define R_ARM_MOVT_ABS 44 |
1212 | #endif |
1213 | |
1214 | #ifndef R_ARM_THM_MOVW_ABS_NC |
1215 | #define R_ARM_THM_MOVW_ABS_NC 47 |
1216 | #endif |
1217 | |
1218 | #ifndef R_ARM_THM_MOVT_ABS |
1219 | #define R_ARM_THM_MOVT_ABS 48 |
1220 | #endif |
1221 | |
1222 | #ifndef R_ARM_THM_JUMP19 |
1223 | #define R_ARM_THM_JUMP19 51 |
1224 | #endif |
1225 | |
1226 | static int32_t sign_extend32(int32_t value, int index) |
1227 | { |
1228 | uint8_t shift = 31 - index; |
1229 | |
1230 | return (int32_t)(value << shift) >> shift; |
1231 | } |
1232 | |
1233 | static Elf_Addr addend_arm_rel(void *loc, Elf_Sym *sym, unsigned int r_type) |
1234 | { |
1235 | uint32_t inst, upper, lower, sign, j1, j2; |
1236 | int32_t offset; |
1237 | |
1238 | switch (r_type) { |
1239 | case R_ARM_ABS32: |
1240 | case R_ARM_REL32: |
1241 | inst = TO_NATIVE(*(uint32_t *)loc); |
1242 | return inst + sym->st_value; |
1243 | case R_ARM_MOVW_ABS_NC: |
1244 | case R_ARM_MOVT_ABS: |
1245 | inst = TO_NATIVE(*(uint32_t *)loc); |
1246 | offset = sign_extend32(value: ((inst & 0xf0000) >> 4) | (inst & 0xfff), |
1247 | index: 15); |
1248 | return offset + sym->st_value; |
1249 | case R_ARM_PC24: |
1250 | case R_ARM_CALL: |
1251 | case R_ARM_JUMP24: |
1252 | inst = TO_NATIVE(*(uint32_t *)loc); |
1253 | offset = sign_extend32(value: (inst & 0x00ffffff) << 2, index: 25); |
1254 | return offset + sym->st_value + 8; |
1255 | case R_ARM_THM_MOVW_ABS_NC: |
1256 | case R_ARM_THM_MOVT_ABS: |
1257 | upper = TO_NATIVE(*(uint16_t *)loc); |
1258 | lower = TO_NATIVE(*((uint16_t *)loc + 1)); |
1259 | offset = sign_extend32(value: ((upper & 0x000f) << 12) | |
1260 | ((upper & 0x0400) << 1) | |
1261 | ((lower & 0x7000) >> 4) | |
1262 | (lower & 0x00ff), |
1263 | index: 15); |
1264 | return offset + sym->st_value; |
1265 | case R_ARM_THM_JUMP19: |
1266 | /* |
1267 | * Encoding T3: |
1268 | * S = upper[10] |
1269 | * imm6 = upper[5:0] |
1270 | * J1 = lower[13] |
1271 | * J2 = lower[11] |
1272 | * imm11 = lower[10:0] |
1273 | * imm32 = SignExtend(S:J2:J1:imm6:imm11:'0') |
1274 | */ |
1275 | upper = TO_NATIVE(*(uint16_t *)loc); |
1276 | lower = TO_NATIVE(*((uint16_t *)loc + 1)); |
1277 | |
1278 | sign = (upper >> 10) & 1; |
1279 | j1 = (lower >> 13) & 1; |
1280 | j2 = (lower >> 11) & 1; |
1281 | offset = sign_extend32(value: (sign << 20) | (j2 << 19) | (j1 << 18) | |
1282 | ((upper & 0x03f) << 12) | |
1283 | ((lower & 0x07ff) << 1), |
1284 | index: 20); |
1285 | return offset + sym->st_value + 4; |
1286 | case R_ARM_THM_CALL: |
1287 | case R_ARM_THM_JUMP24: |
1288 | /* |
1289 | * Encoding T4: |
1290 | * S = upper[10] |
1291 | * imm10 = upper[9:0] |
1292 | * J1 = lower[13] |
1293 | * J2 = lower[11] |
1294 | * imm11 = lower[10:0] |
1295 | * I1 = NOT(J1 XOR S) |
1296 | * I2 = NOT(J2 XOR S) |
1297 | * imm32 = SignExtend(S:I1:I2:imm10:imm11:'0') |
1298 | */ |
1299 | upper = TO_NATIVE(*(uint16_t *)loc); |
1300 | lower = TO_NATIVE(*((uint16_t *)loc + 1)); |
1301 | |
1302 | sign = (upper >> 10) & 1; |
1303 | j1 = (lower >> 13) & 1; |
1304 | j2 = (lower >> 11) & 1; |
1305 | offset = sign_extend32(value: (sign << 24) | |
1306 | ((~(j1 ^ sign) & 1) << 23) | |
1307 | ((~(j2 ^ sign) & 1) << 22) | |
1308 | ((upper & 0x03ff) << 12) | |
1309 | ((lower & 0x07ff) << 1), |
1310 | index: 24); |
1311 | return offset + sym->st_value + 4; |
1312 | } |
1313 | |
1314 | return (Elf_Addr)(-1); |
1315 | } |
1316 | |
1317 | static Elf_Addr addend_mips_rel(uint32_t *location, unsigned int r_type) |
1318 | { |
1319 | uint32_t inst; |
1320 | |
1321 | inst = TO_NATIVE(*location); |
1322 | switch (r_type) { |
1323 | case R_MIPS_LO16: |
1324 | return inst & 0xffff; |
1325 | case R_MIPS_26: |
1326 | return (inst & 0x03ffffff) << 2; |
1327 | case R_MIPS_32: |
1328 | return inst; |
1329 | } |
1330 | return (Elf_Addr)(-1); |
1331 | } |
1332 | |
1333 | #ifndef EM_RISCV |
1334 | #define EM_RISCV 243 |
1335 | #endif |
1336 | |
1337 | #ifndef R_RISCV_SUB32 |
1338 | #define R_RISCV_SUB32 39 |
1339 | #endif |
1340 | |
1341 | #ifndef EM_LOONGARCH |
1342 | #define EM_LOONGARCH 258 |
1343 | #endif |
1344 | |
1345 | #ifndef R_LARCH_SUB32 |
1346 | #define R_LARCH_SUB32 55 |
1347 | #endif |
1348 | |
1349 | static void get_rel_type_and_sym(struct elf_info *elf, uint64_t r_info, |
1350 | unsigned int *r_type, unsigned int *r_sym) |
1351 | { |
1352 | typedef struct { |
1353 | Elf64_Word r_sym; /* Symbol index */ |
1354 | unsigned char r_ssym; /* Special symbol for 2nd relocation */ |
1355 | unsigned char r_type3; /* 3rd relocation type */ |
1356 | unsigned char r_type2; /* 2nd relocation type */ |
1357 | unsigned char r_type; /* 1st relocation type */ |
1358 | } Elf64_Mips_R_Info; |
1359 | |
1360 | bool is_64bit = (elf->hdr->e_ident[EI_CLASS] == ELFCLASS64); |
1361 | |
1362 | if (elf->hdr->e_machine == EM_MIPS && is_64bit) { |
1363 | Elf64_Mips_R_Info *mips64_r_info = (void *)&r_info; |
1364 | |
1365 | *r_type = mips64_r_info->r_type; |
1366 | *r_sym = TO_NATIVE(mips64_r_info->r_sym); |
1367 | return; |
1368 | } |
1369 | |
1370 | if (is_64bit) |
1371 | r_info = TO_NATIVE((Elf64_Xword)r_info); |
1372 | else |
1373 | r_info = TO_NATIVE((Elf32_Word)r_info); |
1374 | |
1375 | *r_type = ELF_R_TYPE(r_info); |
1376 | *r_sym = ELF_R_SYM(r_info); |
1377 | } |
1378 | |
1379 | static void section_rela(struct module *mod, struct elf_info *elf, |
1380 | unsigned int fsecndx, const char *fromsec, |
1381 | const Elf_Rela *start, const Elf_Rela *stop) |
1382 | { |
1383 | const Elf_Rela *rela; |
1384 | |
1385 | for (rela = start; rela < stop; rela++) { |
1386 | Elf_Addr taddr, r_offset; |
1387 | unsigned int r_type, r_sym; |
1388 | |
1389 | r_offset = TO_NATIVE(rela->r_offset); |
1390 | get_rel_type_and_sym(elf, r_info: rela->r_info, r_type: &r_type, r_sym: &r_sym); |
1391 | |
1392 | taddr = TO_NATIVE(rela->r_addend); |
1393 | |
1394 | switch (elf->hdr->e_machine) { |
1395 | case EM_RISCV: |
1396 | if (!strcmp(s1: "__ex_table" , s2: fromsec) && |
1397 | r_type == R_RISCV_SUB32) |
1398 | continue; |
1399 | break; |
1400 | case EM_LOONGARCH: |
1401 | if (!strcmp(s1: "__ex_table" , s2: fromsec) && |
1402 | r_type == R_LARCH_SUB32) |
1403 | continue; |
1404 | break; |
1405 | } |
1406 | |
1407 | check_section_mismatch(mod, elf, sym: elf->symtab_start + r_sym, |
1408 | fsecndx, fromsec, faddr: r_offset, taddr); |
1409 | } |
1410 | } |
1411 | |
1412 | static void section_rel(struct module *mod, struct elf_info *elf, |
1413 | unsigned int fsecndx, const char *fromsec, |
1414 | const Elf_Rel *start, const Elf_Rel *stop) |
1415 | { |
1416 | const Elf_Rel *rel; |
1417 | |
1418 | for (rel = start; rel < stop; rel++) { |
1419 | Elf_Sym *tsym; |
1420 | Elf_Addr taddr = 0, r_offset; |
1421 | unsigned int r_type, r_sym; |
1422 | void *loc; |
1423 | |
1424 | r_offset = TO_NATIVE(rel->r_offset); |
1425 | get_rel_type_and_sym(elf, r_info: rel->r_info, r_type: &r_type, r_sym: &r_sym); |
1426 | |
1427 | loc = sym_get_data_by_offset(info: elf, secindex: fsecndx, offset: r_offset); |
1428 | tsym = elf->symtab_start + r_sym; |
1429 | |
1430 | switch (elf->hdr->e_machine) { |
1431 | case EM_386: |
1432 | taddr = addend_386_rel(location: loc, r_type); |
1433 | break; |
1434 | case EM_ARM: |
1435 | taddr = addend_arm_rel(loc, sym: tsym, r_type); |
1436 | break; |
1437 | case EM_MIPS: |
1438 | taddr = addend_mips_rel(location: loc, r_type); |
1439 | break; |
1440 | default: |
1441 | fatal("Please add code to calculate addend for this architecture\n" ); |
1442 | } |
1443 | |
1444 | check_section_mismatch(mod, elf, sym: tsym, |
1445 | fsecndx, fromsec, faddr: r_offset, taddr); |
1446 | } |
1447 | } |
1448 | |
1449 | /** |
1450 | * A module includes a number of sections that are discarded |
1451 | * either when loaded or when used as built-in. |
1452 | * For loaded modules all functions marked __init and all data |
1453 | * marked __initdata will be discarded when the module has been initialized. |
1454 | * Likewise for modules used built-in the sections marked __exit |
1455 | * are discarded because __exit marked function are supposed to be called |
1456 | * only when a module is unloaded which never happens for built-in modules. |
1457 | * The check_sec_ref() function traverses all relocation records |
1458 | * to find all references to a section that reference a section that will |
1459 | * be discarded and warns about it. |
1460 | **/ |
1461 | static void check_sec_ref(struct module *mod, struct elf_info *elf) |
1462 | { |
1463 | int i; |
1464 | |
1465 | /* Walk through all sections */ |
1466 | for (i = 0; i < elf->num_sections; i++) { |
1467 | Elf_Shdr *sechdr = &elf->sechdrs[i]; |
1468 | |
1469 | check_section(modname: mod->name, elf, sechdr); |
1470 | /* We want to process only relocation sections and not .init */ |
1471 | if (sechdr->sh_type == SHT_REL || sechdr->sh_type == SHT_RELA) { |
1472 | /* section to which the relocation applies */ |
1473 | unsigned int secndx = sechdr->sh_info; |
1474 | const char *secname = sec_name(info: elf, secindex: secndx); |
1475 | const void *start, *stop; |
1476 | |
1477 | /* If the section is known good, skip it */ |
1478 | if (match(string: secname, patterns: section_white_list)) |
1479 | continue; |
1480 | |
1481 | start = sym_get_data_by_offset(info: elf, secindex: i, offset: 0); |
1482 | stop = start + sechdr->sh_size; |
1483 | |
1484 | if (sechdr->sh_type == SHT_RELA) |
1485 | section_rela(mod, elf, fsecndx: secndx, fromsec: secname, |
1486 | start, stop); |
1487 | else |
1488 | section_rel(mod, elf, fsecndx: secndx, fromsec: secname, |
1489 | start, stop); |
1490 | } |
1491 | } |
1492 | } |
1493 | |
1494 | static char *remove_dot(char *s) |
1495 | { |
1496 | size_t n = strcspn(s: s, reject: "." ); |
1497 | |
1498 | if (n && s[n]) { |
1499 | size_t m = strspn(s: s + n + 1, accept: "0123456789" ); |
1500 | if (m && (s[n + m + 1] == '.' || s[n + m + 1] == 0)) |
1501 | s[n] = 0; |
1502 | } |
1503 | return s; |
1504 | } |
1505 | |
1506 | /* |
1507 | * The CRCs are recorded in .*.cmd files in the form of: |
1508 | * #SYMVER <name> <crc> |
1509 | */ |
1510 | static void (const char *object, struct module *mod) |
1511 | { |
1512 | char cmd_file[PATH_MAX]; |
1513 | char *buf, *p; |
1514 | const char *base; |
1515 | int dirlen, ret; |
1516 | |
1517 | base = strrchr(s: object, c: '/'); |
1518 | if (base) { |
1519 | base++; |
1520 | dirlen = base - object; |
1521 | } else { |
1522 | dirlen = 0; |
1523 | base = object; |
1524 | } |
1525 | |
1526 | ret = snprintf(s: cmd_file, maxlen: sizeof(cmd_file), format: "%.*s.%s.cmd" , |
1527 | dirlen, object, base); |
1528 | if (ret >= sizeof(cmd_file)) { |
1529 | error("%s: too long path was truncated\n" , cmd_file); |
1530 | return; |
1531 | } |
1532 | |
1533 | buf = read_text_file(filename: cmd_file); |
1534 | p = buf; |
1535 | |
1536 | while ((p = strstr(haystack: p, needle: "\n#SYMVER " ))) { |
1537 | char *name; |
1538 | size_t namelen; |
1539 | unsigned int crc; |
1540 | struct symbol *sym; |
1541 | |
1542 | name = p + strlen(s: "\n#SYMVER " ); |
1543 | |
1544 | p = strchr(s: name, c: ' '); |
1545 | if (!p) |
1546 | break; |
1547 | |
1548 | namelen = p - name; |
1549 | p++; |
1550 | |
1551 | if (!isdigit(*p)) |
1552 | continue; /* skip this line */ |
1553 | |
1554 | crc = strtoul(nptr: p, endptr: &p, base: 0); |
1555 | if (*p != '\n') |
1556 | continue; /* skip this line */ |
1557 | |
1558 | name[namelen] = '\0'; |
1559 | |
1560 | /* |
1561 | * sym_find_with_module() may return NULL here. |
1562 | * It typically occurs when CONFIG_TRIM_UNUSED_KSYMS=y. |
1563 | * Since commit e1327a127703, genksyms calculates CRCs of all |
1564 | * symbols, including trimmed ones. Ignore orphan CRCs. |
1565 | */ |
1566 | sym = sym_find_with_module(name, mod); |
1567 | if (sym) |
1568 | sym_set_crc(sym, crc); |
1569 | } |
1570 | |
1571 | free(ptr: buf); |
1572 | } |
1573 | |
1574 | /* |
1575 | * The symbol versions (CRC) are recorded in the .*.cmd files. |
1576 | * Parse them to retrieve CRCs for the current module. |
1577 | */ |
1578 | static void mod_set_crcs(struct module *mod) |
1579 | { |
1580 | char objlist[PATH_MAX]; |
1581 | char *buf, *p, *obj; |
1582 | int ret; |
1583 | |
1584 | if (mod->is_vmlinux) { |
1585 | strcpy(dest: objlist, src: ".vmlinux.objs" ); |
1586 | } else { |
1587 | /* objects for a module are listed in the *.mod file. */ |
1588 | ret = snprintf(s: objlist, maxlen: sizeof(objlist), format: "%s.mod" , mod->name); |
1589 | if (ret >= sizeof(objlist)) { |
1590 | error("%s: too long path was truncated\n" , objlist); |
1591 | return; |
1592 | } |
1593 | } |
1594 | |
1595 | buf = read_text_file(filename: objlist); |
1596 | p = buf; |
1597 | |
1598 | while ((obj = strsep(stringp: &p, delim: "\n" )) && obj[0]) |
1599 | extract_crcs_for_object(object: obj, mod); |
1600 | |
1601 | free(ptr: buf); |
1602 | } |
1603 | |
1604 | static void read_symbols(const char *modname) |
1605 | { |
1606 | const char *symname; |
1607 | char *version; |
1608 | char *license; |
1609 | char *namespace; |
1610 | struct module *mod; |
1611 | struct elf_info info = { }; |
1612 | Elf_Sym *sym; |
1613 | |
1614 | if (!parse_elf(info: &info, filename: modname)) |
1615 | return; |
1616 | |
1617 | if (!strends(str: modname, postfix: ".o" )) { |
1618 | error("%s: filename must be suffixed with .o\n" , modname); |
1619 | return; |
1620 | } |
1621 | |
1622 | /* strip trailing .o */ |
1623 | mod = new_module(name: modname, namelen: strlen(s: modname) - strlen(s: ".o" )); |
1624 | |
1625 | if (!mod->is_vmlinux) { |
1626 | license = get_modinfo(info: &info, tag: "license" ); |
1627 | if (!license) |
1628 | error("missing MODULE_LICENSE() in %s\n" , modname); |
1629 | while (license) { |
1630 | if (!license_is_gpl_compatible(license)) { |
1631 | mod->is_gpl_compatible = false; |
1632 | break; |
1633 | } |
1634 | license = get_next_modinfo(info: &info, tag: "license" , prev: license); |
1635 | } |
1636 | |
1637 | namespace = get_modinfo(info: &info, tag: "import_ns" ); |
1638 | while (namespace) { |
1639 | add_namespace(head: &mod->imported_namespaces, namespace); |
1640 | namespace = get_next_modinfo(info: &info, tag: "import_ns" , |
1641 | prev: namespace); |
1642 | } |
1643 | } |
1644 | |
1645 | if (extra_warn && !get_modinfo(info: &info, tag: "description" )) |
1646 | warn("missing MODULE_DESCRIPTION() in %s\n" , modname); |
1647 | for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { |
1648 | symname = remove_dot(s: info.strtab + sym->st_name); |
1649 | |
1650 | handle_symbol(mod, info: &info, sym, symname); |
1651 | handle_moddevtable(mod, info: &info, sym, symname); |
1652 | } |
1653 | |
1654 | check_sec_ref(mod, elf: &info); |
1655 | |
1656 | if (!mod->is_vmlinux) { |
1657 | version = get_modinfo(info: &info, tag: "version" ); |
1658 | if (version || all_versions) |
1659 | get_src_version(modname: mod->name, sum: mod->srcversion, |
1660 | sumlen: sizeof(mod->srcversion) - 1); |
1661 | } |
1662 | |
1663 | parse_elf_finish(info: &info); |
1664 | |
1665 | if (modversions) { |
1666 | /* |
1667 | * Our trick to get versioning for module struct etc. - it's |
1668 | * never passed as an argument to an exported function, so |
1669 | * the automatic versioning doesn't pick it up, but it's really |
1670 | * important anyhow. |
1671 | */ |
1672 | sym_add_unresolved(name: "module_layout" , mod, false); |
1673 | |
1674 | mod_set_crcs(mod); |
1675 | } |
1676 | } |
1677 | |
1678 | static void read_symbols_from_files(const char *filename) |
1679 | { |
1680 | FILE *in = stdin; |
1681 | char fname[PATH_MAX]; |
1682 | |
1683 | in = fopen(filename: filename, modes: "r" ); |
1684 | if (!in) |
1685 | fatal("Can't open filenames file %s: %m" , filename); |
1686 | |
1687 | while (fgets(s: fname, PATH_MAX, stream: in) != NULL) { |
1688 | if (strends(str: fname, postfix: "\n" )) |
1689 | fname[strlen(s: fname)-1] = '\0'; |
1690 | read_symbols(modname: fname); |
1691 | } |
1692 | |
1693 | fclose(stream: in); |
1694 | } |
1695 | |
1696 | #define SZ 500 |
1697 | |
1698 | /* We first write the generated file into memory using the |
1699 | * following helper, then compare to the file on disk and |
1700 | * only update the later if anything changed */ |
1701 | |
1702 | void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf, |
1703 | const char *fmt, ...) |
1704 | { |
1705 | char tmp[SZ]; |
1706 | int len; |
1707 | va_list ap; |
1708 | |
1709 | va_start(ap, fmt); |
1710 | len = vsnprintf(s: tmp, SZ, format: fmt, arg: ap); |
1711 | buf_write(buf, s: tmp, len); |
1712 | va_end(ap); |
1713 | } |
1714 | |
1715 | void buf_write(struct buffer *buf, const char *s, int len) |
1716 | { |
1717 | if (buf->size - buf->pos < len) { |
1718 | buf->size += len + SZ; |
1719 | buf->p = NOFAIL(realloc(buf->p, buf->size)); |
1720 | } |
1721 | strncpy(dest: buf->p + buf->pos, src: s, n: len); |
1722 | buf->pos += len; |
1723 | } |
1724 | |
1725 | static void check_exports(struct module *mod) |
1726 | { |
1727 | struct symbol *s, *exp; |
1728 | |
1729 | list_for_each_entry(s, &mod->unresolved_symbols, list) { |
1730 | const char *basename; |
1731 | exp = find_symbol(name: s->name); |
1732 | if (!exp) { |
1733 | if (!s->weak && nr_unresolved++ < MAX_UNRESOLVED_REPORTS) |
1734 | modpost_log(loglevel: warn_unresolved ? LOG_WARN : LOG_ERROR, |
1735 | fmt: "\"%s\" [%s.ko] undefined!\n" , |
1736 | s->name, mod->name); |
1737 | continue; |
1738 | } |
1739 | if (exp->module == mod) { |
1740 | error("\"%s\" [%s.ko] was exported without definition\n" , |
1741 | s->name, mod->name); |
1742 | continue; |
1743 | } |
1744 | |
1745 | exp->used = true; |
1746 | s->module = exp->module; |
1747 | s->crc_valid = exp->crc_valid; |
1748 | s->crc = exp->crc; |
1749 | |
1750 | basename = strrchr(s: mod->name, c: '/'); |
1751 | if (basename) |
1752 | basename++; |
1753 | else |
1754 | basename = mod->name; |
1755 | |
1756 | if (!contains_namespace(head: &mod->imported_namespaces, namespace: exp->namespace)) { |
1757 | modpost_log(loglevel: allow_missing_ns_imports ? LOG_WARN : LOG_ERROR, |
1758 | fmt: "module %s uses symbol %s from namespace %s, but does not import it.\n" , |
1759 | basename, exp->name, exp->namespace); |
1760 | add_namespace(head: &mod->missing_namespaces, namespace: exp->namespace); |
1761 | } |
1762 | |
1763 | if (!mod->is_gpl_compatible && exp->is_gpl_only) |
1764 | error("GPL-incompatible module %s.ko uses GPL-only symbol '%s'\n" , |
1765 | basename, exp->name); |
1766 | } |
1767 | } |
1768 | |
1769 | static void handle_white_list_exports(const char *white_list) |
1770 | { |
1771 | char *buf, *p, *name; |
1772 | |
1773 | buf = read_text_file(filename: white_list); |
1774 | p = buf; |
1775 | |
1776 | while ((name = strsep(stringp: &p, delim: "\n" ))) { |
1777 | struct symbol *sym = find_symbol(name); |
1778 | |
1779 | if (sym) |
1780 | sym->used = true; |
1781 | } |
1782 | |
1783 | free(ptr: buf); |
1784 | } |
1785 | |
1786 | static void check_modname_len(struct module *mod) |
1787 | { |
1788 | const char *mod_name; |
1789 | |
1790 | mod_name = strrchr(s: mod->name, c: '/'); |
1791 | if (mod_name == NULL) |
1792 | mod_name = mod->name; |
1793 | else |
1794 | mod_name++; |
1795 | if (strlen(s: mod_name) >= MODULE_NAME_LEN) |
1796 | error("module name is too long [%s.ko]\n" , mod->name); |
1797 | } |
1798 | |
1799 | /** |
1800 | * Header for the generated file |
1801 | **/ |
1802 | static void (struct buffer *b, struct module *mod) |
1803 | { |
1804 | buf_printf(buf: b, fmt: "#include <linux/module.h>\n" ); |
1805 | /* |
1806 | * Include build-salt.h after module.h in order to |
1807 | * inherit the definitions. |
1808 | */ |
1809 | buf_printf(buf: b, fmt: "#define INCLUDE_VERMAGIC\n" ); |
1810 | buf_printf(buf: b, fmt: "#include <linux/build-salt.h>\n" ); |
1811 | buf_printf(buf: b, fmt: "#include <linux/elfnote-lto.h>\n" ); |
1812 | buf_printf(buf: b, fmt: "#include <linux/export-internal.h>\n" ); |
1813 | buf_printf(buf: b, fmt: "#include <linux/vermagic.h>\n" ); |
1814 | buf_printf(buf: b, fmt: "#include <linux/compiler.h>\n" ); |
1815 | buf_printf(buf: b, fmt: "\n" ); |
1816 | buf_printf(buf: b, fmt: "#ifdef CONFIG_UNWINDER_ORC\n" ); |
1817 | buf_printf(buf: b, fmt: "#include <asm/orc_header.h>\n" ); |
1818 | buf_printf(buf: b, fmt: "ORC_HEADER;\n" ); |
1819 | buf_printf(buf: b, fmt: "#endif\n" ); |
1820 | buf_printf(buf: b, fmt: "\n" ); |
1821 | buf_printf(buf: b, fmt: "BUILD_SALT;\n" ); |
1822 | buf_printf(buf: b, fmt: "BUILD_LTO_INFO;\n" ); |
1823 | buf_printf(buf: b, fmt: "\n" ); |
1824 | buf_printf(buf: b, fmt: "MODULE_INFO(vermagic, VERMAGIC_STRING);\n" ); |
1825 | buf_printf(buf: b, fmt: "MODULE_INFO(name, KBUILD_MODNAME);\n" ); |
1826 | buf_printf(buf: b, fmt: "\n" ); |
1827 | buf_printf(buf: b, fmt: "__visible struct module __this_module\n" ); |
1828 | buf_printf(buf: b, fmt: "__section(\".gnu.linkonce.this_module\") = {\n" ); |
1829 | buf_printf(buf: b, fmt: "\t.name = KBUILD_MODNAME,\n" ); |
1830 | if (mod->has_init) |
1831 | buf_printf(buf: b, fmt: "\t.init = init_module,\n" ); |
1832 | if (mod->has_cleanup) |
1833 | buf_printf(buf: b, fmt: "#ifdef CONFIG_MODULE_UNLOAD\n" |
1834 | "\t.exit = cleanup_module,\n" |
1835 | "#endif\n" ); |
1836 | buf_printf(buf: b, fmt: "\t.arch = MODULE_ARCH_INIT,\n" ); |
1837 | buf_printf(buf: b, fmt: "};\n" ); |
1838 | |
1839 | if (!external_module) |
1840 | buf_printf(buf: b, fmt: "\nMODULE_INFO(intree, \"Y\");\n" ); |
1841 | |
1842 | buf_printf(buf: b, |
1843 | fmt: "\n" |
1844 | "#ifdef CONFIG_RETPOLINE\n" |
1845 | "MODULE_INFO(retpoline, \"Y\");\n" |
1846 | "#endif\n" ); |
1847 | |
1848 | if (strstarts(mod->name, "drivers/staging" )) |
1849 | buf_printf(buf: b, fmt: "\nMODULE_INFO(staging, \"Y\");\n" ); |
1850 | |
1851 | if (strstarts(mod->name, "tools/testing" )) |
1852 | buf_printf(buf: b, fmt: "\nMODULE_INFO(test, \"Y\");\n" ); |
1853 | } |
1854 | |
1855 | static void add_exported_symbols(struct buffer *buf, struct module *mod) |
1856 | { |
1857 | struct symbol *sym; |
1858 | |
1859 | /* generate struct for exported symbols */ |
1860 | buf_printf(buf, fmt: "\n" ); |
1861 | list_for_each_entry(sym, &mod->exported_symbols, list) { |
1862 | if (trim_unused_exports && !sym->used) |
1863 | continue; |
1864 | |
1865 | buf_printf(buf, fmt: "KSYMTAB_%s(%s, \"%s\", \"%s\");\n" , |
1866 | sym->is_func ? "FUNC" : "DATA" , sym->name, |
1867 | sym->is_gpl_only ? "_gpl" : "" , sym->namespace); |
1868 | } |
1869 | |
1870 | if (!modversions) |
1871 | return; |
1872 | |
1873 | /* record CRCs for exported symbols */ |
1874 | buf_printf(buf, fmt: "\n" ); |
1875 | list_for_each_entry(sym, &mod->exported_symbols, list) { |
1876 | if (trim_unused_exports && !sym->used) |
1877 | continue; |
1878 | |
1879 | if (!sym->crc_valid) |
1880 | warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n" |
1881 | "Is \"%s\" prototyped in <asm/asm-prototypes.h>?\n" , |
1882 | sym->name, mod->name, mod->is_vmlinux ? "" : ".ko" , |
1883 | sym->name); |
1884 | |
1885 | buf_printf(buf, fmt: "SYMBOL_CRC(%s, 0x%08x, \"%s\");\n" , |
1886 | sym->name, sym->crc, sym->is_gpl_only ? "_gpl" : "" ); |
1887 | } |
1888 | } |
1889 | |
1890 | /** |
1891 | * Record CRCs for unresolved symbols |
1892 | **/ |
1893 | static void add_versions(struct buffer *b, struct module *mod) |
1894 | { |
1895 | struct symbol *s; |
1896 | |
1897 | if (!modversions) |
1898 | return; |
1899 | |
1900 | buf_printf(buf: b, fmt: "\n" ); |
1901 | buf_printf(buf: b, fmt: "static const struct modversion_info ____versions[]\n" ); |
1902 | buf_printf(buf: b, fmt: "__used __section(\"__versions\") = {\n" ); |
1903 | |
1904 | list_for_each_entry(s, &mod->unresolved_symbols, list) { |
1905 | if (!s->module) |
1906 | continue; |
1907 | if (!s->crc_valid) { |
1908 | warn("\"%s\" [%s.ko] has no CRC!\n" , |
1909 | s->name, mod->name); |
1910 | continue; |
1911 | } |
1912 | if (strlen(s: s->name) >= MODULE_NAME_LEN) { |
1913 | error("too long symbol \"%s\" [%s.ko]\n" , |
1914 | s->name, mod->name); |
1915 | break; |
1916 | } |
1917 | buf_printf(buf: b, fmt: "\t{ %#8x, \"%s\" },\n" , |
1918 | s->crc, s->name); |
1919 | } |
1920 | |
1921 | buf_printf(buf: b, fmt: "};\n" ); |
1922 | } |
1923 | |
1924 | static void add_depends(struct buffer *b, struct module *mod) |
1925 | { |
1926 | struct symbol *s; |
1927 | int first = 1; |
1928 | |
1929 | /* Clear ->seen flag of modules that own symbols needed by this. */ |
1930 | list_for_each_entry(s, &mod->unresolved_symbols, list) { |
1931 | if (s->module) |
1932 | s->module->seen = s->module->is_vmlinux; |
1933 | } |
1934 | |
1935 | buf_printf(buf: b, fmt: "\n" ); |
1936 | buf_printf(buf: b, fmt: "MODULE_INFO(depends, \"" ); |
1937 | list_for_each_entry(s, &mod->unresolved_symbols, list) { |
1938 | const char *p; |
1939 | if (!s->module) |
1940 | continue; |
1941 | |
1942 | if (s->module->seen) |
1943 | continue; |
1944 | |
1945 | s->module->seen = true; |
1946 | p = strrchr(s: s->module->name, c: '/'); |
1947 | if (p) |
1948 | p++; |
1949 | else |
1950 | p = s->module->name; |
1951 | buf_printf(buf: b, fmt: "%s%s" , first ? "" : "," , p); |
1952 | first = 0; |
1953 | } |
1954 | buf_printf(buf: b, fmt: "\");\n" ); |
1955 | } |
1956 | |
1957 | static void add_srcversion(struct buffer *b, struct module *mod) |
1958 | { |
1959 | if (mod->srcversion[0]) { |
1960 | buf_printf(buf: b, fmt: "\n" ); |
1961 | buf_printf(buf: b, fmt: "MODULE_INFO(srcversion, \"%s\");\n" , |
1962 | mod->srcversion); |
1963 | } |
1964 | } |
1965 | |
1966 | static void write_buf(struct buffer *b, const char *fname) |
1967 | { |
1968 | FILE *file; |
1969 | |
1970 | if (error_occurred) |
1971 | return; |
1972 | |
1973 | file = fopen(filename: fname, modes: "w" ); |
1974 | if (!file) { |
1975 | perror(s: fname); |
1976 | exit(status: 1); |
1977 | } |
1978 | if (fwrite(ptr: b->p, size: 1, n: b->pos, s: file) != b->pos) { |
1979 | perror(s: fname); |
1980 | exit(status: 1); |
1981 | } |
1982 | if (fclose(stream: file) != 0) { |
1983 | perror(s: fname); |
1984 | exit(status: 1); |
1985 | } |
1986 | } |
1987 | |
1988 | static void write_if_changed(struct buffer *b, const char *fname) |
1989 | { |
1990 | char *tmp; |
1991 | FILE *file; |
1992 | struct stat st; |
1993 | |
1994 | file = fopen(filename: fname, modes: "r" ); |
1995 | if (!file) |
1996 | goto write; |
1997 | |
1998 | if (fstat(fd: fileno(stream: file), buf: &st) < 0) |
1999 | goto close_write; |
2000 | |
2001 | if (st.st_size != b->pos) |
2002 | goto close_write; |
2003 | |
2004 | tmp = NOFAIL(malloc(b->pos)); |
2005 | if (fread(ptr: tmp, size: 1, n: b->pos, stream: file) != b->pos) |
2006 | goto free_write; |
2007 | |
2008 | if (memcmp(s1: tmp, s2: b->p, n: b->pos) != 0) |
2009 | goto free_write; |
2010 | |
2011 | free(ptr: tmp); |
2012 | fclose(stream: file); |
2013 | return; |
2014 | |
2015 | free_write: |
2016 | free(ptr: tmp); |
2017 | close_write: |
2018 | fclose(stream: file); |
2019 | write: |
2020 | write_buf(b, fname); |
2021 | } |
2022 | |
2023 | static void write_vmlinux_export_c_file(struct module *mod) |
2024 | { |
2025 | struct buffer buf = { }; |
2026 | |
2027 | buf_printf(buf: &buf, |
2028 | fmt: "#include <linux/export-internal.h>\n" ); |
2029 | |
2030 | add_exported_symbols(buf: &buf, mod); |
2031 | write_if_changed(b: &buf, fname: ".vmlinux.export.c" ); |
2032 | free(ptr: buf.p); |
2033 | } |
2034 | |
2035 | /* do sanity checks, and generate *.mod.c file */ |
2036 | static void write_mod_c_file(struct module *mod) |
2037 | { |
2038 | struct buffer buf = { }; |
2039 | char fname[PATH_MAX]; |
2040 | int ret; |
2041 | |
2042 | add_header(b: &buf, mod); |
2043 | add_exported_symbols(buf: &buf, mod); |
2044 | add_versions(b: &buf, mod); |
2045 | add_depends(b: &buf, mod); |
2046 | add_moddevtable(buf: &buf, mod); |
2047 | add_srcversion(b: &buf, mod); |
2048 | |
2049 | ret = snprintf(s: fname, maxlen: sizeof(fname), format: "%s.mod.c" , mod->name); |
2050 | if (ret >= sizeof(fname)) { |
2051 | error("%s: too long path was truncated\n" , fname); |
2052 | goto free; |
2053 | } |
2054 | |
2055 | write_if_changed(b: &buf, fname); |
2056 | |
2057 | free: |
2058 | free(ptr: buf.p); |
2059 | } |
2060 | |
2061 | /* parse Module.symvers file. line format: |
2062 | * 0x12345678<tab>symbol<tab>module<tab>export<tab>namespace |
2063 | **/ |
2064 | static void read_dump(const char *fname) |
2065 | { |
2066 | char *buf, *pos, *line; |
2067 | |
2068 | buf = read_text_file(filename: fname); |
2069 | if (!buf) |
2070 | /* No symbol versions, silently ignore */ |
2071 | return; |
2072 | |
2073 | pos = buf; |
2074 | |
2075 | while ((line = get_line(stringp: &pos))) { |
2076 | char *symname, *namespace, *modname, *d, *export; |
2077 | unsigned int crc; |
2078 | struct module *mod; |
2079 | struct symbol *s; |
2080 | bool gpl_only; |
2081 | |
2082 | if (!(symname = strchr(s: line, c: '\t'))) |
2083 | goto fail; |
2084 | *symname++ = '\0'; |
2085 | if (!(modname = strchr(s: symname, c: '\t'))) |
2086 | goto fail; |
2087 | *modname++ = '\0'; |
2088 | if (!(export = strchr(s: modname, c: '\t'))) |
2089 | goto fail; |
2090 | *export++ = '\0'; |
2091 | if (!(namespace = strchr(s: export, c: '\t'))) |
2092 | goto fail; |
2093 | *namespace++ = '\0'; |
2094 | |
2095 | crc = strtoul(nptr: line, endptr: &d, base: 16); |
2096 | if (*symname == '\0' || *modname == '\0' || *d != '\0') |
2097 | goto fail; |
2098 | |
2099 | if (!strcmp(s1: export, s2: "EXPORT_SYMBOL_GPL" )) { |
2100 | gpl_only = true; |
2101 | } else if (!strcmp(s1: export, s2: "EXPORT_SYMBOL" )) { |
2102 | gpl_only = false; |
2103 | } else { |
2104 | error("%s: unknown license %s. skip" , symname, export); |
2105 | continue; |
2106 | } |
2107 | |
2108 | mod = find_module(modname); |
2109 | if (!mod) { |
2110 | mod = new_module(name: modname, namelen: strlen(s: modname)); |
2111 | mod->from_dump = true; |
2112 | } |
2113 | s = sym_add_exported(name: symname, mod, gpl_only, namespace); |
2114 | sym_set_crc(sym: s, crc); |
2115 | } |
2116 | free(ptr: buf); |
2117 | return; |
2118 | fail: |
2119 | free(ptr: buf); |
2120 | fatal("parse error in symbol dump file\n" ); |
2121 | } |
2122 | |
2123 | static void write_dump(const char *fname) |
2124 | { |
2125 | struct buffer buf = { }; |
2126 | struct module *mod; |
2127 | struct symbol *sym; |
2128 | |
2129 | list_for_each_entry(mod, &modules, list) { |
2130 | if (mod->from_dump) |
2131 | continue; |
2132 | list_for_each_entry(sym, &mod->exported_symbols, list) { |
2133 | if (trim_unused_exports && !sym->used) |
2134 | continue; |
2135 | |
2136 | buf_printf(buf: &buf, fmt: "0x%08x\t%s\t%s\tEXPORT_SYMBOL%s\t%s\n" , |
2137 | sym->crc, sym->name, mod->name, |
2138 | sym->is_gpl_only ? "_GPL" : "" , |
2139 | sym->namespace); |
2140 | } |
2141 | } |
2142 | write_buf(b: &buf, fname); |
2143 | free(ptr: buf.p); |
2144 | } |
2145 | |
2146 | static void write_namespace_deps_files(const char *fname) |
2147 | { |
2148 | struct module *mod; |
2149 | struct namespace_list *ns; |
2150 | struct buffer ns_deps_buf = {}; |
2151 | |
2152 | list_for_each_entry(mod, &modules, list) { |
2153 | |
2154 | if (mod->from_dump || list_empty(head: &mod->missing_namespaces)) |
2155 | continue; |
2156 | |
2157 | buf_printf(buf: &ns_deps_buf, fmt: "%s.ko:" , mod->name); |
2158 | |
2159 | list_for_each_entry(ns, &mod->missing_namespaces, list) |
2160 | buf_printf(buf: &ns_deps_buf, fmt: " %s" , ns->namespace); |
2161 | |
2162 | buf_printf(buf: &ns_deps_buf, fmt: "\n" ); |
2163 | } |
2164 | |
2165 | write_if_changed(b: &ns_deps_buf, fname); |
2166 | free(ptr: ns_deps_buf.p); |
2167 | } |
2168 | |
2169 | struct dump_list { |
2170 | struct list_head list; |
2171 | const char *file; |
2172 | }; |
2173 | |
2174 | int main(int argc, char **argv) |
2175 | { |
2176 | struct module *mod; |
2177 | char *missing_namespace_deps = NULL; |
2178 | char *unused_exports_white_list = NULL; |
2179 | char *dump_write = NULL, *files_source = NULL; |
2180 | int opt; |
2181 | LIST_HEAD(dump_lists); |
2182 | struct dump_list *dl, *dl2; |
2183 | |
2184 | while ((opt = getopt(argc: argc, argv: argv, shortopts: "ei:MmnT:to:au:WwENd:" )) != -1) { |
2185 | switch (opt) { |
2186 | case 'e': |
2187 | external_module = true; |
2188 | break; |
2189 | case 'i': |
2190 | dl = NOFAIL(malloc(sizeof(*dl))); |
2191 | dl->file = optarg; |
2192 | list_add_tail(new: &dl->list, head: &dump_lists); |
2193 | break; |
2194 | case 'M': |
2195 | module_enabled = true; |
2196 | break; |
2197 | case 'm': |
2198 | modversions = true; |
2199 | break; |
2200 | case 'n': |
2201 | ignore_missing_files = true; |
2202 | break; |
2203 | case 'o': |
2204 | dump_write = optarg; |
2205 | break; |
2206 | case 'a': |
2207 | all_versions = true; |
2208 | break; |
2209 | case 'T': |
2210 | files_source = optarg; |
2211 | break; |
2212 | case 't': |
2213 | trim_unused_exports = true; |
2214 | break; |
2215 | case 'u': |
2216 | unused_exports_white_list = optarg; |
2217 | break; |
2218 | case 'W': |
2219 | extra_warn = true; |
2220 | break; |
2221 | case 'w': |
2222 | warn_unresolved = true; |
2223 | break; |
2224 | case 'E': |
2225 | sec_mismatch_warn_only = false; |
2226 | break; |
2227 | case 'N': |
2228 | allow_missing_ns_imports = true; |
2229 | break; |
2230 | case 'd': |
2231 | missing_namespace_deps = optarg; |
2232 | break; |
2233 | default: |
2234 | exit(status: 1); |
2235 | } |
2236 | } |
2237 | |
2238 | list_for_each_entry_safe(dl, dl2, &dump_lists, list) { |
2239 | read_dump(fname: dl->file); |
2240 | list_del(entry: &dl->list); |
2241 | free(ptr: dl); |
2242 | } |
2243 | |
2244 | while (optind < argc) |
2245 | read_symbols(modname: argv[optind++]); |
2246 | |
2247 | if (files_source) |
2248 | read_symbols_from_files(filename: files_source); |
2249 | |
2250 | list_for_each_entry(mod, &modules, list) { |
2251 | if (mod->from_dump || mod->is_vmlinux) |
2252 | continue; |
2253 | |
2254 | check_modname_len(mod); |
2255 | check_exports(mod); |
2256 | } |
2257 | |
2258 | if (unused_exports_white_list) |
2259 | handle_white_list_exports(white_list: unused_exports_white_list); |
2260 | |
2261 | list_for_each_entry(mod, &modules, list) { |
2262 | if (mod->from_dump) |
2263 | continue; |
2264 | |
2265 | if (mod->is_vmlinux) |
2266 | write_vmlinux_export_c_file(mod); |
2267 | else |
2268 | write_mod_c_file(mod); |
2269 | } |
2270 | |
2271 | if (missing_namespace_deps) |
2272 | write_namespace_deps_files(fname: missing_namespace_deps); |
2273 | |
2274 | if (dump_write) |
2275 | write_dump(fname: dump_write); |
2276 | if (sec_mismatch_count && !sec_mismatch_warn_only) |
2277 | error("Section mismatches detected.\n" |
2278 | "Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n" ); |
2279 | |
2280 | if (nr_unresolved > MAX_UNRESOLVED_REPORTS) |
2281 | warn("suppressed %u unresolved symbol warnings because there were too many)\n" , |
2282 | nr_unresolved - MAX_UNRESOLVED_REPORTS); |
2283 | |
2284 | return error_occurred ? 1 : 0; |
2285 | } |
2286 | |