blob: e48742760fec8b08a38125c52dcde4dce0cc3ff4 [file] [log] [blame]
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001/* 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
Olivier Deprez157378f2022-04-04 15:47:50 +020015#include <elf.h>
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000016#include <stdio.h>
17#include <ctype.h>
18#include <string.h>
19#include <limits.h>
20#include <stdbool.h>
21#include <errno.h>
22#include "modpost.h"
23#include "../../include/linux/license.h"
24
25/* Are we using CONFIG_MODVERSIONS? */
26static int modversions = 0;
27/* Warn about undefined symbols? (do so if we have vmlinux) */
28static int have_vmlinux = 0;
29/* Is CONFIG_MODULE_SRCVERSION_ALL set? */
30static int all_versions = 0;
31/* If we are modposting external module set to 1 */
32static int external_module = 0;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000033/* Only warn about unresolved symbols */
34static int warn_unresolved = 0;
35/* How a symbol is exported */
36static int sec_mismatch_count = 0;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000037static int sec_mismatch_fatal = 0;
38/* ignore missing files */
39static int ignore_missing_files;
Olivier Deprez157378f2022-04-04 15:47:50 +020040/* If set to 1, only warn (instead of error) about missing ns imports */
41static int allow_missing_ns_imports;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000042
43enum export {
44 export_plain, export_unused, export_gpl,
45 export_unused_gpl, export_gpl_future, export_unknown
46};
47
48/* In kernel, this size is defined in linux/module.h;
49 * here we use Elf_Addr instead of long for covering cross-compile
50 */
51
52#define MODULE_NAME_LEN (64 - sizeof(Elf_Addr))
53
Olivier Deprez157378f2022-04-04 15:47:50 +020054void __attribute__((format(printf, 2, 3)))
55modpost_log(enum loglevel loglevel, const char *fmt, ...)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000056{
57 va_list arglist;
58
Olivier Deprez157378f2022-04-04 15:47:50 +020059 switch (loglevel) {
60 case LOG_WARN:
61 fprintf(stderr, "WARNING: ");
62 break;
63 case LOG_ERROR:
64 fprintf(stderr, "ERROR: ");
65 break;
66 case LOG_FATAL:
67 fprintf(stderr, "FATAL: ");
68 break;
69 default: /* invalid loglevel, ignore */
70 break;
71 }
72
73 fprintf(stderr, "modpost: ");
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000074
75 va_start(arglist, fmt);
76 vfprintf(stderr, fmt, arglist);
77 va_end(arglist);
78
Olivier Deprez157378f2022-04-04 15:47:50 +020079 if (loglevel == LOG_FATAL)
80 exit(1);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000081}
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
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000091void *do_nofail(void *ptr, const char *expr)
92{
93 if (!ptr)
Olivier Deprez157378f2022-04-04 15:47:50 +020094 fatal("Memory allocation failure: %s.\n", expr);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000095
96 return ptr;
97}
98
Olivier Deprez157378f2022-04-04 15:47:50 +020099char *read_text_file(const char *filename)
100{
101 struct stat st;
102 size_t nbytes;
103 int fd;
104 char *buf;
105
106 fd = open(filename, O_RDONLY);
107 if (fd < 0) {
108 perror(filename);
109 exit(1);
110 }
111
112 if (fstat(fd, &st) < 0) {
113 perror(filename);
114 exit(1);
115 }
116
117 buf = NOFAIL(malloc(st.st_size + 1));
118
119 nbytes = st.st_size;
120
121 while (nbytes) {
122 ssize_t bytes_read;
123
124 bytes_read = read(fd, buf, nbytes);
125 if (bytes_read < 0) {
126 perror(filename);
127 exit(1);
128 }
129
130 nbytes -= bytes_read;
131 }
132 buf[st.st_size] = '\0';
133
134 close(fd);
135
136 return buf;
137}
138
139char *get_line(char **stringp)
140{
141 char *orig = *stringp, *next;
142
143 /* do not return the unwanted extra line at EOF */
144 if (!orig || *orig == '\0')
145 return NULL;
146
147 /* don't use strsep here, it is not available everywhere */
148 next = strchr(orig, '\n');
149 if (next)
150 *next++ = '\0';
151
152 *stringp = next;
153
154 return orig;
155}
156
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000157/* A list of all modules we processed */
158static struct module *modules;
159
160static struct module *find_module(const char *modname)
161{
162 struct module *mod;
163
164 for (mod = modules; mod; mod = mod->next)
165 if (strcmp(mod->name, modname) == 0)
166 break;
167 return mod;
168}
169
170static struct module *new_module(const char *modname)
171{
172 struct module *mod;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000173
Olivier Deprez157378f2022-04-04 15:47:50 +0200174 mod = NOFAIL(malloc(sizeof(*mod) + strlen(modname) + 1));
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000175 memset(mod, 0, sizeof(*mod));
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000176
177 /* add to list */
Olivier Deprez157378f2022-04-04 15:47:50 +0200178 strcpy(mod->name, modname);
179 mod->is_vmlinux = (strcmp(modname, "vmlinux") == 0);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000180 mod->gpl_compatible = -1;
181 mod->next = modules;
182 modules = mod;
183
Olivier Deprez157378f2022-04-04 15:47:50 +0200184 if (mod->is_vmlinux)
185 have_vmlinux = 1;
186
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000187 return mod;
188}
189
190/* A hash of all exported symbols,
191 * struct symbol is also used for lists of unresolved symbols */
192
193#define SYMBOL_HASH_SIZE 1024
194
195struct symbol {
196 struct symbol *next;
197 struct module *module;
198 unsigned int crc;
199 int crc_valid;
David Brazdil0f672f62019-12-10 10:32:29 +0000200 char *namespace;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000201 unsigned int weak:1;
David Brazdil0f672f62019-12-10 10:32:29 +0000202 unsigned int is_static:1; /* 1 if symbol is not global */
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000203 enum export export; /* Type of export */
Olivier Deprez157378f2022-04-04 15:47:50 +0200204 char name[];
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000205};
206
207static struct symbol *symbolhash[SYMBOL_HASH_SIZE];
208
209/* This is based on the hash agorithm from gdbm, via tdb */
210static inline unsigned int tdb_hash(const char *name)
211{
212 unsigned value; /* Used to compute the hash value. */
213 unsigned i; /* Used to cycle through random values. */
214
215 /* Set the initial value from the key size. */
216 for (value = 0x238F13AF * strlen(name), i = 0; name[i]; i++)
217 value = (value + (((unsigned char *)name)[i] << (i*5 % 24)));
218
219 return (1103515243 * value + 12345);
220}
221
222/**
223 * Allocate a new symbols for use in the hash of exported symbols or
224 * the list of unresolved symbols per module
225 **/
226static struct symbol *alloc_symbol(const char *name, unsigned int weak,
227 struct symbol *next)
228{
229 struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1));
230
231 memset(s, 0, sizeof(*s));
232 strcpy(s->name, name);
233 s->weak = weak;
234 s->next = next;
David Brazdil0f672f62019-12-10 10:32:29 +0000235 s->is_static = 1;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000236 return s;
237}
238
239/* For the hash of exported symbols */
240static struct symbol *new_symbol(const char *name, struct module *module,
241 enum export export)
242{
243 unsigned int hash;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000244
245 hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
Olivier Deprez157378f2022-04-04 15:47:50 +0200246 symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]);
247
248 return symbolhash[hash];
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000249}
250
251static struct symbol *find_symbol(const char *name)
252{
253 struct symbol *s;
254
255 /* For our purposes, .foo matches foo. PPC64 needs this. */
256 if (name[0] == '.')
257 name++;
258
259 for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s = s->next) {
260 if (strcmp(s->name, name) == 0)
261 return s;
262 }
263 return NULL;
264}
265
David Brazdil0f672f62019-12-10 10:32:29 +0000266static bool contains_namespace(struct namespace_list *list,
267 const char *namespace)
268{
Olivier Deprez157378f2022-04-04 15:47:50 +0200269 for (; list; list = list->next)
270 if (!strcmp(list->namespace, namespace))
David Brazdil0f672f62019-12-10 10:32:29 +0000271 return true;
272
273 return false;
274}
275
276static void add_namespace(struct namespace_list **list, const char *namespace)
277{
278 struct namespace_list *ns_entry;
279
280 if (!contains_namespace(*list, namespace)) {
281 ns_entry = NOFAIL(malloc(sizeof(struct namespace_list) +
282 strlen(namespace) + 1));
283 strcpy(ns_entry->namespace, namespace);
284 ns_entry->next = *list;
285 *list = ns_entry;
286 }
287}
288
289static bool module_imports_namespace(struct module *module,
290 const char *namespace)
291{
292 return contains_namespace(module->imported_namespaces, namespace);
293}
294
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000295static const struct {
296 const char *str;
297 enum export export;
298} export_list[] = {
299 { .str = "EXPORT_SYMBOL", .export = export_plain },
300 { .str = "EXPORT_UNUSED_SYMBOL", .export = export_unused },
301 { .str = "EXPORT_SYMBOL_GPL", .export = export_gpl },
302 { .str = "EXPORT_UNUSED_SYMBOL_GPL", .export = export_unused_gpl },
303 { .str = "EXPORT_SYMBOL_GPL_FUTURE", .export = export_gpl_future },
304 { .str = "(unknown)", .export = export_unknown },
305};
306
307
308static const char *export_str(enum export ex)
309{
310 return export_list[ex].str;
311}
312
313static enum export export_no(const char *s)
314{
315 int i;
316
317 if (!s)
318 return export_unknown;
319 for (i = 0; export_list[i].export != export_unknown; i++) {
320 if (strcmp(export_list[i].str, s) == 0)
321 return export_list[i].export;
322 }
323 return export_unknown;
324}
325
Olivier Deprez157378f2022-04-04 15:47:50 +0200326static void *sym_get_data_by_offset(const struct elf_info *info,
327 unsigned int secindex, unsigned long offset)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000328{
Olivier Deprez157378f2022-04-04 15:47:50 +0200329 Elf_Shdr *sechdr = &info->sechdrs[secindex];
330
331 if (info->hdr->e_type != ET_REL)
332 offset -= sechdr->sh_addr;
333
334 return (void *)info->hdr + sechdr->sh_offset + offset;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000335}
336
Olivier Deprez157378f2022-04-04 15:47:50 +0200337static void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000338{
Olivier Deprez157378f2022-04-04 15:47:50 +0200339 return sym_get_data_by_offset(info, get_secindex(info, sym),
340 sym->st_value);
341}
342
343static const char *sech_name(const struct elf_info *info, Elf_Shdr *sechdr)
344{
345 return sym_get_data_by_offset(info, info->secindex_strings,
346 sechdr->sh_name);
347}
348
349static const char *sec_name(const struct elf_info *info, int secindex)
350{
351 return sech_name(info, &info->sechdrs[secindex]);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000352}
353
354#define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0)
355
356static enum export export_from_secname(struct elf_info *elf, unsigned int sec)
357{
358 const char *secname = sec_name(elf, sec);
359
360 if (strstarts(secname, "___ksymtab+"))
361 return export_plain;
362 else if (strstarts(secname, "___ksymtab_unused+"))
363 return export_unused;
364 else if (strstarts(secname, "___ksymtab_gpl+"))
365 return export_gpl;
366 else if (strstarts(secname, "___ksymtab_unused_gpl+"))
367 return export_unused_gpl;
368 else if (strstarts(secname, "___ksymtab_gpl_future+"))
369 return export_gpl_future;
370 else
371 return export_unknown;
372}
373
374static enum export export_from_sec(struct elf_info *elf, unsigned int sec)
375{
376 if (sec == elf->export_sec)
377 return export_plain;
378 else if (sec == elf->export_unused_sec)
379 return export_unused;
380 else if (sec == elf->export_gpl_sec)
381 return export_gpl;
382 else if (sec == elf->export_unused_gpl_sec)
383 return export_unused_gpl;
384 else if (sec == elf->export_gpl_future_sec)
385 return export_gpl_future;
386 else
387 return export_unknown;
388}
389
Olivier Deprez157378f2022-04-04 15:47:50 +0200390static const char *namespace_from_kstrtabns(const struct elf_info *info,
391 const Elf_Sym *sym)
David Brazdil0f672f62019-12-10 10:32:29 +0000392{
Olivier Deprez157378f2022-04-04 15:47:50 +0200393 const char *value = sym_get_data(info, sym);
David Brazdil0f672f62019-12-10 10:32:29 +0000394 return value[0] ? value : NULL;
395}
396
397static void sym_update_namespace(const char *symname, const char *namespace)
398{
399 struct symbol *s = find_symbol(symname);
400
401 /*
402 * That symbol should have been created earlier and thus this is
403 * actually an assertion.
404 */
405 if (!s) {
406 merror("Could not update namespace(%s) for symbol %s\n",
407 namespace, symname);
408 return;
409 }
410
411 free(s->namespace);
412 s->namespace =
413 namespace && namespace[0] ? NOFAIL(strdup(namespace)) : NULL;
414}
415
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000416/**
417 * Add an exported symbol - it may have already been added without a
418 * CRC, in this case just update the CRC
419 **/
420static struct symbol *sym_add_exported(const char *name, struct module *mod,
421 enum export export)
422{
423 struct symbol *s = find_symbol(name);
424
425 if (!s) {
426 s = new_symbol(name, mod, export);
Olivier Deprez157378f2022-04-04 15:47:50 +0200427 } else if (!external_module || s->module->is_vmlinux ||
428 s->module == mod) {
429 warn("%s: '%s' exported twice. Previous export was in %s%s\n",
430 mod->name, name, s->module->name,
431 s->module->is_vmlinux ? "" : ".ko");
432 return s;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000433 }
Olivier Deprez157378f2022-04-04 15:47:50 +0200434
435 s->module = mod;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000436 s->export = export;
437 return s;
438}
439
Olivier Deprez157378f2022-04-04 15:47:50 +0200440static void sym_set_crc(const char *name, unsigned int crc)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000441{
442 struct symbol *s = find_symbol(name);
443
Olivier Deprez157378f2022-04-04 15:47:50 +0200444 /*
445 * Ignore stand-alone __crc_*, which might be auto-generated symbols
446 * such as __*_veneer in ARM ELF.
447 */
448 if (!s)
449 return;
450
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000451 s->crc = crc;
452 s->crc_valid = 1;
453}
454
Olivier Deprez157378f2022-04-04 15:47:50 +0200455static void *grab_file(const char *filename, size_t *size)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000456{
457 struct stat st;
458 void *map = MAP_FAILED;
459 int fd;
460
461 fd = open(filename, O_RDONLY);
462 if (fd < 0)
463 return NULL;
464 if (fstat(fd, &st))
465 goto failed;
466
467 *size = st.st_size;
468 map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
469
470failed:
471 close(fd);
472 if (map == MAP_FAILED)
473 return NULL;
474 return map;
475}
476
Olivier Deprez157378f2022-04-04 15:47:50 +0200477static void release_file(void *file, size_t size)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000478{
479 munmap(file, size);
480}
481
482static int parse_elf(struct elf_info *info, const char *filename)
483{
484 unsigned int i;
485 Elf_Ehdr *hdr;
486 Elf_Shdr *sechdrs;
487 Elf_Sym *sym;
488 const char *secstrings;
489 unsigned int symtab_idx = ~0U, symtab_shndx_idx = ~0U;
490
491 hdr = grab_file(filename, &info->size);
492 if (!hdr) {
493 if (ignore_missing_files) {
494 fprintf(stderr, "%s: %s (ignored)\n", filename,
495 strerror(errno));
496 return 0;
497 }
498 perror(filename);
499 exit(1);
500 }
501 info->hdr = hdr;
502 if (info->size < sizeof(*hdr)) {
503 /* file too small, assume this is an empty .o file */
504 return 0;
505 }
506 /* Is this a valid ELF file? */
507 if ((hdr->e_ident[EI_MAG0] != ELFMAG0) ||
508 (hdr->e_ident[EI_MAG1] != ELFMAG1) ||
509 (hdr->e_ident[EI_MAG2] != ELFMAG2) ||
510 (hdr->e_ident[EI_MAG3] != ELFMAG3)) {
511 /* Not an ELF file - silently ignore it */
512 return 0;
513 }
514 /* Fix endianness in ELF header */
515 hdr->e_type = TO_NATIVE(hdr->e_type);
516 hdr->e_machine = TO_NATIVE(hdr->e_machine);
517 hdr->e_version = TO_NATIVE(hdr->e_version);
518 hdr->e_entry = TO_NATIVE(hdr->e_entry);
519 hdr->e_phoff = TO_NATIVE(hdr->e_phoff);
520 hdr->e_shoff = TO_NATIVE(hdr->e_shoff);
521 hdr->e_flags = TO_NATIVE(hdr->e_flags);
522 hdr->e_ehsize = TO_NATIVE(hdr->e_ehsize);
523 hdr->e_phentsize = TO_NATIVE(hdr->e_phentsize);
524 hdr->e_phnum = TO_NATIVE(hdr->e_phnum);
525 hdr->e_shentsize = TO_NATIVE(hdr->e_shentsize);
526 hdr->e_shnum = TO_NATIVE(hdr->e_shnum);
527 hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx);
528 sechdrs = (void *)hdr + hdr->e_shoff;
529 info->sechdrs = sechdrs;
530
531 /* Check if file offset is correct */
532 if (hdr->e_shoff > info->size) {
Olivier Deprez157378f2022-04-04 15:47:50 +0200533 fatal("section header offset=%lu in file '%s' is bigger than filesize=%zu\n",
534 (unsigned long)hdr->e_shoff, filename, info->size);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000535 return 0;
536 }
537
538 if (hdr->e_shnum == SHN_UNDEF) {
539 /*
540 * There are more than 64k sections,
541 * read count from .sh_size.
542 */
543 info->num_sections = TO_NATIVE(sechdrs[0].sh_size);
544 }
545 else {
546 info->num_sections = hdr->e_shnum;
547 }
548 if (hdr->e_shstrndx == SHN_XINDEX) {
549 info->secindex_strings = TO_NATIVE(sechdrs[0].sh_link);
550 }
551 else {
552 info->secindex_strings = hdr->e_shstrndx;
553 }
554
555 /* Fix endianness in section headers */
556 for (i = 0; i < info->num_sections; i++) {
557 sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name);
558 sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type);
559 sechdrs[i].sh_flags = TO_NATIVE(sechdrs[i].sh_flags);
560 sechdrs[i].sh_addr = TO_NATIVE(sechdrs[i].sh_addr);
561 sechdrs[i].sh_offset = TO_NATIVE(sechdrs[i].sh_offset);
562 sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size);
563 sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link);
564 sechdrs[i].sh_info = TO_NATIVE(sechdrs[i].sh_info);
565 sechdrs[i].sh_addralign = TO_NATIVE(sechdrs[i].sh_addralign);
566 sechdrs[i].sh_entsize = TO_NATIVE(sechdrs[i].sh_entsize);
567 }
568 /* Find symbol table. */
569 secstrings = (void *)hdr + sechdrs[info->secindex_strings].sh_offset;
570 for (i = 1; i < info->num_sections; i++) {
571 const char *secname;
572 int nobits = sechdrs[i].sh_type == SHT_NOBITS;
573
574 if (!nobits && sechdrs[i].sh_offset > info->size) {
575 fatal("%s is truncated. sechdrs[i].sh_offset=%lu > "
576 "sizeof(*hrd)=%zu\n", filename,
577 (unsigned long)sechdrs[i].sh_offset,
578 sizeof(*hdr));
579 return 0;
580 }
581 secname = secstrings + sechdrs[i].sh_name;
582 if (strcmp(secname, ".modinfo") == 0) {
583 if (nobits)
584 fatal("%s has NOBITS .modinfo\n", filename);
585 info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
586 info->modinfo_len = sechdrs[i].sh_size;
587 } else if (strcmp(secname, "__ksymtab") == 0)
588 info->export_sec = i;
589 else if (strcmp(secname, "__ksymtab_unused") == 0)
590 info->export_unused_sec = i;
591 else if (strcmp(secname, "__ksymtab_gpl") == 0)
592 info->export_gpl_sec = i;
593 else if (strcmp(secname, "__ksymtab_unused_gpl") == 0)
594 info->export_unused_gpl_sec = i;
595 else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
596 info->export_gpl_future_sec = i;
597
598 if (sechdrs[i].sh_type == SHT_SYMTAB) {
599 unsigned int sh_link_idx;
600 symtab_idx = i;
601 info->symtab_start = (void *)hdr +
602 sechdrs[i].sh_offset;
603 info->symtab_stop = (void *)hdr +
604 sechdrs[i].sh_offset + sechdrs[i].sh_size;
605 sh_link_idx = sechdrs[i].sh_link;
606 info->strtab = (void *)hdr +
607 sechdrs[sh_link_idx].sh_offset;
608 }
609
610 /* 32bit section no. table? ("more than 64k sections") */
611 if (sechdrs[i].sh_type == SHT_SYMTAB_SHNDX) {
612 symtab_shndx_idx = i;
613 info->symtab_shndx_start = (void *)hdr +
614 sechdrs[i].sh_offset;
615 info->symtab_shndx_stop = (void *)hdr +
616 sechdrs[i].sh_offset + sechdrs[i].sh_size;
617 }
618 }
619 if (!info->symtab_start)
620 fatal("%s has no symtab?\n", filename);
621
622 /* Fix endianness in symbols */
623 for (sym = info->symtab_start; sym < info->symtab_stop; sym++) {
624 sym->st_shndx = TO_NATIVE(sym->st_shndx);
625 sym->st_name = TO_NATIVE(sym->st_name);
626 sym->st_value = TO_NATIVE(sym->st_value);
627 sym->st_size = TO_NATIVE(sym->st_size);
628 }
629
630 if (symtab_shndx_idx != ~0U) {
631 Elf32_Word *p;
632 if (symtab_idx != sechdrs[symtab_shndx_idx].sh_link)
633 fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n",
634 filename, sechdrs[symtab_shndx_idx].sh_link,
635 symtab_idx);
636 /* Fix endianness */
637 for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop;
638 p++)
639 *p = TO_NATIVE(*p);
640 }
641
642 return 1;
643}
644
645static void parse_elf_finish(struct elf_info *info)
646{
647 release_file(info->hdr, info->size);
648}
649
650static int ignore_undef_symbol(struct elf_info *info, const char *symname)
651{
652 /* ignore __this_module, it will be resolved shortly */
653 if (strcmp(symname, "__this_module") == 0)
654 return 1;
655 /* ignore global offset table */
656 if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0)
657 return 1;
658 if (info->hdr->e_machine == EM_PPC)
659 /* Special register function linked on all modules during final link of .ko */
660 if (strstarts(symname, "_restgpr_") ||
661 strstarts(symname, "_savegpr_") ||
662 strstarts(symname, "_rest32gpr_") ||
663 strstarts(symname, "_save32gpr_") ||
664 strstarts(symname, "_restvr_") ||
665 strstarts(symname, "_savevr_"))
666 return 1;
667 if (info->hdr->e_machine == EM_PPC64)
668 /* Special register function linked on all modules during final link of .ko */
669 if (strstarts(symname, "_restgpr0_") ||
670 strstarts(symname, "_savegpr0_") ||
671 strstarts(symname, "_restvr_") ||
672 strstarts(symname, "_savevr_") ||
673 strcmp(symname, ".TOC.") == 0)
674 return 1;
675 /* Do not ignore this symbol */
676 return 0;
677}
678
Olivier Deprez157378f2022-04-04 15:47:50 +0200679static void handle_modversion(const struct module *mod,
680 const struct elf_info *info,
681 const Elf_Sym *sym, const char *symname)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000682{
683 unsigned int crc;
Olivier Deprez157378f2022-04-04 15:47:50 +0200684
685 if (sym->st_shndx == SHN_UNDEF) {
686 warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n",
687 symname, mod->name, mod->is_vmlinux ? "" : ".ko");
688 return;
689 }
690
691 if (sym->st_shndx == SHN_ABS) {
692 crc = sym->st_value;
693 } else {
694 unsigned int *crcp;
695
696 /* symbol points to the CRC in the ELF object */
697 crcp = sym_get_data(info, sym);
698 crc = TO_NATIVE(*crcp);
699 }
700 sym_set_crc(symname, crc);
701}
702
703static void handle_symbol(struct module *mod, struct elf_info *info,
704 const Elf_Sym *sym, const char *symname)
705{
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000706 enum export export;
David Brazdil0f672f62019-12-10 10:32:29 +0000707 const char *name;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000708
Olivier Deprez157378f2022-04-04 15:47:50 +0200709 if (strstarts(symname, "__ksymtab"))
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000710 export = export_from_secname(info, get_secindex(info, sym));
711 else
712 export = export_from_sec(info, get_secindex(info, sym));
713
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000714 switch (sym->st_shndx) {
715 case SHN_COMMON:
716 if (strstarts(symname, "__gnu_lto_")) {
717 /* Should warn here, but modpost runs before the linker */
718 } else
719 warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name);
720 break;
721 case SHN_UNDEF:
722 /* undefined symbol */
723 if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL &&
724 ELF_ST_BIND(sym->st_info) != STB_WEAK)
725 break;
726 if (ignore_undef_symbol(info, symname))
727 break;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000728 if (info->hdr->e_machine == EM_SPARC ||
729 info->hdr->e_machine == EM_SPARCV9) {
730 /* Ignore register directives. */
731 if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)
732 break;
733 if (symname[0] == '.') {
734 char *munged = NOFAIL(strdup(symname));
735 munged[0] = '_';
736 munged[1] = toupper(munged[1]);
737 symname = munged;
738 }
739 }
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000740
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000741 mod->unres = alloc_symbol(symname,
742 ELF_ST_BIND(sym->st_info) == STB_WEAK,
743 mod->unres);
744 break;
745 default:
746 /* All exported symbols */
747 if (strstarts(symname, "__ksymtab_")) {
David Brazdil0f672f62019-12-10 10:32:29 +0000748 name = symname + strlen("__ksymtab_");
749 sym_add_exported(name, mod, export);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000750 }
751 if (strcmp(symname, "init_module") == 0)
752 mod->has_init = 1;
753 if (strcmp(symname, "cleanup_module") == 0)
754 mod->has_cleanup = 1;
755 break;
756 }
757}
758
759/**
760 * Parse tag=value strings from .modinfo section
761 **/
762static char *next_string(char *string, unsigned long *secsize)
763{
764 /* Skip non-zero chars */
765 while (string[0]) {
766 string++;
767 if ((*secsize)-- <= 1)
768 return NULL;
769 }
770
771 /* Skip any zero padding. */
772 while (!string[0]) {
773 string++;
774 if ((*secsize)-- <= 1)
775 return NULL;
776 }
777 return string;
778}
779
780static char *get_next_modinfo(struct elf_info *info, const char *tag,
781 char *prev)
782{
783 char *p;
784 unsigned int taglen = strlen(tag);
785 char *modinfo = info->modinfo;
786 unsigned long size = info->modinfo_len;
787
788 if (prev) {
789 size -= prev - modinfo;
790 modinfo = next_string(prev, &size);
791 }
792
793 for (p = modinfo; p; p = next_string(p, &size)) {
794 if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
795 return p + taglen + 1;
796 }
797 return NULL;
798}
799
800static char *get_modinfo(struct elf_info *info, const char *tag)
801
802{
803 return get_next_modinfo(info, tag, NULL);
804}
805
806/**
807 * Test if string s ends in string sub
808 * return 0 if match
809 **/
810static int strrcmp(const char *s, const char *sub)
811{
812 int slen, sublen;
813
814 if (!s || !sub)
815 return 1;
816
817 slen = strlen(s);
818 sublen = strlen(sub);
819
820 if ((slen == 0) || (sublen == 0))
821 return 1;
822
823 if (sublen > slen)
824 return 1;
825
826 return memcmp(s + slen - sublen, sub, sublen);
827}
828
829static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
830{
831 if (sym)
832 return elf->strtab + sym->st_name;
833 else
834 return "(unknown)";
835}
836
837/* The pattern is an array of simple patterns.
838 * "foo" will match an exact string equal to "foo"
839 * "*foo" will match a string that ends with "foo"
840 * "foo*" will match a string that begins with "foo"
841 * "*foo*" will match a string that contains "foo"
842 */
843static int match(const char *sym, const char * const pat[])
844{
845 const char *p;
846 while (*pat) {
847 p = *pat++;
848 const char *endp = p + strlen(p) - 1;
849
850 /* "*foo*" */
851 if (*p == '*' && *endp == '*') {
David Brazdil0f672f62019-12-10 10:32:29 +0000852 char *bare = NOFAIL(strndup(p + 1, strlen(p) - 2));
853 char *here = strstr(sym, bare);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000854
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000855 free(bare);
856 if (here != NULL)
857 return 1;
858 }
859 /* "*foo" */
860 else if (*p == '*') {
861 if (strrcmp(sym, p + 1) == 0)
862 return 1;
863 }
864 /* "foo*" */
865 else if (*endp == '*') {
866 if (strncmp(sym, p, strlen(p) - 1) == 0)
867 return 1;
868 }
869 /* no wildcards */
870 else {
871 if (strcmp(p, sym) == 0)
872 return 1;
873 }
874 }
875 /* no match */
876 return 0;
877}
878
879/* sections that we do not want to do full section mismatch check on */
880static const char *const section_white_list[] =
881{
882 ".comment*",
883 ".debug*",
884 ".cranges", /* sh64 */
885 ".zdebug*", /* Compressed debug sections. */
886 ".GCC.command.line", /* record-gcc-switches */
887 ".mdebug*", /* alpha, score, mips etc. */
888 ".pdr", /* alpha, score, mips etc. */
889 ".stab*",
890 ".note*",
891 ".got*",
892 ".toc*",
893 ".xt.prop", /* xtensa */
894 ".xt.lit", /* xtensa */
895 ".arcextmap*", /* arc */
896 ".gnu.linkonce.arcext*", /* arc : modules */
897 ".cmem*", /* EZchip */
898 ".fmt_slot*", /* EZchip */
899 ".gnu.lto*",
900 ".discard.*",
901 NULL
902};
903
904/*
905 * This is used to find sections missing the SHF_ALLOC flag.
906 * The cause of this is often a section specified in assembler
907 * without "ax" / "aw".
908 */
909static void check_section(const char *modname, struct elf_info *elf,
910 Elf_Shdr *sechdr)
911{
912 const char *sec = sech_name(elf, sechdr);
913
914 if (sechdr->sh_type == SHT_PROGBITS &&
915 !(sechdr->sh_flags & SHF_ALLOC) &&
916 !match(sec, section_white_list)) {
917 warn("%s (%s): unexpected non-allocatable section.\n"
918 "Did you forget to use \"ax\"/\"aw\" in a .S file?\n"
919 "Note that for example <linux/init.h> contains\n"
920 "section definitions for use in .S files.\n\n",
921 modname, sec);
922 }
923}
924
925
926
927#define ALL_INIT_DATA_SECTIONS \
928 ".init.setup", ".init.rodata", ".meminit.rodata", \
929 ".init.data", ".meminit.data"
930#define ALL_EXIT_DATA_SECTIONS \
931 ".exit.data", ".memexit.data"
932
933#define ALL_INIT_TEXT_SECTIONS \
934 ".init.text", ".meminit.text"
935#define ALL_EXIT_TEXT_SECTIONS \
936 ".exit.text", ".memexit.text"
937
938#define ALL_PCI_INIT_SECTIONS \
939 ".pci_fixup_early", ".pci_fixup_header", ".pci_fixup_final", \
940 ".pci_fixup_enable", ".pci_fixup_resume", \
941 ".pci_fixup_resume_early", ".pci_fixup_suspend"
942
943#define ALL_XXXINIT_SECTIONS MEM_INIT_SECTIONS
944#define ALL_XXXEXIT_SECTIONS MEM_EXIT_SECTIONS
945
946#define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS
947#define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS
948
949#define DATA_SECTIONS ".data", ".data.rel"
950#define TEXT_SECTIONS ".text", ".text.unlikely", ".sched.text", \
Olivier Deprez0e641232021-09-23 10:07:05 +0200951 ".kprobes.text", ".cpuidle.text", ".noinstr.text"
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000952#define OTHER_TEXT_SECTIONS ".ref.text", ".head.text", ".spinlock.text", \
953 ".fixup", ".entry.text", ".exception.text", ".text.*", \
954 ".coldtext"
955
956#define INIT_SECTIONS ".init.*"
957#define MEM_INIT_SECTIONS ".meminit.*"
958
959#define EXIT_SECTIONS ".exit.*"
960#define MEM_EXIT_SECTIONS ".memexit.*"
961
962#define ALL_TEXT_SECTIONS ALL_INIT_TEXT_SECTIONS, ALL_EXIT_TEXT_SECTIONS, \
963 TEXT_SECTIONS, OTHER_TEXT_SECTIONS
964
965/* init data sections */
966static const char *const init_data_sections[] =
967 { ALL_INIT_DATA_SECTIONS, NULL };
968
969/* all init sections */
970static const char *const init_sections[] = { ALL_INIT_SECTIONS, NULL };
971
972/* All init and exit sections (code + data) */
973static const char *const init_exit_sections[] =
974 {ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL };
975
976/* all text sections */
977static const char *const text_sections[] = { ALL_TEXT_SECTIONS, NULL };
978
979/* data section */
980static const char *const data_sections[] = { DATA_SECTIONS, NULL };
981
982
983/* symbols in .data that may refer to init/exit sections */
984#define DEFAULT_SYMBOL_WHITE_LIST \
985 "*driver", \
986 "*_template", /* scsi uses *_template a lot */ \
987 "*_timer", /* arm uses ops structures named _timer a lot */ \
988 "*_sht", /* scsi also used *_sht to some extent */ \
989 "*_ops", \
990 "*_probe", \
991 "*_probe_one", \
992 "*_console"
993
994static const char *const head_sections[] = { ".head.text*", NULL };
995static const char *const linker_symbols[] =
996 { "__init_begin", "_sinittext", "_einittext", NULL };
997static const char *const optim_symbols[] = { "*.constprop.*", NULL };
998
999enum mismatch {
1000 TEXT_TO_ANY_INIT,
1001 DATA_TO_ANY_INIT,
1002 TEXT_TO_ANY_EXIT,
1003 DATA_TO_ANY_EXIT,
1004 XXXINIT_TO_SOME_INIT,
1005 XXXEXIT_TO_SOME_EXIT,
1006 ANY_INIT_TO_ANY_EXIT,
1007 ANY_EXIT_TO_ANY_INIT,
1008 EXPORT_TO_INIT_EXIT,
1009 EXTABLE_TO_NON_TEXT,
1010};
1011
1012/**
1013 * Describe how to match sections on different criterias:
1014 *
1015 * @fromsec: Array of sections to be matched.
1016 *
1017 * @bad_tosec: Relocations applied to a section in @fromsec to a section in
1018 * this array is forbidden (black-list). Can be empty.
1019 *
1020 * @good_tosec: Relocations applied to a section in @fromsec must be
1021 * targetting sections in this array (white-list). Can be empty.
1022 *
1023 * @mismatch: Type of mismatch.
1024 *
1025 * @symbol_white_list: Do not match a relocation to a symbol in this list
1026 * even if it is targetting a section in @bad_to_sec.
1027 *
1028 * @handler: Specific handler to call when a match is found. If NULL,
1029 * default_mismatch_handler() will be called.
1030 *
1031 */
1032struct sectioncheck {
1033 const char *fromsec[20];
1034 const char *bad_tosec[20];
1035 const char *good_tosec[20];
1036 enum mismatch mismatch;
1037 const char *symbol_white_list[20];
1038 void (*handler)(const char *modname, struct elf_info *elf,
1039 const struct sectioncheck* const mismatch,
1040 Elf_Rela *r, Elf_Sym *sym, const char *fromsec);
1041
1042};
1043
1044static void extable_mismatch_handler(const char *modname, struct elf_info *elf,
1045 const struct sectioncheck* const mismatch,
1046 Elf_Rela *r, Elf_Sym *sym,
1047 const char *fromsec);
1048
1049static const struct sectioncheck sectioncheck[] = {
1050/* Do not reference init/exit code/data from
1051 * normal code and data
1052 */
1053{
1054 .fromsec = { TEXT_SECTIONS, NULL },
1055 .bad_tosec = { ALL_INIT_SECTIONS, NULL },
1056 .mismatch = TEXT_TO_ANY_INIT,
1057 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
1058},
1059{
1060 .fromsec = { DATA_SECTIONS, NULL },
1061 .bad_tosec = { ALL_XXXINIT_SECTIONS, NULL },
1062 .mismatch = DATA_TO_ANY_INIT,
1063 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
1064},
1065{
1066 .fromsec = { DATA_SECTIONS, NULL },
1067 .bad_tosec = { INIT_SECTIONS, NULL },
1068 .mismatch = DATA_TO_ANY_INIT,
1069 .symbol_white_list = {
1070 "*_template", "*_timer", "*_sht", "*_ops",
1071 "*_probe", "*_probe_one", "*_console", NULL
1072 },
1073},
1074{
1075 .fromsec = { TEXT_SECTIONS, NULL },
1076 .bad_tosec = { ALL_EXIT_SECTIONS, NULL },
1077 .mismatch = TEXT_TO_ANY_EXIT,
1078 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
1079},
1080{
1081 .fromsec = { DATA_SECTIONS, NULL },
1082 .bad_tosec = { ALL_EXIT_SECTIONS, NULL },
1083 .mismatch = DATA_TO_ANY_EXIT,
1084 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
1085},
1086/* Do not reference init code/data from meminit code/data */
1087{
1088 .fromsec = { ALL_XXXINIT_SECTIONS, NULL },
1089 .bad_tosec = { INIT_SECTIONS, NULL },
1090 .mismatch = XXXINIT_TO_SOME_INIT,
1091 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
1092},
1093/* Do not reference exit code/data from memexit code/data */
1094{
1095 .fromsec = { ALL_XXXEXIT_SECTIONS, NULL },
1096 .bad_tosec = { EXIT_SECTIONS, NULL },
1097 .mismatch = XXXEXIT_TO_SOME_EXIT,
1098 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
1099},
1100/* Do not use exit code/data from init code */
1101{
1102 .fromsec = { ALL_INIT_SECTIONS, NULL },
1103 .bad_tosec = { ALL_EXIT_SECTIONS, NULL },
1104 .mismatch = ANY_INIT_TO_ANY_EXIT,
1105 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
1106},
1107/* Do not use init code/data from exit code */
1108{
1109 .fromsec = { ALL_EXIT_SECTIONS, NULL },
1110 .bad_tosec = { ALL_INIT_SECTIONS, NULL },
1111 .mismatch = ANY_EXIT_TO_ANY_INIT,
1112 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
1113},
1114{
1115 .fromsec = { ALL_PCI_INIT_SECTIONS, NULL },
1116 .bad_tosec = { INIT_SECTIONS, NULL },
1117 .mismatch = ANY_INIT_TO_ANY_EXIT,
1118 .symbol_white_list = { NULL },
1119},
1120/* Do not export init/exit functions or data */
1121{
Olivier Deprez92d4c212022-12-06 15:05:30 +01001122 .fromsec = { "___ksymtab*", NULL },
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001123 .bad_tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
1124 .mismatch = EXPORT_TO_INIT_EXIT,
1125 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
1126},
1127{
1128 .fromsec = { "__ex_table", NULL },
1129 /* If you're adding any new black-listed sections in here, consider
1130 * adding a special 'printer' for them in scripts/check_extable.
1131 */
1132 .bad_tosec = { ".altinstr_replacement", NULL },
1133 .good_tosec = {ALL_TEXT_SECTIONS , NULL},
1134 .mismatch = EXTABLE_TO_NON_TEXT,
1135 .handler = extable_mismatch_handler,
1136}
1137};
1138
1139static const struct sectioncheck *section_mismatch(
1140 const char *fromsec, const char *tosec)
1141{
1142 int i;
1143 int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck);
1144 const struct sectioncheck *check = &sectioncheck[0];
1145
1146 /*
1147 * The target section could be the SHT_NUL section when we're
1148 * handling relocations to un-resolved symbols, trying to match it
1149 * doesn't make much sense and causes build failures on parisc
1150 * architectures.
1151 */
1152 if (*tosec == '\0')
1153 return NULL;
1154
1155 for (i = 0; i < elems; i++) {
1156 if (match(fromsec, check->fromsec)) {
1157 if (check->bad_tosec[0] && match(tosec, check->bad_tosec))
1158 return check;
1159 if (check->good_tosec[0] && !match(tosec, check->good_tosec))
1160 return check;
1161 }
1162 check++;
1163 }
1164 return NULL;
1165}
1166
1167/**
1168 * Whitelist to allow certain references to pass with no warning.
1169 *
1170 * Pattern 1:
1171 * If a module parameter is declared __initdata and permissions=0
1172 * then this is legal despite the warning generated.
1173 * We cannot see value of permissions here, so just ignore
1174 * this pattern.
1175 * The pattern is identified by:
1176 * tosec = .init.data
1177 * fromsec = .data*
1178 * atsym =__param*
1179 *
1180 * Pattern 1a:
1181 * module_param_call() ops can refer to __init set function if permissions=0
1182 * The pattern is identified by:
1183 * tosec = .init.text
1184 * fromsec = .data*
1185 * atsym = __param_ops_*
1186 *
1187 * Pattern 2:
1188 * Many drivers utilise a *driver container with references to
1189 * add, remove, probe functions etc.
1190 * the pattern is identified by:
1191 * tosec = init or exit section
1192 * fromsec = data section
1193 * atsym = *driver, *_template, *_sht, *_ops, *_probe,
1194 * *probe_one, *_console, *_timer
1195 *
1196 * Pattern 3:
1197 * Whitelist all references from .head.text to any init section
1198 *
1199 * Pattern 4:
1200 * Some symbols belong to init section but still it is ok to reference
1201 * these from non-init sections as these symbols don't have any memory
1202 * allocated for them and symbol address and value are same. So even
1203 * if init section is freed, its ok to reference those symbols.
1204 * For ex. symbols marking the init section boundaries.
1205 * This pattern is identified by
1206 * refsymname = __init_begin, _sinittext, _einittext
1207 *
1208 * Pattern 5:
1209 * GCC may optimize static inlines when fed constant arg(s) resulting
1210 * in functions like cpumask_empty() -- generating an associated symbol
1211 * cpumask_empty.constprop.3 that appears in the audit. If the const that
1212 * is passed in comes from __init, like say nmi_ipi_mask, we get a
1213 * meaningless section warning. May need to add isra symbols too...
1214 * This pattern is identified by
1215 * tosec = init section
1216 * fromsec = text section
1217 * refsymname = *.constprop.*
1218 *
David Brazdil0f672f62019-12-10 10:32:29 +00001219 * Pattern 6:
1220 * Hide section mismatch warnings for ELF local symbols. The goal
1221 * is to eliminate false positive modpost warnings caused by
1222 * compiler-generated ELF local symbol names such as ".LANCHOR1".
1223 * Autogenerated symbol names bypass modpost's "Pattern 2"
1224 * whitelisting, which relies on pattern-matching against symbol
1225 * names to work. (One situation where gcc can autogenerate ELF
1226 * local symbols is when "-fsection-anchors" is used.)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001227 **/
1228static int secref_whitelist(const struct sectioncheck *mismatch,
1229 const char *fromsec, const char *fromsym,
1230 const char *tosec, const char *tosym)
1231{
1232 /* Check for pattern 1 */
1233 if (match(tosec, init_data_sections) &&
1234 match(fromsec, data_sections) &&
1235 strstarts(fromsym, "__param"))
1236 return 0;
1237
1238 /* Check for pattern 1a */
1239 if (strcmp(tosec, ".init.text") == 0 &&
1240 match(fromsec, data_sections) &&
1241 strstarts(fromsym, "__param_ops_"))
1242 return 0;
1243
1244 /* Check for pattern 2 */
1245 if (match(tosec, init_exit_sections) &&
1246 match(fromsec, data_sections) &&
1247 match(fromsym, mismatch->symbol_white_list))
1248 return 0;
1249
1250 /* Check for pattern 3 */
1251 if (match(fromsec, head_sections) &&
1252 match(tosec, init_sections))
1253 return 0;
1254
1255 /* Check for pattern 4 */
1256 if (match(tosym, linker_symbols))
1257 return 0;
1258
1259 /* Check for pattern 5 */
1260 if (match(fromsec, text_sections) &&
1261 match(tosec, init_sections) &&
1262 match(fromsym, optim_symbols))
1263 return 0;
1264
David Brazdil0f672f62019-12-10 10:32:29 +00001265 /* Check for pattern 6 */
1266 if (strstarts(fromsym, ".L"))
1267 return 0;
1268
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001269 return 1;
1270}
1271
David Brazdil0f672f62019-12-10 10:32:29 +00001272static inline int is_arm_mapping_symbol(const char *str)
1273{
Olivier Deprez92d4c212022-12-06 15:05:30 +01001274 return str[0] == '$' &&
1275 (str[1] == 'a' || str[1] == 'd' || str[1] == 't' || str[1] == 'x')
David Brazdil0f672f62019-12-10 10:32:29 +00001276 && (str[2] == '\0' || str[2] == '.');
1277}
1278
1279/*
1280 * If there's no name there, ignore it; likewise, ignore it if it's
1281 * one of the magic symbols emitted used by current ARM tools.
1282 *
1283 * Otherwise if find_symbols_between() returns those symbols, they'll
1284 * fail the whitelist tests and cause lots of false alarms ... fixable
1285 * only by merging __exit and __init sections into __text, bloating
1286 * the kernel (which is especially evil on embedded platforms).
1287 */
1288static inline int is_valid_name(struct elf_info *elf, Elf_Sym *sym)
1289{
1290 const char *name = elf->strtab + sym->st_name;
1291
1292 if (!name || !strlen(name))
1293 return 0;
1294 return !is_arm_mapping_symbol(name);
1295}
1296
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001297/**
1298 * Find symbol based on relocation record info.
1299 * In some cases the symbol supplied is a valid symbol so
1300 * return refsym. If st_name != 0 we assume this is a valid symbol.
1301 * In other cases the symbol needs to be looked up in the symbol table
1302 * based on section and address.
1303 * **/
1304static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,
1305 Elf_Sym *relsym)
1306{
1307 Elf_Sym *sym;
1308 Elf_Sym *near = NULL;
1309 Elf64_Sword distance = 20;
1310 Elf64_Sword d;
1311 unsigned int relsym_secindex;
1312
1313 if (relsym->st_name != 0)
1314 return relsym;
1315
1316 relsym_secindex = get_secindex(elf, relsym);
1317 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
1318 if (get_secindex(elf, sym) != relsym_secindex)
1319 continue;
1320 if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
1321 continue;
David Brazdil0f672f62019-12-10 10:32:29 +00001322 if (!is_valid_name(elf, sym))
1323 continue;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001324 if (sym->st_value == addr)
1325 return sym;
1326 /* Find a symbol nearby - addr are maybe negative */
1327 d = sym->st_value - addr;
1328 if (d < 0)
1329 d = addr - sym->st_value;
1330 if (d < distance) {
1331 distance = d;
1332 near = sym;
1333 }
1334 }
1335 /* We need a close match */
1336 if (distance < 20)
1337 return near;
1338 else
1339 return NULL;
1340}
1341
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001342/*
1343 * Find symbols before or equal addr and after addr - in the section sec.
1344 * If we find two symbols with equal offset prefer one with a valid name.
1345 * The ELF format may have a better way to detect what type of symbol
1346 * it is, but this works for now.
1347 **/
1348static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
1349 const char *sec)
1350{
1351 Elf_Sym *sym;
1352 Elf_Sym *near = NULL;
1353 Elf_Addr distance = ~0;
1354
1355 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
1356 const char *symsec;
1357
1358 if (is_shndx_special(sym->st_shndx))
1359 continue;
1360 symsec = sec_name(elf, get_secindex(elf, sym));
1361 if (strcmp(symsec, sec) != 0)
1362 continue;
1363 if (!is_valid_name(elf, sym))
1364 continue;
1365 if (sym->st_value <= addr) {
1366 if ((addr - sym->st_value) < distance) {
1367 distance = addr - sym->st_value;
1368 near = sym;
1369 } else if ((addr - sym->st_value) == distance) {
1370 near = sym;
1371 }
1372 }
1373 }
1374 return near;
1375}
1376
1377/*
1378 * Convert a section name to the function/data attribute
1379 * .init.text => __init
1380 * .memexitconst => __memconst
1381 * etc.
1382 *
1383 * The memory of returned value has been allocated on a heap. The user of this
1384 * method should free it after usage.
1385*/
1386static char *sec2annotation(const char *s)
1387{
1388 if (match(s, init_exit_sections)) {
1389 char *p = NOFAIL(malloc(20));
1390 char *r = p;
1391
1392 *p++ = '_';
1393 *p++ = '_';
1394 if (*s == '.')
1395 s++;
1396 while (*s && *s != '.')
1397 *p++ = *s++;
1398 *p = '\0';
1399 if (*s == '.')
1400 s++;
1401 if (strstr(s, "rodata") != NULL)
1402 strcat(p, "const ");
1403 else if (strstr(s, "data") != NULL)
1404 strcat(p, "data ");
1405 else
1406 strcat(p, " ");
1407 return r;
1408 } else {
1409 return NOFAIL(strdup(""));
1410 }
1411}
1412
1413static int is_function(Elf_Sym *sym)
1414{
1415 if (sym)
1416 return ELF_ST_TYPE(sym->st_info) == STT_FUNC;
1417 else
1418 return -1;
1419}
1420
1421static void print_section_list(const char * const list[20])
1422{
1423 const char *const *s = list;
1424
1425 while (*s) {
1426 fprintf(stderr, "%s", *s);
1427 s++;
1428 if (*s)
1429 fprintf(stderr, ", ");
1430 }
1431 fprintf(stderr, "\n");
1432}
1433
1434static inline void get_pretty_name(int is_func, const char** name, const char** name_p)
1435{
1436 switch (is_func) {
1437 case 0: *name = "variable"; *name_p = ""; break;
1438 case 1: *name = "function"; *name_p = "()"; break;
1439 default: *name = "(unknown reference)"; *name_p = ""; break;
1440 }
1441}
1442
1443/*
1444 * Print a warning about a section mismatch.
1445 * Try to find symbols near it so user can find it.
1446 * Check whitelist before warning - it may be a false positive.
1447 */
1448static void report_sec_mismatch(const char *modname,
1449 const struct sectioncheck *mismatch,
1450 const char *fromsec,
1451 unsigned long long fromaddr,
1452 const char *fromsym,
1453 int from_is_func,
1454 const char *tosec, const char *tosym,
1455 int to_is_func)
1456{
1457 const char *from, *from_p;
1458 const char *to, *to_p;
1459 char *prl_from;
1460 char *prl_to;
1461
1462 sec_mismatch_count++;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001463
1464 get_pretty_name(from_is_func, &from, &from_p);
1465 get_pretty_name(to_is_func, &to, &to_p);
1466
1467 warn("%s(%s+0x%llx): Section mismatch in reference from the %s %s%s "
1468 "to the %s %s:%s%s\n",
1469 modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec,
1470 tosym, to_p);
1471
1472 switch (mismatch->mismatch) {
1473 case TEXT_TO_ANY_INIT:
1474 prl_from = sec2annotation(fromsec);
1475 prl_to = sec2annotation(tosec);
1476 fprintf(stderr,
1477 "The function %s%s() references\n"
1478 "the %s %s%s%s.\n"
1479 "This is often because %s lacks a %s\n"
1480 "annotation or the annotation of %s is wrong.\n",
1481 prl_from, fromsym,
1482 to, prl_to, tosym, to_p,
1483 fromsym, prl_to, tosym);
1484 free(prl_from);
1485 free(prl_to);
1486 break;
1487 case DATA_TO_ANY_INIT: {
1488 prl_to = sec2annotation(tosec);
1489 fprintf(stderr,
1490 "The variable %s references\n"
1491 "the %s %s%s%s\n"
1492 "If the reference is valid then annotate the\n"
1493 "variable with __init* or __refdata (see linux/init.h) "
1494 "or name the variable:\n",
1495 fromsym, to, prl_to, tosym, to_p);
1496 print_section_list(mismatch->symbol_white_list);
1497 free(prl_to);
1498 break;
1499 }
1500 case TEXT_TO_ANY_EXIT:
1501 prl_to = sec2annotation(tosec);
1502 fprintf(stderr,
1503 "The function %s() references a %s in an exit section.\n"
1504 "Often the %s %s%s has valid usage outside the exit section\n"
1505 "and the fix is to remove the %sannotation of %s.\n",
1506 fromsym, to, to, tosym, to_p, prl_to, tosym);
1507 free(prl_to);
1508 break;
1509 case DATA_TO_ANY_EXIT: {
1510 prl_to = sec2annotation(tosec);
1511 fprintf(stderr,
1512 "The variable %s references\n"
1513 "the %s %s%s%s\n"
1514 "If the reference is valid then annotate the\n"
1515 "variable with __exit* (see linux/init.h) or "
1516 "name the variable:\n",
1517 fromsym, to, prl_to, tosym, to_p);
1518 print_section_list(mismatch->symbol_white_list);
1519 free(prl_to);
1520 break;
1521 }
1522 case XXXINIT_TO_SOME_INIT:
1523 case XXXEXIT_TO_SOME_EXIT:
1524 prl_from = sec2annotation(fromsec);
1525 prl_to = sec2annotation(tosec);
1526 fprintf(stderr,
1527 "The %s %s%s%s references\n"
1528 "a %s %s%s%s.\n"
1529 "If %s is only used by %s then\n"
1530 "annotate %s with a matching annotation.\n",
1531 from, prl_from, fromsym, from_p,
1532 to, prl_to, tosym, to_p,
1533 tosym, fromsym, tosym);
1534 free(prl_from);
1535 free(prl_to);
1536 break;
1537 case ANY_INIT_TO_ANY_EXIT:
1538 prl_from = sec2annotation(fromsec);
1539 prl_to = sec2annotation(tosec);
1540 fprintf(stderr,
1541 "The %s %s%s%s references\n"
1542 "a %s %s%s%s.\n"
1543 "This is often seen when error handling "
1544 "in the init function\n"
1545 "uses functionality in the exit path.\n"
1546 "The fix is often to remove the %sannotation of\n"
1547 "%s%s so it may be used outside an exit section.\n",
1548 from, prl_from, fromsym, from_p,
1549 to, prl_to, tosym, to_p,
1550 prl_to, tosym, to_p);
1551 free(prl_from);
1552 free(prl_to);
1553 break;
1554 case ANY_EXIT_TO_ANY_INIT:
1555 prl_from = sec2annotation(fromsec);
1556 prl_to = sec2annotation(tosec);
1557 fprintf(stderr,
1558 "The %s %s%s%s references\n"
1559 "a %s %s%s%s.\n"
1560 "This is often seen when error handling "
1561 "in the exit function\n"
1562 "uses functionality in the init path.\n"
1563 "The fix is often to remove the %sannotation of\n"
1564 "%s%s so it may be used outside an init section.\n",
1565 from, prl_from, fromsym, from_p,
1566 to, prl_to, tosym, to_p,
1567 prl_to, tosym, to_p);
1568 free(prl_from);
1569 free(prl_to);
1570 break;
1571 case EXPORT_TO_INIT_EXIT:
1572 prl_to = sec2annotation(tosec);
1573 fprintf(stderr,
1574 "The symbol %s is exported and annotated %s\n"
1575 "Fix this by removing the %sannotation of %s "
1576 "or drop the export.\n",
1577 tosym, prl_to, prl_to, tosym);
1578 free(prl_to);
1579 break;
1580 case EXTABLE_TO_NON_TEXT:
1581 fatal("There's a special handler for this mismatch type, "
1582 "we should never get here.");
1583 break;
1584 }
1585 fprintf(stderr, "\n");
1586}
1587
1588static void default_mismatch_handler(const char *modname, struct elf_info *elf,
1589 const struct sectioncheck* const mismatch,
1590 Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
1591{
1592 const char *tosec;
1593 Elf_Sym *to;
1594 Elf_Sym *from;
1595 const char *tosym;
1596 const char *fromsym;
1597
1598 from = find_elf_symbol2(elf, r->r_offset, fromsec);
1599 fromsym = sym_name(elf, from);
1600
1601 if (strstarts(fromsym, "reference___initcall"))
1602 return;
1603
1604 tosec = sec_name(elf, get_secindex(elf, sym));
1605 to = find_elf_symbol(elf, r->r_addend, sym);
1606 tosym = sym_name(elf, to);
1607
1608 /* check whitelist - we may ignore it */
1609 if (secref_whitelist(mismatch,
1610 fromsec, fromsym, tosec, tosym)) {
1611 report_sec_mismatch(modname, mismatch,
1612 fromsec, r->r_offset, fromsym,
1613 is_function(from), tosec, tosym,
1614 is_function(to));
1615 }
1616}
1617
1618static int is_executable_section(struct elf_info* elf, unsigned int section_index)
1619{
1620 if (section_index > elf->num_sections)
1621 fatal("section_index is outside elf->num_sections!\n");
1622
1623 return ((elf->sechdrs[section_index].sh_flags & SHF_EXECINSTR) == SHF_EXECINSTR);
1624}
1625
1626/*
1627 * We rely on a gross hack in section_rel[a]() calling find_extable_entry_size()
1628 * to know the sizeof(struct exception_table_entry) for the target architecture.
1629 */
1630static unsigned int extable_entry_size = 0;
1631static void find_extable_entry_size(const char* const sec, const Elf_Rela* r)
1632{
1633 /*
1634 * If we're currently checking the second relocation within __ex_table,
1635 * that relocation offset tells us the offsetof(struct
1636 * exception_table_entry, fixup) which is equal to sizeof(struct
1637 * exception_table_entry) divided by two. We use that to our advantage
1638 * since there's no portable way to get that size as every architecture
1639 * seems to go with different sized types. Not pretty but better than
1640 * hard-coding the size for every architecture..
1641 */
1642 if (!extable_entry_size)
1643 extable_entry_size = r->r_offset * 2;
1644}
1645
1646static inline bool is_extable_fault_address(Elf_Rela *r)
1647{
1648 /*
1649 * extable_entry_size is only discovered after we've handled the
1650 * _second_ relocation in __ex_table, so only abort when we're not
1651 * handling the first reloc and extable_entry_size is zero.
1652 */
1653 if (r->r_offset && extable_entry_size == 0)
1654 fatal("extable_entry size hasn't been discovered!\n");
1655
1656 return ((r->r_offset == 0) ||
1657 (r->r_offset % extable_entry_size == 0));
1658}
1659
1660#define is_second_extable_reloc(Start, Cur, Sec) \
1661 (((Cur) == (Start) + 1) && (strcmp("__ex_table", (Sec)) == 0))
1662
1663static void report_extable_warnings(const char* modname, struct elf_info* elf,
1664 const struct sectioncheck* const mismatch,
1665 Elf_Rela* r, Elf_Sym* sym,
1666 const char* fromsec, const char* tosec)
1667{
1668 Elf_Sym* fromsym = find_elf_symbol2(elf, r->r_offset, fromsec);
1669 const char* fromsym_name = sym_name(elf, fromsym);
1670 Elf_Sym* tosym = find_elf_symbol(elf, r->r_addend, sym);
1671 const char* tosym_name = sym_name(elf, tosym);
1672 const char* from_pretty_name;
1673 const char* from_pretty_name_p;
1674 const char* to_pretty_name;
1675 const char* to_pretty_name_p;
1676
1677 get_pretty_name(is_function(fromsym),
1678 &from_pretty_name, &from_pretty_name_p);
1679 get_pretty_name(is_function(tosym),
1680 &to_pretty_name, &to_pretty_name_p);
1681
1682 warn("%s(%s+0x%lx): Section mismatch in reference"
1683 " from the %s %s%s to the %s %s:%s%s\n",
1684 modname, fromsec, (long)r->r_offset, from_pretty_name,
1685 fromsym_name, from_pretty_name_p,
1686 to_pretty_name, tosec, tosym_name, to_pretty_name_p);
1687
1688 if (!match(tosec, mismatch->bad_tosec) &&
1689 is_executable_section(elf, get_secindex(elf, sym)))
1690 fprintf(stderr,
1691 "The relocation at %s+0x%lx references\n"
1692 "section \"%s\" which is not in the list of\n"
1693 "authorized sections. If you're adding a new section\n"
1694 "and/or if this reference is valid, add \"%s\" to the\n"
1695 "list of authorized sections to jump to on fault.\n"
1696 "This can be achieved by adding \"%s\" to \n"
1697 "OTHER_TEXT_SECTIONS in scripts/mod/modpost.c.\n",
1698 fromsec, (long)r->r_offset, tosec, tosec, tosec);
1699}
1700
1701static void extable_mismatch_handler(const char* modname, struct elf_info *elf,
1702 const struct sectioncheck* const mismatch,
1703 Elf_Rela* r, Elf_Sym* sym,
1704 const char *fromsec)
1705{
1706 const char* tosec = sec_name(elf, get_secindex(elf, sym));
1707
1708 sec_mismatch_count++;
1709
David Brazdil0f672f62019-12-10 10:32:29 +00001710 report_extable_warnings(modname, elf, mismatch, r, sym, fromsec, tosec);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001711
1712 if (match(tosec, mismatch->bad_tosec))
1713 fatal("The relocation at %s+0x%lx references\n"
1714 "section \"%s\" which is black-listed.\n"
1715 "Something is seriously wrong and should be fixed.\n"
1716 "You might get more information about where this is\n"
1717 "coming from by using scripts/check_extable.sh %s\n",
1718 fromsec, (long)r->r_offset, tosec, modname);
1719 else if (!is_executable_section(elf, get_secindex(elf, sym))) {
1720 if (is_extable_fault_address(r))
1721 fatal("The relocation at %s+0x%lx references\n"
1722 "section \"%s\" which is not executable, IOW\n"
1723 "it is not possible for the kernel to fault\n"
1724 "at that address. Something is seriously wrong\n"
1725 "and should be fixed.\n",
1726 fromsec, (long)r->r_offset, tosec);
1727 else
1728 fatal("The relocation at %s+0x%lx references\n"
1729 "section \"%s\" which is not executable, IOW\n"
1730 "the kernel will fault if it ever tries to\n"
1731 "jump to it. Something is seriously wrong\n"
1732 "and should be fixed.\n",
1733 fromsec, (long)r->r_offset, tosec);
1734 }
1735}
1736
1737static void check_section_mismatch(const char *modname, struct elf_info *elf,
1738 Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
1739{
1740 const char *tosec = sec_name(elf, get_secindex(elf, sym));
1741 const struct sectioncheck *mismatch = section_mismatch(fromsec, tosec);
1742
1743 if (mismatch) {
1744 if (mismatch->handler)
1745 mismatch->handler(modname, elf, mismatch,
1746 r, sym, fromsec);
1747 else
1748 default_mismatch_handler(modname, elf, mismatch,
1749 r, sym, fromsec);
1750 }
1751}
1752
1753static unsigned int *reloc_location(struct elf_info *elf,
1754 Elf_Shdr *sechdr, Elf_Rela *r)
1755{
Olivier Deprez157378f2022-04-04 15:47:50 +02001756 return sym_get_data_by_offset(elf, sechdr->sh_info, r->r_offset);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001757}
1758
1759static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
1760{
1761 unsigned int r_typ = ELF_R_TYPE(r->r_info);
1762 unsigned int *location = reloc_location(elf, sechdr, r);
1763
1764 switch (r_typ) {
1765 case R_386_32:
1766 r->r_addend = TO_NATIVE(*location);
1767 break;
1768 case R_386_PC32:
1769 r->r_addend = TO_NATIVE(*location) + 4;
1770 /* For CONFIG_RELOCATABLE=y */
1771 if (elf->hdr->e_type == ET_EXEC)
1772 r->r_addend += r->r_offset;
1773 break;
1774 }
1775 return 0;
1776}
1777
1778#ifndef R_ARM_CALL
1779#define R_ARM_CALL 28
1780#endif
1781#ifndef R_ARM_JUMP24
1782#define R_ARM_JUMP24 29
1783#endif
1784
1785#ifndef R_ARM_THM_CALL
1786#define R_ARM_THM_CALL 10
1787#endif
1788#ifndef R_ARM_THM_JUMP24
1789#define R_ARM_THM_JUMP24 30
1790#endif
1791#ifndef R_ARM_THM_JUMP19
1792#define R_ARM_THM_JUMP19 51
1793#endif
1794
1795static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
1796{
1797 unsigned int r_typ = ELF_R_TYPE(r->r_info);
1798
1799 switch (r_typ) {
1800 case R_ARM_ABS32:
1801 /* From ARM ABI: (S + A) | T */
1802 r->r_addend = (int)(long)
1803 (elf->symtab_start + ELF_R_SYM(r->r_info));
1804 break;
1805 case R_ARM_PC24:
1806 case R_ARM_CALL:
1807 case R_ARM_JUMP24:
1808 case R_ARM_THM_CALL:
1809 case R_ARM_THM_JUMP24:
1810 case R_ARM_THM_JUMP19:
1811 /* From ARM ABI: ((S + A) | T) - P */
1812 r->r_addend = (int)(long)(elf->hdr +
1813 sechdr->sh_offset +
1814 (r->r_offset - sechdr->sh_addr));
1815 break;
1816 default:
1817 return 1;
1818 }
1819 return 0;
1820}
1821
1822static int addend_mips_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
1823{
1824 unsigned int r_typ = ELF_R_TYPE(r->r_info);
1825 unsigned int *location = reloc_location(elf, sechdr, r);
1826 unsigned int inst;
1827
1828 if (r_typ == R_MIPS_HI16)
1829 return 1; /* skip this */
1830 inst = TO_NATIVE(*location);
1831 switch (r_typ) {
1832 case R_MIPS_LO16:
1833 r->r_addend = inst & 0xffff;
1834 break;
1835 case R_MIPS_26:
1836 r->r_addend = (inst & 0x03ffffff) << 2;
1837 break;
1838 case R_MIPS_32:
1839 r->r_addend = inst;
1840 break;
1841 }
1842 return 0;
1843}
1844
1845static void section_rela(const char *modname, struct elf_info *elf,
1846 Elf_Shdr *sechdr)
1847{
1848 Elf_Sym *sym;
1849 Elf_Rela *rela;
1850 Elf_Rela r;
1851 unsigned int r_sym;
1852 const char *fromsec;
1853
1854 Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset;
1855 Elf_Rela *stop = (void *)start + sechdr->sh_size;
1856
1857 fromsec = sech_name(elf, sechdr);
1858 fromsec += strlen(".rela");
1859 /* if from section (name) is know good then skip it */
1860 if (match(fromsec, section_white_list))
1861 return;
1862
1863 for (rela = start; rela < stop; rela++) {
1864 r.r_offset = TO_NATIVE(rela->r_offset);
1865#if KERNEL_ELFCLASS == ELFCLASS64
1866 if (elf->hdr->e_machine == EM_MIPS) {
1867 unsigned int r_typ;
1868 r_sym = ELF64_MIPS_R_SYM(rela->r_info);
1869 r_sym = TO_NATIVE(r_sym);
1870 r_typ = ELF64_MIPS_R_TYPE(rela->r_info);
1871 r.r_info = ELF64_R_INFO(r_sym, r_typ);
1872 } else {
1873 r.r_info = TO_NATIVE(rela->r_info);
1874 r_sym = ELF_R_SYM(r.r_info);
1875 }
1876#else
1877 r.r_info = TO_NATIVE(rela->r_info);
1878 r_sym = ELF_R_SYM(r.r_info);
1879#endif
1880 r.r_addend = TO_NATIVE(rela->r_addend);
1881 sym = elf->symtab_start + r_sym;
1882 /* Skip special sections */
1883 if (is_shndx_special(sym->st_shndx))
1884 continue;
1885 if (is_second_extable_reloc(start, rela, fromsec))
1886 find_extable_entry_size(fromsec, &r);
1887 check_section_mismatch(modname, elf, &r, sym, fromsec);
1888 }
1889}
1890
1891static void section_rel(const char *modname, struct elf_info *elf,
1892 Elf_Shdr *sechdr)
1893{
1894 Elf_Sym *sym;
1895 Elf_Rel *rel;
1896 Elf_Rela r;
1897 unsigned int r_sym;
1898 const char *fromsec;
1899
1900 Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset;
1901 Elf_Rel *stop = (void *)start + sechdr->sh_size;
1902
1903 fromsec = sech_name(elf, sechdr);
1904 fromsec += strlen(".rel");
1905 /* if from section (name) is know good then skip it */
1906 if (match(fromsec, section_white_list))
1907 return;
1908
1909 for (rel = start; rel < stop; rel++) {
1910 r.r_offset = TO_NATIVE(rel->r_offset);
1911#if KERNEL_ELFCLASS == ELFCLASS64
1912 if (elf->hdr->e_machine == EM_MIPS) {
1913 unsigned int r_typ;
1914 r_sym = ELF64_MIPS_R_SYM(rel->r_info);
1915 r_sym = TO_NATIVE(r_sym);
1916 r_typ = ELF64_MIPS_R_TYPE(rel->r_info);
1917 r.r_info = ELF64_R_INFO(r_sym, r_typ);
1918 } else {
1919 r.r_info = TO_NATIVE(rel->r_info);
1920 r_sym = ELF_R_SYM(r.r_info);
1921 }
1922#else
1923 r.r_info = TO_NATIVE(rel->r_info);
1924 r_sym = ELF_R_SYM(r.r_info);
1925#endif
1926 r.r_addend = 0;
1927 switch (elf->hdr->e_machine) {
1928 case EM_386:
1929 if (addend_386_rel(elf, sechdr, &r))
1930 continue;
1931 break;
1932 case EM_ARM:
1933 if (addend_arm_rel(elf, sechdr, &r))
1934 continue;
1935 break;
1936 case EM_MIPS:
1937 if (addend_mips_rel(elf, sechdr, &r))
1938 continue;
1939 break;
1940 }
1941 sym = elf->symtab_start + r_sym;
1942 /* Skip special sections */
1943 if (is_shndx_special(sym->st_shndx))
1944 continue;
1945 if (is_second_extable_reloc(start, rel, fromsec))
1946 find_extable_entry_size(fromsec, &r);
1947 check_section_mismatch(modname, elf, &r, sym, fromsec);
1948 }
1949}
1950
1951/**
1952 * A module includes a number of sections that are discarded
1953 * either when loaded or when used as built-in.
1954 * For loaded modules all functions marked __init and all data
1955 * marked __initdata will be discarded when the module has been initialized.
1956 * Likewise for modules used built-in the sections marked __exit
1957 * are discarded because __exit marked function are supposed to be called
1958 * only when a module is unloaded which never happens for built-in modules.
1959 * The check_sec_ref() function traverses all relocation records
1960 * to find all references to a section that reference a section that will
1961 * be discarded and warns about it.
1962 **/
1963static void check_sec_ref(struct module *mod, const char *modname,
1964 struct elf_info *elf)
1965{
1966 int i;
1967 Elf_Shdr *sechdrs = elf->sechdrs;
1968
1969 /* Walk through all sections */
1970 for (i = 0; i < elf->num_sections; i++) {
1971 check_section(modname, elf, &elf->sechdrs[i]);
1972 /* We want to process only relocation sections and not .init */
1973 if (sechdrs[i].sh_type == SHT_RELA)
1974 section_rela(modname, elf, &elf->sechdrs[i]);
1975 else if (sechdrs[i].sh_type == SHT_REL)
1976 section_rel(modname, elf, &elf->sechdrs[i]);
1977 }
1978}
1979
1980static char *remove_dot(char *s)
1981{
1982 size_t n = strcspn(s, ".");
1983
1984 if (n && s[n]) {
1985 size_t m = strspn(s + n + 1, "0123456789");
Olivier Deprez92d4c212022-12-06 15:05:30 +01001986 if (m && (s[n + m + 1] == '.' || s[n + m + 1] == 0))
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001987 s[n] = 0;
1988 }
1989 return s;
1990}
1991
1992static void read_symbols(const char *modname)
1993{
1994 const char *symname;
1995 char *version;
1996 char *license;
David Brazdil0f672f62019-12-10 10:32:29 +00001997 char *namespace;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001998 struct module *mod;
1999 struct elf_info info = { };
2000 Elf_Sym *sym;
2001
2002 if (!parse_elf(&info, modname))
2003 return;
2004
Olivier Deprez157378f2022-04-04 15:47:50 +02002005 {
2006 char *tmp;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002007
Olivier Deprez157378f2022-04-04 15:47:50 +02002008 /* strip trailing .o */
2009 tmp = NOFAIL(strdup(modname));
2010 tmp[strlen(tmp) - 2] = '\0';
2011 mod = new_module(tmp);
2012 free(tmp);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002013 }
2014
Olivier Deprez157378f2022-04-04 15:47:50 +02002015 if (!mod->is_vmlinux) {
2016 license = get_modinfo(&info, "license");
2017 if (!license)
2018 warn("missing MODULE_LICENSE() in %s\n", modname);
2019 while (license) {
2020 if (license_is_gpl_compatible(license))
2021 mod->gpl_compatible = 1;
2022 else {
2023 mod->gpl_compatible = 0;
2024 break;
2025 }
2026 license = get_next_modinfo(&info, "license", license);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002027 }
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002028
Olivier Deprez157378f2022-04-04 15:47:50 +02002029 namespace = get_modinfo(&info, "import_ns");
2030 while (namespace) {
2031 add_namespace(&mod->imported_namespaces, namespace);
2032 namespace = get_next_modinfo(&info, "import_ns",
2033 namespace);
2034 }
David Brazdil0f672f62019-12-10 10:32:29 +00002035 }
2036
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002037 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
2038 symname = remove_dot(info.strtab + sym->st_name);
2039
Olivier Deprez157378f2022-04-04 15:47:50 +02002040 handle_symbol(mod, &info, sym, symname);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002041 handle_moddevtable(mod, &info, sym, symname);
2042 }
David Brazdil0f672f62019-12-10 10:32:29 +00002043
David Brazdil0f672f62019-12-10 10:32:29 +00002044 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
2045 symname = remove_dot(info.strtab + sym->st_name);
2046
Olivier Deprez157378f2022-04-04 15:47:50 +02002047 /* Apply symbol namespaces from __kstrtabns_<symbol> entries. */
David Brazdil0f672f62019-12-10 10:32:29 +00002048 if (strstarts(symname, "__kstrtabns_"))
2049 sym_update_namespace(symname + strlen("__kstrtabns_"),
2050 namespace_from_kstrtabns(&info,
2051 sym));
Olivier Deprez157378f2022-04-04 15:47:50 +02002052
2053 if (strstarts(symname, "__crc_"))
2054 handle_modversion(mod, &info, sym,
2055 symname + strlen("__crc_"));
David Brazdil0f672f62019-12-10 10:32:29 +00002056 }
2057
2058 // check for static EXPORT_SYMBOL_* functions && global vars
2059 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
2060 unsigned char bind = ELF_ST_BIND(sym->st_info);
2061
2062 if (bind == STB_GLOBAL || bind == STB_WEAK) {
2063 struct symbol *s =
2064 find_symbol(remove_dot(info.strtab +
2065 sym->st_name));
2066
2067 if (s)
2068 s->is_static = 0;
2069 }
2070 }
2071
Olivier Deprez157378f2022-04-04 15:47:50 +02002072 check_sec_ref(mod, modname, &info);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002073
Olivier Deprez157378f2022-04-04 15:47:50 +02002074 if (!mod->is_vmlinux) {
2075 version = get_modinfo(&info, "version");
2076 if (version || all_versions)
2077 get_src_version(modname, mod->srcversion,
2078 sizeof(mod->srcversion) - 1);
2079 }
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002080
2081 parse_elf_finish(&info);
2082
2083 /* Our trick to get versioning for module struct etc. - it's
2084 * never passed as an argument to an exported function, so
2085 * the automatic versioning doesn't pick it up, but it's really
2086 * important anyhow */
2087 if (modversions)
2088 mod->unres = alloc_symbol("module_layout", 0, mod->unres);
2089}
2090
2091static void read_symbols_from_files(const char *filename)
2092{
2093 FILE *in = stdin;
2094 char fname[PATH_MAX];
2095
2096 if (strcmp(filename, "-") != 0) {
2097 in = fopen(filename, "r");
2098 if (!in)
2099 fatal("Can't open filenames file %s: %m", filename);
2100 }
2101
2102 while (fgets(fname, PATH_MAX, in) != NULL) {
2103 if (strends(fname, "\n"))
2104 fname[strlen(fname)-1] = '\0';
2105 read_symbols(fname);
2106 }
2107
2108 if (in != stdin)
2109 fclose(in);
2110}
2111
2112#define SZ 500
2113
2114/* We first write the generated file into memory using the
2115 * following helper, then compare to the file on disk and
2116 * only update the later if anything changed */
2117
2118void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf,
2119 const char *fmt, ...)
2120{
2121 char tmp[SZ];
2122 int len;
2123 va_list ap;
2124
2125 va_start(ap, fmt);
2126 len = vsnprintf(tmp, SZ, fmt, ap);
2127 buf_write(buf, tmp, len);
2128 va_end(ap);
2129}
2130
2131void buf_write(struct buffer *buf, const char *s, int len)
2132{
2133 if (buf->size - buf->pos < len) {
2134 buf->size += len + SZ;
2135 buf->p = NOFAIL(realloc(buf->p, buf->size));
2136 }
2137 strncpy(buf->p + buf->pos, s, len);
2138 buf->pos += len;
2139}
2140
2141static void check_for_gpl_usage(enum export exp, const char *m, const char *s)
2142{
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002143 switch (exp) {
2144 case export_gpl:
Olivier Deprez157378f2022-04-04 15:47:50 +02002145 fatal("GPL-incompatible module %s.ko uses GPL-only symbol '%s'\n",
2146 m, s);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002147 break;
2148 case export_unused_gpl:
Olivier Deprez157378f2022-04-04 15:47:50 +02002149 fatal("GPL-incompatible module %s.ko uses GPL-only symbol marked UNUSED '%s'\n",
2150 m, s);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002151 break;
2152 case export_gpl_future:
Olivier Deprez157378f2022-04-04 15:47:50 +02002153 warn("GPL-incompatible module %s.ko uses future GPL-only symbol '%s'\n",
2154 m, s);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002155 break;
2156 case export_plain:
2157 case export_unused:
2158 case export_unknown:
2159 /* ignore */
2160 break;
2161 }
2162}
2163
2164static void check_for_unused(enum export exp, const char *m, const char *s)
2165{
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002166 switch (exp) {
2167 case export_unused:
2168 case export_unused_gpl:
Olivier Deprez157378f2022-04-04 15:47:50 +02002169 warn("module %s.ko uses symbol '%s' marked UNUSED\n",
2170 m, s);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002171 break;
2172 default:
2173 /* ignore */
2174 break;
2175 }
2176}
2177
David Brazdil0f672f62019-12-10 10:32:29 +00002178static int check_exports(struct module *mod)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002179{
2180 struct symbol *s, *exp;
David Brazdil0f672f62019-12-10 10:32:29 +00002181 int err = 0;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002182
2183 for (s = mod->unres; s; s = s->next) {
2184 const char *basename;
2185 exp = find_symbol(s->name);
David Brazdil0f672f62019-12-10 10:32:29 +00002186 if (!exp || exp->module == mod) {
2187 if (have_vmlinux && !s->weak) {
Olivier Deprez157378f2022-04-04 15:47:50 +02002188 modpost_log(warn_unresolved ? LOG_WARN : LOG_ERROR,
2189 "\"%s\" [%s.ko] undefined!\n",
2190 s->name, mod->name);
2191 if (!warn_unresolved)
David Brazdil0f672f62019-12-10 10:32:29 +00002192 err = 1;
David Brazdil0f672f62019-12-10 10:32:29 +00002193 }
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002194 continue;
David Brazdil0f672f62019-12-10 10:32:29 +00002195 }
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002196 basename = strrchr(mod->name, '/');
2197 if (basename)
2198 basename++;
2199 else
2200 basename = mod->name;
David Brazdil0f672f62019-12-10 10:32:29 +00002201
Olivier Deprez157378f2022-04-04 15:47:50 +02002202 if (exp->namespace &&
2203 !module_imports_namespace(mod, exp->namespace)) {
2204 modpost_log(allow_missing_ns_imports ? LOG_WARN : LOG_ERROR,
2205 "module %s uses symbol %s from namespace %s, but does not import it.\n",
2206 basename, exp->name, exp->namespace);
2207 if (!allow_missing_ns_imports)
2208 err = 1;
2209 add_namespace(&mod->missing_namespaces, exp->namespace);
David Brazdil0f672f62019-12-10 10:32:29 +00002210 }
2211
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002212 if (!mod->gpl_compatible)
2213 check_for_gpl_usage(exp->export, basename, exp->name);
2214 check_for_unused(exp->export, basename, exp->name);
2215 }
David Brazdil0f672f62019-12-10 10:32:29 +00002216
2217 return err;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002218}
2219
2220static int check_modname_len(struct module *mod)
2221{
2222 const char *mod_name;
2223
2224 mod_name = strrchr(mod->name, '/');
2225 if (mod_name == NULL)
2226 mod_name = mod->name;
2227 else
2228 mod_name++;
2229 if (strlen(mod_name) >= MODULE_NAME_LEN) {
2230 merror("module name is too long [%s.ko]\n", mod->name);
2231 return 1;
2232 }
2233
2234 return 0;
2235}
2236
2237/**
2238 * Header for the generated file
2239 **/
2240static void add_header(struct buffer *b, struct module *mod)
2241{
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002242 buf_printf(b, "#include <linux/module.h>\n");
Olivier Deprez157378f2022-04-04 15:47:50 +02002243 /*
2244 * Include build-salt.h after module.h in order to
2245 * inherit the definitions.
2246 */
2247 buf_printf(b, "#define INCLUDE_VERMAGIC\n");
2248 buf_printf(b, "#include <linux/build-salt.h>\n");
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002249 buf_printf(b, "#include <linux/vermagic.h>\n");
2250 buf_printf(b, "#include <linux/compiler.h>\n");
2251 buf_printf(b, "\n");
2252 buf_printf(b, "BUILD_SALT;\n");
2253 buf_printf(b, "\n");
2254 buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
2255 buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n");
2256 buf_printf(b, "\n");
2257 buf_printf(b, "__visible struct module __this_module\n");
Olivier Deprez157378f2022-04-04 15:47:50 +02002258 buf_printf(b, "__section(\".gnu.linkonce.this_module\") = {\n");
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002259 buf_printf(b, "\t.name = KBUILD_MODNAME,\n");
2260 if (mod->has_init)
2261 buf_printf(b, "\t.init = init_module,\n");
2262 if (mod->has_cleanup)
2263 buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n"
2264 "\t.exit = cleanup_module,\n"
2265 "#endif\n");
2266 buf_printf(b, "\t.arch = MODULE_ARCH_INIT,\n");
2267 buf_printf(b, "};\n");
2268}
2269
2270static void add_intree_flag(struct buffer *b, int is_intree)
2271{
2272 if (is_intree)
2273 buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n");
2274}
2275
2276/* Cannot check for assembler */
2277static void add_retpoline(struct buffer *b)
2278{
David Brazdil0f672f62019-12-10 10:32:29 +00002279 buf_printf(b, "\n#ifdef CONFIG_RETPOLINE\n");
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002280 buf_printf(b, "MODULE_INFO(retpoline, \"Y\");\n");
2281 buf_printf(b, "#endif\n");
2282}
2283
2284static void add_staging_flag(struct buffer *b, const char *name)
2285{
2286 if (strstarts(name, "drivers/staging"))
2287 buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
2288}
2289
2290/**
2291 * Record CRCs for unresolved symbols
2292 **/
2293static int add_versions(struct buffer *b, struct module *mod)
2294{
2295 struct symbol *s, *exp;
2296 int err = 0;
2297
2298 for (s = mod->unres; s; s = s->next) {
2299 exp = find_symbol(s->name);
David Brazdil0f672f62019-12-10 10:32:29 +00002300 if (!exp || exp->module == mod)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002301 continue;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002302 s->module = exp->module;
2303 s->crc_valid = exp->crc_valid;
2304 s->crc = exp->crc;
2305 }
2306
2307 if (!modversions)
2308 return err;
2309
2310 buf_printf(b, "\n");
2311 buf_printf(b, "static const struct modversion_info ____versions[]\n");
Olivier Deprez157378f2022-04-04 15:47:50 +02002312 buf_printf(b, "__used __section(\"__versions\") = {\n");
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002313
2314 for (s = mod->unres; s; s = s->next) {
2315 if (!s->module)
2316 continue;
2317 if (!s->crc_valid) {
2318 warn("\"%s\" [%s.ko] has no CRC!\n",
2319 s->name, mod->name);
2320 continue;
2321 }
2322 if (strlen(s->name) >= MODULE_NAME_LEN) {
2323 merror("too long symbol \"%s\" [%s.ko]\n",
2324 s->name, mod->name);
2325 err = 1;
2326 break;
2327 }
2328 buf_printf(b, "\t{ %#8x, \"%s\" },\n",
2329 s->crc, s->name);
2330 }
2331
2332 buf_printf(b, "};\n");
2333
2334 return err;
2335}
2336
David Brazdil0f672f62019-12-10 10:32:29 +00002337static void add_depends(struct buffer *b, struct module *mod)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002338{
2339 struct symbol *s;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002340 int first = 1;
2341
David Brazdil0f672f62019-12-10 10:32:29 +00002342 /* Clear ->seen flag of modules that own symbols needed by this. */
2343 for (s = mod->unres; s; s = s->next)
2344 if (s->module)
Olivier Deprez157378f2022-04-04 15:47:50 +02002345 s->module->seen = s->module->is_vmlinux;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002346
2347 buf_printf(b, "\n");
David Brazdil0f672f62019-12-10 10:32:29 +00002348 buf_printf(b, "MODULE_INFO(depends, \"");
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002349 for (s = mod->unres; s; s = s->next) {
2350 const char *p;
2351 if (!s->module)
2352 continue;
2353
2354 if (s->module->seen)
2355 continue;
2356
2357 s->module->seen = 1;
2358 p = strrchr(s->module->name, '/');
2359 if (p)
2360 p++;
2361 else
2362 p = s->module->name;
2363 buf_printf(b, "%s%s", first ? "" : ",", p);
2364 first = 0;
2365 }
David Brazdil0f672f62019-12-10 10:32:29 +00002366 buf_printf(b, "\");\n");
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002367}
2368
2369static void add_srcversion(struct buffer *b, struct module *mod)
2370{
2371 if (mod->srcversion[0]) {
2372 buf_printf(b, "\n");
2373 buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n",
2374 mod->srcversion);
2375 }
2376}
2377
Olivier Deprez157378f2022-04-04 15:47:50 +02002378static void write_buf(struct buffer *b, const char *fname)
2379{
2380 FILE *file;
2381
2382 file = fopen(fname, "w");
2383 if (!file) {
2384 perror(fname);
2385 exit(1);
2386 }
2387 if (fwrite(b->p, 1, b->pos, file) != b->pos) {
2388 perror(fname);
2389 exit(1);
2390 }
2391 if (fclose(file) != 0) {
2392 perror(fname);
2393 exit(1);
2394 }
2395}
2396
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002397static void write_if_changed(struct buffer *b, const char *fname)
2398{
2399 char *tmp;
2400 FILE *file;
2401 struct stat st;
2402
2403 file = fopen(fname, "r");
2404 if (!file)
2405 goto write;
2406
2407 if (fstat(fileno(file), &st) < 0)
2408 goto close_write;
2409
2410 if (st.st_size != b->pos)
2411 goto close_write;
2412
2413 tmp = NOFAIL(malloc(b->pos));
2414 if (fread(tmp, 1, b->pos, file) != b->pos)
2415 goto free_write;
2416
2417 if (memcmp(tmp, b->p, b->pos) != 0)
2418 goto free_write;
2419
2420 free(tmp);
2421 fclose(file);
2422 return;
2423
2424 free_write:
2425 free(tmp);
2426 close_write:
2427 fclose(file);
2428 write:
Olivier Deprez157378f2022-04-04 15:47:50 +02002429 write_buf(b, fname);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002430}
2431
2432/* parse Module.symvers file. line format:
Olivier Deprez0e641232021-09-23 10:07:05 +02002433 * 0x12345678<tab>symbol<tab>module<tab>export<tab>namespace
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002434 **/
Olivier Deprez157378f2022-04-04 15:47:50 +02002435static void read_dump(const char *fname)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002436{
Olivier Deprez157378f2022-04-04 15:47:50 +02002437 char *buf, *pos, *line;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002438
Olivier Deprez157378f2022-04-04 15:47:50 +02002439 buf = read_text_file(fname);
2440 if (!buf)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002441 /* No symbol versions, silently ignore */
2442 return;
2443
Olivier Deprez157378f2022-04-04 15:47:50 +02002444 pos = buf;
2445
2446 while ((line = get_line(&pos))) {
Olivier Deprez0e641232021-09-23 10:07:05 +02002447 char *symname, *namespace, *modname, *d, *export;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002448 unsigned int crc;
2449 struct module *mod;
2450 struct symbol *s;
2451
2452 if (!(symname = strchr(line, '\t')))
2453 goto fail;
2454 *symname++ = '\0';
Olivier Deprez0e641232021-09-23 10:07:05 +02002455 if (!(modname = strchr(symname, '\t')))
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002456 goto fail;
2457 *modname++ = '\0';
Olivier Deprez0e641232021-09-23 10:07:05 +02002458 if (!(export = strchr(modname, '\t')))
2459 goto fail;
2460 *export++ = '\0';
2461 if (!(namespace = strchr(export, '\t')))
2462 goto fail;
2463 *namespace++ = '\0';
2464
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002465 crc = strtoul(line, &d, 16);
2466 if (*symname == '\0' || *modname == '\0' || *d != '\0')
2467 goto fail;
2468 mod = find_module(modname);
2469 if (!mod) {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002470 mod = new_module(modname);
Olivier Deprez157378f2022-04-04 15:47:50 +02002471 mod->from_dump = 1;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002472 }
2473 s = sym_add_exported(symname, mod, export_no(export));
David Brazdil0f672f62019-12-10 10:32:29 +00002474 s->is_static = 0;
Olivier Deprez157378f2022-04-04 15:47:50 +02002475 sym_set_crc(symname, crc);
David Brazdil0f672f62019-12-10 10:32:29 +00002476 sym_update_namespace(symname, namespace);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002477 }
Olivier Deprez157378f2022-04-04 15:47:50 +02002478 free(buf);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002479 return;
2480fail:
Olivier Deprez157378f2022-04-04 15:47:50 +02002481 free(buf);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002482 fatal("parse error in symbol dump file\n");
2483}
2484
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002485static void write_dump(const char *fname)
2486{
2487 struct buffer buf = { };
2488 struct symbol *symbol;
David Brazdil0f672f62019-12-10 10:32:29 +00002489 const char *namespace;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002490 int n;
2491
2492 for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
2493 symbol = symbolhash[n];
2494 while (symbol) {
Olivier Deprez157378f2022-04-04 15:47:50 +02002495 if (!symbol->module->from_dump) {
David Brazdil0f672f62019-12-10 10:32:29 +00002496 namespace = symbol->namespace;
2497 buf_printf(&buf, "0x%08x\t%s\t%s\t%s\t%s\n",
2498 symbol->crc, symbol->name,
David Brazdil0f672f62019-12-10 10:32:29 +00002499 symbol->module->name,
Olivier Deprez0e641232021-09-23 10:07:05 +02002500 export_str(symbol->export),
2501 namespace ? namespace : "");
David Brazdil0f672f62019-12-10 10:32:29 +00002502 }
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002503 symbol = symbol->next;
2504 }
2505 }
Olivier Deprez157378f2022-04-04 15:47:50 +02002506 write_buf(&buf, fname);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002507 free(buf.p);
2508}
2509
Olivier Deprez157378f2022-04-04 15:47:50 +02002510static void write_namespace_deps_files(const char *fname)
David Brazdil0f672f62019-12-10 10:32:29 +00002511{
2512 struct module *mod;
2513 struct namespace_list *ns;
2514 struct buffer ns_deps_buf = {};
2515
2516 for (mod = modules; mod; mod = mod->next) {
David Brazdil0f672f62019-12-10 10:32:29 +00002517
Olivier Deprez157378f2022-04-04 15:47:50 +02002518 if (mod->from_dump || !mod->missing_namespaces)
David Brazdil0f672f62019-12-10 10:32:29 +00002519 continue;
2520
Olivier Deprez157378f2022-04-04 15:47:50 +02002521 buf_printf(&ns_deps_buf, "%s.ko:", mod->name);
David Brazdil0f672f62019-12-10 10:32:29 +00002522
Olivier Deprez157378f2022-04-04 15:47:50 +02002523 for (ns = mod->missing_namespaces; ns; ns = ns->next)
2524 buf_printf(&ns_deps_buf, " %s", ns->namespace);
David Brazdil0f672f62019-12-10 10:32:29 +00002525
Olivier Deprez157378f2022-04-04 15:47:50 +02002526 buf_printf(&ns_deps_buf, "\n");
David Brazdil0f672f62019-12-10 10:32:29 +00002527 }
Olivier Deprez157378f2022-04-04 15:47:50 +02002528
2529 write_if_changed(&ns_deps_buf, fname);
2530 free(ns_deps_buf.p);
David Brazdil0f672f62019-12-10 10:32:29 +00002531}
2532
Olivier Deprez157378f2022-04-04 15:47:50 +02002533struct dump_list {
2534 struct dump_list *next;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002535 const char *file;
2536};
2537
2538int main(int argc, char **argv)
2539{
2540 struct module *mod;
2541 struct buffer buf = { };
Olivier Deprez157378f2022-04-04 15:47:50 +02002542 char *missing_namespace_deps = NULL;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002543 char *dump_write = NULL, *files_source = NULL;
2544 int opt;
2545 int err;
David Brazdil0f672f62019-12-10 10:32:29 +00002546 int n;
Olivier Deprez157378f2022-04-04 15:47:50 +02002547 struct dump_list *dump_read_start = NULL;
2548 struct dump_list **dump_read_iter = &dump_read_start;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002549
Olivier Deprez157378f2022-04-04 15:47:50 +02002550 while ((opt = getopt(argc, argv, "ei:mnT:o:awENd:")) != -1) {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002551 switch (opt) {
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002552 case 'e':
2553 external_module = 1;
Olivier Deprez157378f2022-04-04 15:47:50 +02002554 break;
2555 case 'i':
2556 *dump_read_iter =
2557 NOFAIL(calloc(1, sizeof(**dump_read_iter)));
2558 (*dump_read_iter)->file = optarg;
2559 dump_read_iter = &(*dump_read_iter)->next;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002560 break;
2561 case 'm':
2562 modversions = 1;
2563 break;
2564 case 'n':
2565 ignore_missing_files = 1;
2566 break;
2567 case 'o':
2568 dump_write = optarg;
2569 break;
2570 case 'a':
2571 all_versions = 1;
2572 break;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002573 case 'T':
2574 files_source = optarg;
2575 break;
2576 case 'w':
2577 warn_unresolved = 1;
2578 break;
2579 case 'E':
2580 sec_mismatch_fatal = 1;
2581 break;
Olivier Deprez157378f2022-04-04 15:47:50 +02002582 case 'N':
2583 allow_missing_ns_imports = 1;
2584 break;
David Brazdil0f672f62019-12-10 10:32:29 +00002585 case 'd':
Olivier Deprez157378f2022-04-04 15:47:50 +02002586 missing_namespace_deps = optarg;
David Brazdil0f672f62019-12-10 10:32:29 +00002587 break;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002588 default:
2589 exit(1);
2590 }
2591 }
2592
Olivier Deprez157378f2022-04-04 15:47:50 +02002593 while (dump_read_start) {
2594 struct dump_list *tmp;
2595
2596 read_dump(dump_read_start->file);
2597 tmp = dump_read_start->next;
2598 free(dump_read_start);
2599 dump_read_start = tmp;
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002600 }
2601
2602 while (optind < argc)
2603 read_symbols(argv[optind++]);
2604
2605 if (files_source)
2606 read_symbols_from_files(files_source);
2607
Olivier Deprez157378f2022-04-04 15:47:50 +02002608 /*
2609 * When there's no vmlinux, don't print warnings about
2610 * unresolved symbols (since there'll be too many ;)
2611 */
2612 if (!have_vmlinux)
2613 warn("Symbol info of vmlinux is missing. Unresolved symbol check will be entirely skipped.\n");
2614
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002615 err = 0;
2616
2617 for (mod = modules; mod; mod = mod->next) {
2618 char fname[PATH_MAX];
2619
Olivier Deprez157378f2022-04-04 15:47:50 +02002620 if (mod->is_vmlinux || mod->from_dump)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002621 continue;
2622
2623 buf.pos = 0;
2624
2625 err |= check_modname_len(mod);
David Brazdil0f672f62019-12-10 10:32:29 +00002626 err |= check_exports(mod);
David Brazdil0f672f62019-12-10 10:32:29 +00002627
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002628 add_header(&buf, mod);
2629 add_intree_flag(&buf, !external_module);
2630 add_retpoline(&buf);
2631 add_staging_flag(&buf, mod->name);
2632 err |= add_versions(&buf, mod);
David Brazdil0f672f62019-12-10 10:32:29 +00002633 add_depends(&buf, mod);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002634 add_moddevtable(&buf, mod);
2635 add_srcversion(&buf, mod);
2636
2637 sprintf(fname, "%s.mod.c", mod->name);
2638 write_if_changed(&buf, fname);
2639 }
David Brazdil0f672f62019-12-10 10:32:29 +00002640
Olivier Deprez157378f2022-04-04 15:47:50 +02002641 if (missing_namespace_deps)
2642 write_namespace_deps_files(missing_namespace_deps);
David Brazdil0f672f62019-12-10 10:32:29 +00002643
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002644 if (dump_write)
2645 write_dump(dump_write);
David Brazdil0f672f62019-12-10 10:32:29 +00002646 if (sec_mismatch_count && sec_mismatch_fatal)
Olivier Deprez157378f2022-04-04 15:47:50 +02002647 fatal("Section mismatches detected.\n"
David Brazdil0f672f62019-12-10 10:32:29 +00002648 "Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n");
2649 for (n = 0; n < SYMBOL_HASH_SIZE; n++) {
2650 struct symbol *s;
2651
2652 for (s = symbolhash[n]; s; s = s->next) {
David Brazdil0f672f62019-12-10 10:32:29 +00002653 if (s->is_static)
2654 warn("\"%s\" [%s] is a static %s\n",
2655 s->name, s->module->name,
2656 export_str(s->export));
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002657 }
2658 }
David Brazdil0f672f62019-12-10 10:32:29 +00002659
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00002660 free(buf.p);
2661
2662 return err;
2663}