blob: 9c8c7511d10d8e30a7f10d184893c9a587ac710d [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* Postprocess module symbol versions
2 *
3 * Copyright 2003 Kai Germaschewski
4 * Copyright 2002-2004 Rusty Russell, IBM Corporation
Sam Ravnborgdf578e72008-01-11 19:17:15 +01005 * Copyright 2006-2008 Sam Ravnborg
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 * 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
Mathieu Desnoyersb2e3e652008-02-13 15:03:39 -080014#define _GNU_SOURCE
Masahiro Yamada5370d4a2020-01-05 00:36:51 +090015#include <elf.h>
Mathieu Desnoyersb2e3e652008-02-13 15:03:39 -080016#include <stdio.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070017#include <ctype.h>
Andrew Morton5003bab2010-08-11 00:42:26 -070018#include <string.h>
Rusty Russell712f9b42013-04-04 17:37:38 +103019#include <limits.h>
Guenter Roeckeed380f2013-09-23 15:23:54 +093020#include <errno.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070021#include "modpost.h"
Sam Ravnborgb817f6f2006-06-09 21:53:55 +020022#include "../../include/linux/license.h"
Alan Jenkins9e1b9b82009-11-07 21:03:54 +000023
Linus Torvalds1da177e2005-04-16 15:20:36 -070024/* Are we using CONFIG_MODVERSIONS? */
Mathias Krause7a3ee752014-08-27 20:28:53 +093025static int modversions = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070026/* Warn about undefined symbols? (do so if we have vmlinux) */
Mathias Krause7a3ee752014-08-27 20:28:53 +093027static int have_vmlinux = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070028/* Is CONFIG_MODULE_SRCVERSION_ALL set? */
29static int all_versions = 0;
Sam Ravnborg040fcc82006-01-28 22:15:55 +010030/* If we are modposting external module set to 1 */
31static int external_module = 0;
Will McVickerda2089a2020-11-19 13:46:37 -080032#define MODULE_SCMVERSION_SIZE 64
33static char module_scmversion[MODULE_SCMVERSION_SIZE];
Kirill Korotaevc53ddac2006-09-07 13:08:54 -070034/* Only warn about unresolved symbols */
35static int warn_unresolved = 0;
Ram Paibd5cbce2006-06-08 22:12:53 -070036/* How a symbol is exported */
Sam Ravnborg588ccd72008-01-24 21:12:37 +010037static int sec_mismatch_count = 0;
Masahiro Yamada1e582602020-12-01 19:34:18 +090038static int sec_mismatch_warn_only = true;
Guenter Roeckeed380f2013-09-23 15:23:54 +093039/* ignore missing files */
40static int ignore_missing_files;
Jessica Yu54b77842020-03-06 17:02:06 +010041/* If set to 1, only warn (instead of error) about missing ns imports */
42static int allow_missing_ns_imports;
Sam Ravnborg588ccd72008-01-24 21:12:37 +010043
Masahiro Yamadaba0f6422020-12-01 19:34:15 +090044static bool error_occurred;
45
Sam Ravnborgc96fca22006-07-01 11:44:23 +020046enum export {
47 export_plain, export_unused, export_gpl,
48 export_unused_gpl, export_gpl_future, export_unknown
49};
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
Wanlong Gao4fd3e4e2017-06-30 22:07:03 +080051/* In kernel, this size is defined in linux/module.h;
52 * here we use Elf_Addr instead of long for covering cross-compile
53 */
54
55#define MODULE_NAME_LEN (64 - sizeof(Elf_Addr))
56
Jessica Yu93c95e52020-03-06 17:02:05 +010057void __attribute__((format(printf, 2, 3)))
58modpost_log(enum loglevel loglevel, const char *fmt, ...)
Linus Torvalds1da177e2005-04-16 15:20:36 -070059{
60 va_list arglist;
61
Jessica Yu93c95e52020-03-06 17:02:05 +010062 switch (loglevel) {
63 case LOG_WARN:
64 fprintf(stderr, "WARNING: ");
65 break;
66 case LOG_ERROR:
67 fprintf(stderr, "ERROR: ");
68 break;
69 case LOG_FATAL:
70 fprintf(stderr, "FATAL: ");
71 break;
72 default: /* invalid loglevel, ignore */
73 break;
74 }
75
76 fprintf(stderr, "modpost: ");
Linus Torvalds1da177e2005-04-16 15:20:36 -070077
78 va_start(arglist, fmt);
79 vfprintf(stderr, fmt, arglist);
80 va_end(arglist);
81
Jessica Yu93c95e52020-03-06 17:02:05 +010082 if (loglevel == LOG_FATAL)
83 exit(1);
Masahiro Yamadaba0f6422020-12-01 19:34:15 +090084 if (loglevel == LOG_ERROR)
85 error_occurred = true;
Matthew Wilcox2a116652006-10-07 05:35:32 -060086}
87
Linus Torvalds1da177e2005-04-16 15:20:36 -070088void *do_nofail(void *ptr, const char *expr)
89{
Sam Ravnborgdf578e72008-01-11 19:17:15 +010090 if (!ptr)
Jessica Yu93c95e52020-03-06 17:02:05 +010091 fatal("Memory allocation failure: %s.\n", expr);
Sam Ravnborgdf578e72008-01-11 19:17:15 +010092
Linus Torvalds1da177e2005-04-16 15:20:36 -070093 return ptr;
94}
95
Masahiro Yamadaac5100f2020-06-01 14:57:17 +090096char *read_text_file(const char *filename)
97{
98 struct stat st;
99 size_t nbytes;
100 int fd;
101 char *buf;
102
103 fd = open(filename, O_RDONLY);
104 if (fd < 0) {
105 perror(filename);
106 exit(1);
107 }
108
109 if (fstat(fd, &st) < 0) {
110 perror(filename);
111 exit(1);
112 }
113
114 buf = NOFAIL(malloc(st.st_size + 1));
115
116 nbytes = st.st_size;
117
118 while (nbytes) {
119 ssize_t bytes_read;
120
121 bytes_read = read(fd, buf, nbytes);
122 if (bytes_read < 0) {
123 perror(filename);
124 exit(1);
125 }
126
127 nbytes -= bytes_read;
128 }
129 buf[st.st_size] = '\0';
130
131 close(fd);
132
133 return buf;
134}
135
136char *get_line(char **stringp)
137{
H. Nikolaus Schaller736bb112020-07-01 08:18:27 +0200138 char *orig = *stringp, *next;
139
Masahiro Yamadaac5100f2020-06-01 14:57:17 +0900140 /* do not return the unwanted extra line at EOF */
H. Nikolaus Schaller736bb112020-07-01 08:18:27 +0200141 if (!orig || *orig == '\0')
Masahiro Yamadaac5100f2020-06-01 14:57:17 +0900142 return NULL;
143
Wolfram Sang6020db52020-07-26 23:44:19 +0200144 /* don't use strsep here, it is not available everywhere */
H. Nikolaus Schaller736bb112020-07-01 08:18:27 +0200145 next = strchr(orig, '\n');
146 if (next)
147 *next++ = '\0';
148
149 *stringp = next;
150
151 return orig;
Masahiro Yamadaac5100f2020-06-01 14:57:17 +0900152}
153
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154/* A list of all modules we processed */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155static struct module *modules;
156
Masahiro Yamada8b185742018-05-09 18:50:40 +0900157static struct module *find_module(const char *modname)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158{
159 struct module *mod;
160
161 for (mod = modules; mod; mod = mod->next)
162 if (strcmp(mod->name, modname) == 0)
163 break;
164 return mod;
165}
166
Rusty Russelld4ef1c32013-04-04 17:37:32 +1030167static struct module *new_module(const char *modname)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168{
169 struct module *mod;
Sam Ravnborg62070fa2006-03-03 16:46:04 +0100170
Masahiro Yamadaa82f7942020-06-01 14:57:29 +0900171 mod = NOFAIL(malloc(sizeof(*mod) + strlen(modname) + 1));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172 memset(mod, 0, sizeof(*mod));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173
174 /* add to list */
Masahiro Yamadaa82f7942020-06-01 14:57:29 +0900175 strcpy(mod->name, modname);
Masahiro Yamada4de7b622020-06-01 14:57:30 +0900176 mod->is_vmlinux = (strcmp(modname, "vmlinux") == 0);
Sam Ravnborgb817f6f2006-06-09 21:53:55 +0200177 mod->gpl_compatible = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178 mod->next = modules;
179 modules = mod;
180
Masahiro Yamada858b9372020-06-01 14:57:28 +0900181 if (mod->is_vmlinux)
182 have_vmlinux = 1;
183
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184 return mod;
185}
186
187/* A hash of all exported symbols,
188 * struct symbol is also used for lists of unresolved symbols */
189
190#define SYMBOL_HASH_SIZE 1024
191
192struct symbol {
193 struct symbol *next;
194 struct module *module;
195 unsigned int crc;
196 int crc_valid;
Masahiro Yamada389eb3f2019-10-03 16:58:22 +0900197 char *namespace;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198 unsigned int weak:1;
Denis Efremov15bfc232019-08-01 09:06:57 +0300199 unsigned int is_static:1; /* 1 if symbol is not global */
Ram Paibd5cbce2006-06-08 22:12:53 -0700200 enum export export; /* Type of export */
Gustavo A. R. Silva859c8172020-05-07 13:56:01 -0500201 char name[];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202};
203
204static struct symbol *symbolhash[SYMBOL_HASH_SIZE];
205
206/* This is based on the hash agorithm from gdbm, via tdb */
207static inline unsigned int tdb_hash(const char *name)
208{
209 unsigned value; /* Used to compute the hash value. */
210 unsigned i; /* Used to cycle through random values. */
211
212 /* Set the initial value from the key size. */
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100213 for (value = 0x238F13AF * strlen(name), i = 0; name[i]; i++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214 value = (value + (((unsigned char *)name)[i] << (i*5 % 24)));
215
216 return (1103515243 * value + 12345);
217}
218
Sam Ravnborg5c3ead82006-01-28 17:19:35 +0100219/**
220 * Allocate a new symbols for use in the hash of exported symbols or
221 * the list of unresolved symbols per module
222 **/
223static struct symbol *alloc_symbol(const char *name, unsigned int weak,
224 struct symbol *next)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225{
226 struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1));
227
228 memset(s, 0, sizeof(*s));
229 strcpy(s->name, name);
230 s->weak = weak;
231 s->next = next;
Denis Efremov15bfc232019-08-01 09:06:57 +0300232 s->is_static = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700233 return s;
234}
235
236/* For the hash of exported symbols */
Ram Paibd5cbce2006-06-08 22:12:53 -0700237static struct symbol *new_symbol(const char *name, struct module *module,
238 enum export export)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239{
240 unsigned int hash;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241
242 hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
Masahiro Yamada7ef9ab32019-11-15 02:42:26 +0900243 symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]);
244
245 return symbolhash[hash];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246}
247
Sam Ravnborg5c3ead82006-01-28 17:19:35 +0100248static struct symbol *find_symbol(const char *name)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249{
250 struct symbol *s;
251
252 /* For our purposes, .foo matches foo. PPC64 needs this. */
253 if (name[0] == '.')
254 name++;
255
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100256 for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s = s->next) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257 if (strcmp(s->name, name) == 0)
258 return s;
259 }
260 return NULL;
261}
262
Matthias Maennichcb9b55d2019-09-06 11:32:28 +0100263static bool contains_namespace(struct namespace_list *list,
264 const char *namespace)
265{
Masahiro Yamada76b54cf2019-10-29 21:38:09 +0900266 for (; list; list = list->next)
267 if (!strcmp(list->namespace, namespace))
Matthias Maennichcb9b55d2019-09-06 11:32:28 +0100268 return true;
269
270 return false;
271}
272
273static void add_namespace(struct namespace_list **list, const char *namespace)
274{
275 struct namespace_list *ns_entry;
276
277 if (!contains_namespace(*list, namespace)) {
278 ns_entry = NOFAIL(malloc(sizeof(struct namespace_list) +
279 strlen(namespace) + 1));
280 strcpy(ns_entry->namespace, namespace);
281 ns_entry->next = *list;
282 *list = ns_entry;
283 }
284}
285
286static bool module_imports_namespace(struct module *module,
287 const char *namespace)
288{
289 return contains_namespace(module->imported_namespaces, namespace);
290}
291
Mathias Krause7a3ee752014-08-27 20:28:53 +0930292static const struct {
Ram Paibd5cbce2006-06-08 22:12:53 -0700293 const char *str;
294 enum export export;
295} export_list[] = {
296 { .str = "EXPORT_SYMBOL", .export = export_plain },
Sam Ravnborgc96fca22006-07-01 11:44:23 +0200297 { .str = "EXPORT_UNUSED_SYMBOL", .export = export_unused },
Ram Paibd5cbce2006-06-08 22:12:53 -0700298 { .str = "EXPORT_SYMBOL_GPL", .export = export_gpl },
Sam Ravnborgc96fca22006-07-01 11:44:23 +0200299 { .str = "EXPORT_UNUSED_SYMBOL_GPL", .export = export_unused_gpl },
Ram Paibd5cbce2006-06-08 22:12:53 -0700300 { .str = "EXPORT_SYMBOL_GPL_FUTURE", .export = export_gpl_future },
301 { .str = "(unknown)", .export = export_unknown },
302};
303
304
305static const char *export_str(enum export ex)
306{
307 return export_list[ex].str;
308}
309
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100310static enum export export_no(const char *s)
Ram Paibd5cbce2006-06-08 22:12:53 -0700311{
312 int i;
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100313
Sam Ravnborg534b89a2006-07-01 10:10:19 +0200314 if (!s)
315 return export_unknown;
Ram Paibd5cbce2006-06-08 22:12:53 -0700316 for (i = 0; export_list[i].export != export_unknown; i++) {
317 if (strcmp(export_list[i].str, s) == 0)
318 return export_list[i].export;
319 }
320 return export_unknown;
321}
322
Masahiro Yamadad2e4d052020-05-25 14:47:04 +0900323static void *sym_get_data_by_offset(const struct elf_info *info,
324 unsigned int secindex, unsigned long offset)
Masahiro Yamada6124c042017-09-06 16:19:05 -0700325{
Xiao Yang4b8a5cf2020-03-18 18:34:16 +0800326 Elf_Shdr *sechdr = &info->sechdrs[secindex];
Masahiro Yamadaafa04592019-11-15 02:42:21 +0900327
Masahiro Yamadaafa04592019-11-15 02:42:21 +0900328 if (info->hdr->e_type != ET_REL)
329 offset -= sechdr->sh_addr;
330
331 return (void *)info->hdr + sechdr->sh_offset + offset;
332}
333
Masahiro Yamadad2e4d052020-05-25 14:47:04 +0900334static void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym)
335{
336 return sym_get_data_by_offset(info, get_secindex(info, sym),
337 sym->st_value);
338}
339
Masahiro Yamada565587d2020-05-25 14:47:05 +0900340static const char *sech_name(const struct elf_info *info, Elf_Shdr *sechdr)
341{
342 return sym_get_data_by_offset(info, info->secindex_strings,
343 sechdr->sh_name);
344}
345
346static const char *sec_name(const struct elf_info *info, int secindex)
347{
348 return sech_name(info, &info->sechdrs[secindex]);
349}
350
Alessio Igor Bogani62a26352011-07-14 08:51:16 +0200351#define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0)
352
353static enum export export_from_secname(struct elf_info *elf, unsigned int sec)
354{
355 const char *secname = sec_name(elf, sec);
356
357 if (strstarts(secname, "___ksymtab+"))
358 return export_plain;
359 else if (strstarts(secname, "___ksymtab_unused+"))
360 return export_unused;
361 else if (strstarts(secname, "___ksymtab_gpl+"))
362 return export_gpl;
363 else if (strstarts(secname, "___ksymtab_unused_gpl+"))
364 return export_unused_gpl;
365 else if (strstarts(secname, "___ksymtab_gpl_future+"))
366 return export_gpl_future;
367 else
368 return export_unknown;
369}
370
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200371static enum export export_from_sec(struct elf_info *elf, unsigned int sec)
Ram Paibd5cbce2006-06-08 22:12:53 -0700372{
373 if (sec == elf->export_sec)
374 return export_plain;
Sam Ravnborgc96fca22006-07-01 11:44:23 +0200375 else if (sec == elf->export_unused_sec)
376 return export_unused;
Ram Paibd5cbce2006-06-08 22:12:53 -0700377 else if (sec == elf->export_gpl_sec)
378 return export_gpl;
Sam Ravnborgc96fca22006-07-01 11:44:23 +0200379 else if (sec == elf->export_unused_gpl_sec)
380 return export_unused_gpl;
Ram Paibd5cbce2006-06-08 22:12:53 -0700381 else if (sec == elf->export_gpl_future_sec)
382 return export_gpl_future;
383 else
384 return export_unknown;
385}
386
Masahiro Yamadae84f9fb2019-11-15 02:42:22 +0900387static const char *namespace_from_kstrtabns(const struct elf_info *info,
388 const Elf_Sym *sym)
Matthias Maennichcb9b55d2019-09-06 11:32:28 +0100389{
Masahiro Yamadae84f9fb2019-11-15 02:42:22 +0900390 const char *value = sym_get_data(info, sym);
Matthias Maennich69923202019-10-18 10:31:42 +0100391 return value[0] ? value : NULL;
Matthias Maennichcb9b55d2019-09-06 11:32:28 +0100392}
393
Matthias Maennicha2b11182019-10-18 10:31:40 +0100394static void sym_update_namespace(const char *symname, const char *namespace)
395{
396 struct symbol *s = find_symbol(symname);
397
398 /*
399 * That symbol should have been created earlier and thus this is
400 * actually an assertion.
401 */
402 if (!s) {
Masahiro Yamada979f7482020-12-01 19:34:14 +0900403 error("Could not update namespace(%s) for symbol %s\n",
404 namespace, symname);
Matthias Maennicha2b11182019-10-18 10:31:40 +0100405 return;
406 }
407
408 free(s->namespace);
409 s->namespace =
410 namespace && namespace[0] ? NOFAIL(strdup(namespace)) : NULL;
411}
412
Sam Ravnborg5c3ead82006-01-28 17:19:35 +0100413/**
414 * Add an exported symbol - it may have already been added without a
415 * CRC, in this case just update the CRC
416 **/
Matthias Maennich9ae5bd12019-10-18 10:31:41 +0100417static struct symbol *sym_add_exported(const char *name, struct module *mod,
418 enum export export)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419{
420 struct symbol *s = find_symbol(name);
421
422 if (!s) {
Ram Paibd5cbce2006-06-08 22:12:53 -0700423 s = new_symbol(name, mod, export);
Masahiro Yamada5a438af2020-06-01 14:57:26 +0900424 } else if (!external_module || s->module->is_vmlinux ||
Masahiro Yamada7ef9ab32019-11-15 02:42:26 +0900425 s->module == mod) {
Quentin Perret479488f2020-11-24 14:40:13 +0000426 fatal("%s: '%s' exported twice. Previous export was in %s%s\n",
427 mod->name, name, s->module->name,
428 s->module->is_vmlinux ? "" : ".ko");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429 }
Masahiro Yamada7ef9ab32019-11-15 02:42:26 +0900430
431 s->module = mod;
Ram Paibd5cbce2006-06-08 22:12:53 -0700432 s->export = export;
Sam Ravnborg040fcc82006-01-28 22:15:55 +0100433 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434}
435
Masahiro Yamada17436942019-11-15 02:42:24 +0900436static void sym_set_crc(const char *name, unsigned int crc)
Sam Ravnborg040fcc82006-01-28 22:15:55 +0100437{
438 struct symbol *s = find_symbol(name);
439
Masahiro Yamada17436942019-11-15 02:42:24 +0900440 /*
441 * Ignore stand-alone __crc_*, which might be auto-generated symbols
442 * such as __*_veneer in ARM ELF.
443 */
444 if (!s)
445 return;
446
Sam Ravnborg040fcc82006-01-28 22:15:55 +0100447 s->crc = crc;
448 s->crc_valid = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449}
450
Masahiro Yamada3b09efc2020-06-01 14:57:31 +0900451static void *grab_file(const char *filename, size_t *size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452{
453 struct stat st;
Jesper Juhleb3d5cc2012-05-23 22:28:49 +0930454 void *map = MAP_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455 int fd;
456
457 fd = open(filename, O_RDONLY);
Jesper Juhleb3d5cc2012-05-23 22:28:49 +0930458 if (fd < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459 return NULL;
Jesper Juhleb3d5cc2012-05-23 22:28:49 +0930460 if (fstat(fd, &st))
461 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462
463 *size = st.st_size;
464 map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465
Jesper Juhleb3d5cc2012-05-23 22:28:49 +0930466failed:
467 close(fd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468 if (map == MAP_FAILED)
469 return NULL;
470 return map;
471}
472
Masahiro Yamada3b09efc2020-06-01 14:57:31 +0900473static void release_file(void *file, size_t size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474{
475 munmap(file, size);
476}
477
Sam Ravnborg85bd2fd2007-02-26 15:33:52 +0100478static int parse_elf(struct elf_info *info, const char *filename)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479{
480 unsigned int i;
Sam Ravnborg85bd2fd2007-02-26 15:33:52 +0100481 Elf_Ehdr *hdr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482 Elf_Shdr *sechdrs;
483 Elf_Sym *sym;
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200484 const char *secstrings;
485 unsigned int symtab_idx = ~0U, symtab_shndx_idx = ~0U;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486
487 hdr = grab_file(filename, &info->size);
488 if (!hdr) {
Guenter Roeckeed380f2013-09-23 15:23:54 +0930489 if (ignore_missing_files) {
490 fprintf(stderr, "%s: %s (ignored)\n", filename,
491 strerror(errno));
492 return 0;
493 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494 perror(filename);
Sam Ravnborg6803dc02006-06-24 23:46:54 +0200495 exit(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496 }
497 info->hdr = hdr;
Sam Ravnborg85bd2fd2007-02-26 15:33:52 +0100498 if (info->size < sizeof(*hdr)) {
499 /* file too small, assume this is an empty .o file */
500 return 0;
501 }
502 /* Is this a valid ELF file? */
503 if ((hdr->e_ident[EI_MAG0] != ELFMAG0) ||
504 (hdr->e_ident[EI_MAG1] != ELFMAG1) ||
505 (hdr->e_ident[EI_MAG2] != ELFMAG2) ||
506 (hdr->e_ident[EI_MAG3] != ELFMAG3)) {
507 /* Not an ELF file - silently ignore it */
508 return 0;
509 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510 /* Fix endianness in ELF header */
Anders Kaseorg7d875a02009-05-03 22:02:55 +0200511 hdr->e_type = TO_NATIVE(hdr->e_type);
512 hdr->e_machine = TO_NATIVE(hdr->e_machine);
513 hdr->e_version = TO_NATIVE(hdr->e_version);
514 hdr->e_entry = TO_NATIVE(hdr->e_entry);
515 hdr->e_phoff = TO_NATIVE(hdr->e_phoff);
516 hdr->e_shoff = TO_NATIVE(hdr->e_shoff);
517 hdr->e_flags = TO_NATIVE(hdr->e_flags);
518 hdr->e_ehsize = TO_NATIVE(hdr->e_ehsize);
519 hdr->e_phentsize = TO_NATIVE(hdr->e_phentsize);
520 hdr->e_phnum = TO_NATIVE(hdr->e_phnum);
521 hdr->e_shentsize = TO_NATIVE(hdr->e_shentsize);
522 hdr->e_shnum = TO_NATIVE(hdr->e_shnum);
523 hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524 sechdrs = (void *)hdr + hdr->e_shoff;
525 info->sechdrs = sechdrs;
526
Petr Stetiara83710e2007-08-27 12:15:07 +0200527 /* Check if file offset is correct */
528 if (hdr->e_shoff > info->size) {
Masahiro Yamada3b09efc2020-06-01 14:57:31 +0900529 fatal("section header offset=%lu in file '%s' is bigger than filesize=%zu\n",
530 (unsigned long)hdr->e_shoff, filename, info->size);
Petr Stetiara83710e2007-08-27 12:15:07 +0200531 return 0;
532 }
533
Anders Kaseorg68457562011-05-19 16:55:27 -0600534 if (hdr->e_shnum == SHN_UNDEF) {
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200535 /*
536 * There are more than 64k sections,
537 * read count from .sh_size.
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200538 */
539 info->num_sections = TO_NATIVE(sechdrs[0].sh_size);
540 }
541 else {
542 info->num_sections = hdr->e_shnum;
543 }
544 if (hdr->e_shstrndx == SHN_XINDEX) {
Anders Kaseorg68457562011-05-19 16:55:27 -0600545 info->secindex_strings = TO_NATIVE(sechdrs[0].sh_link);
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200546 }
547 else {
548 info->secindex_strings = hdr->e_shstrndx;
549 }
550
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 /* Fix endianness in section headers */
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200552 for (i = 0; i < info->num_sections; i++) {
Anders Kaseorg7d875a02009-05-03 22:02:55 +0200553 sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name);
554 sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type);
555 sechdrs[i].sh_flags = TO_NATIVE(sechdrs[i].sh_flags);
556 sechdrs[i].sh_addr = TO_NATIVE(sechdrs[i].sh_addr);
557 sechdrs[i].sh_offset = TO_NATIVE(sechdrs[i].sh_offset);
558 sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size);
559 sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link);
560 sechdrs[i].sh_info = TO_NATIVE(sechdrs[i].sh_info);
561 sechdrs[i].sh_addralign = TO_NATIVE(sechdrs[i].sh_addralign);
562 sechdrs[i].sh_entsize = TO_NATIVE(sechdrs[i].sh_entsize);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 }
564 /* Find symbol table. */
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200565 secstrings = (void *)hdr + sechdrs[info->secindex_strings].sh_offset;
566 for (i = 1; i < info->num_sections; i++) {
Ram Paibd5cbce2006-06-08 22:12:53 -0700567 const char *secname;
Tejun Heo56fc82c2009-02-06 00:48:02 +0900568 int nobits = sechdrs[i].sh_type == SHT_NOBITS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569
Tejun Heo56fc82c2009-02-06 00:48:02 +0900570 if (!nobits && sechdrs[i].sh_offset > info->size) {
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100571 fatal("%s is truncated. sechdrs[i].sh_offset=%lu > "
572 "sizeof(*hrd)=%zu\n", filename,
573 (unsigned long)sechdrs[i].sh_offset,
574 sizeof(*hdr));
Sam Ravnborg85bd2fd2007-02-26 15:33:52 +0100575 return 0;
576 }
Ram Paibd5cbce2006-06-08 22:12:53 -0700577 secname = secstrings + sechdrs[i].sh_name;
578 if (strcmp(secname, ".modinfo") == 0) {
Tejun Heo56fc82c2009-02-06 00:48:02 +0900579 if (nobits)
580 fatal("%s has NOBITS .modinfo\n", filename);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
582 info->modinfo_len = sechdrs[i].sh_size;
Ram Paibd5cbce2006-06-08 22:12:53 -0700583 } else if (strcmp(secname, "__ksymtab") == 0)
584 info->export_sec = i;
Sam Ravnborgc96fca22006-07-01 11:44:23 +0200585 else if (strcmp(secname, "__ksymtab_unused") == 0)
586 info->export_unused_sec = i;
Ram Paibd5cbce2006-06-08 22:12:53 -0700587 else if (strcmp(secname, "__ksymtab_gpl") == 0)
588 info->export_gpl_sec = i;
Sam Ravnborgc96fca22006-07-01 11:44:23 +0200589 else if (strcmp(secname, "__ksymtab_unused_gpl") == 0)
590 info->export_unused_gpl_sec = i;
Ram Paibd5cbce2006-06-08 22:12:53 -0700591 else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
592 info->export_gpl_future_sec = i;
593
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200594 if (sechdrs[i].sh_type == SHT_SYMTAB) {
595 unsigned int sh_link_idx;
596 symtab_idx = i;
597 info->symtab_start = (void *)hdr +
598 sechdrs[i].sh_offset;
599 info->symtab_stop = (void *)hdr +
600 sechdrs[i].sh_offset + sechdrs[i].sh_size;
Anders Kaseorg68457562011-05-19 16:55:27 -0600601 sh_link_idx = sechdrs[i].sh_link;
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200602 info->strtab = (void *)hdr +
603 sechdrs[sh_link_idx].sh_offset;
604 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200606 /* 32bit section no. table? ("more than 64k sections") */
607 if (sechdrs[i].sh_type == SHT_SYMTAB_SHNDX) {
608 symtab_shndx_idx = i;
609 info->symtab_shndx_start = (void *)hdr +
610 sechdrs[i].sh_offset;
611 info->symtab_shndx_stop = (void *)hdr +
612 sechdrs[i].sh_offset + sechdrs[i].sh_size;
613 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 }
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100615 if (!info->symtab_start)
Sam Ravnborgcb805142006-01-28 16:57:26 +0100616 fatal("%s has no symtab?\n", filename);
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100617
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 /* Fix endianness in symbols */
619 for (sym = info->symtab_start; sym < info->symtab_stop; sym++) {
620 sym->st_shndx = TO_NATIVE(sym->st_shndx);
621 sym->st_name = TO_NATIVE(sym->st_name);
622 sym->st_value = TO_NATIVE(sym->st_value);
623 sym->st_size = TO_NATIVE(sym->st_size);
624 }
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200625
626 if (symtab_shndx_idx != ~0U) {
627 Elf32_Word *p;
Anders Kaseorg68457562011-05-19 16:55:27 -0600628 if (symtab_idx != sechdrs[symtab_shndx_idx].sh_link)
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200629 fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n",
Anders Kaseorg68457562011-05-19 16:55:27 -0600630 filename, sechdrs[symtab_shndx_idx].sh_link,
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200631 symtab_idx);
632 /* Fix endianness */
633 for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop;
634 p++)
635 *p = TO_NATIVE(*p);
636 }
637
Sam Ravnborg85bd2fd2007-02-26 15:33:52 +0100638 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639}
640
Sam Ravnborg5c3ead82006-01-28 17:19:35 +0100641static void parse_elf_finish(struct elf_info *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642{
643 release_file(info->hdr, info->size);
644}
645
Sam Ravnborg4d7365d2008-06-12 15:02:55 +0200646static int ignore_undef_symbol(struct elf_info *info, const char *symname)
647{
648 /* ignore __this_module, it will be resolved shortly */
Masahiro Yamadab2c5cdc2018-05-09 16:23:45 +0900649 if (strcmp(symname, "__this_module") == 0)
Sam Ravnborg4d7365d2008-06-12 15:02:55 +0200650 return 1;
651 /* ignore global offset table */
652 if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0)
653 return 1;
654 if (info->hdr->e_machine == EM_PPC)
655 /* Special register function linked on all modules during final link of .ko */
Masahiro Yamadad62c4762018-05-09 18:50:38 +0900656 if (strstarts(symname, "_restgpr_") ||
657 strstarts(symname, "_savegpr_") ||
658 strstarts(symname, "_rest32gpr_") ||
659 strstarts(symname, "_save32gpr_") ||
660 strstarts(symname, "_restvr_") ||
661 strstarts(symname, "_savevr_"))
Sam Ravnborg4d7365d2008-06-12 15:02:55 +0200662 return 1;
Stephen Rothwell7fca5dc2010-06-29 20:08:42 +0000663 if (info->hdr->e_machine == EM_PPC64)
664 /* Special register function linked on all modules during final link of .ko */
Masahiro Yamadad62c4762018-05-09 18:50:38 +0900665 if (strstarts(symname, "_restgpr0_") ||
666 strstarts(symname, "_savegpr0_") ||
667 strstarts(symname, "_restvr_") ||
668 strstarts(symname, "_savevr_") ||
Alan Modrac1536932016-01-15 20:52:22 +1100669 strcmp(symname, ".TOC.") == 0)
Stephen Rothwell7fca5dc2010-06-29 20:08:42 +0000670 return 1;
Sam Ravnborg4d7365d2008-06-12 15:02:55 +0200671 /* Do not ignore this symbol */
672 return 0;
673}
674
Masahiro Yamada17436942019-11-15 02:42:24 +0900675static void handle_modversion(const struct module *mod,
676 const struct elf_info *info,
677 const Elf_Sym *sym, const char *symname)
678{
679 unsigned int crc;
680
681 if (sym->st_shndx == SHN_UNDEF) {
682 warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n",
Masahiro Yamada5a438af2020-06-01 14:57:26 +0900683 symname, mod->name, mod->is_vmlinux ? "" : ".ko");
Masahiro Yamada17436942019-11-15 02:42:24 +0900684 return;
685 }
686
687 if (sym->st_shndx == SHN_ABS) {
688 crc = sym->st_value;
689 } else {
690 unsigned int *crcp;
691
692 /* symbol points to the CRC in the ELF object */
693 crcp = sym_get_data(info, sym);
694 crc = TO_NATIVE(*crcp);
695 }
696 sym_set_crc(symname, crc);
697}
698
Masahiro Yamada9bd2a092019-11-15 02:42:23 +0900699static void handle_symbol(struct module *mod, struct elf_info *info,
700 const Elf_Sym *sym, const char *symname)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701{
Alessio Igor Bogani62a26352011-07-14 08:51:16 +0200702 enum export export;
Masahiro Yamada389eb3f2019-10-03 16:58:22 +0900703 const char *name;
Alessio Igor Bogani62a26352011-07-14 08:51:16 +0200704
Masahiro Yamada33795762020-06-01 14:57:24 +0900705 if (strstarts(symname, "__ksymtab"))
Alessio Igor Bogani62a26352011-07-14 08:51:16 +0200706 export = export_from_secname(info, get_secindex(info, sym));
707 else
708 export = export_from_sec(info, get_secindex(info, sym));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709
710 switch (sym->st_shndx) {
711 case SHN_COMMON:
Masahiro Yamadad62c4762018-05-09 18:50:38 +0900712 if (strstarts(symname, "__gnu_lto_")) {
Andi Kleenef178f92014-02-08 09:01:17 +0100713 /* Should warn here, but modpost runs before the linker */
714 } else
715 warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717 case SHN_UNDEF:
718 /* undefined symbol */
719 if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL &&
720 ELF_ST_BIND(sym->st_info) != STB_WEAK)
721 break;
Sam Ravnborg4d7365d2008-06-12 15:02:55 +0200722 if (ignore_undef_symbol(info, symname))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700723 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724 if (info->hdr->e_machine == EM_SPARC ||
725 info->hdr->e_machine == EM_SPARCV9) {
726 /* Ignore register directives. */
Ben Colline8d529012005-08-19 13:44:57 -0700727 if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728 break;
Sam Ravnborg62070fa2006-03-03 16:46:04 +0100729 if (symname[0] == '.') {
Randy Dunlap1f3aa902018-08-15 12:30:38 -0700730 char *munged = NOFAIL(strdup(symname));
Sam Ravnborg62070fa2006-03-03 16:46:04 +0100731 munged[0] = '_';
732 munged[1] = toupper(munged[1]);
733 symname = munged;
734 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735 }
Sam Ravnborg62070fa2006-03-03 16:46:04 +0100736
Rusty Russellb92021b2013-03-15 15:04:17 +1030737 mod->unres = alloc_symbol(symname,
738 ELF_ST_BIND(sym->st_info) == STB_WEAK,
739 mod->unres);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740 break;
741 default:
742 /* All exported symbols */
Masahiro Yamadad62c4762018-05-09 18:50:38 +0900743 if (strstarts(symname, "__ksymtab_")) {
Matthias Maennichcb9b55d2019-09-06 11:32:28 +0100744 name = symname + strlen("__ksymtab_");
Matthias Maennich9ae5bd12019-10-18 10:31:41 +0100745 sym_add_exported(name, mod, export);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746 }
Masahiro Yamadab2c5cdc2018-05-09 16:23:45 +0900747 if (strcmp(symname, "init_module") == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700748 mod->has_init = 1;
Masahiro Yamadab2c5cdc2018-05-09 16:23:45 +0900749 if (strcmp(symname, "cleanup_module") == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750 mod->has_cleanup = 1;
751 break;
752 }
753}
754
Sam Ravnborg5c3ead82006-01-28 17:19:35 +0100755/**
756 * Parse tag=value strings from .modinfo section
757 **/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758static char *next_string(char *string, unsigned long *secsize)
759{
760 /* Skip non-zero chars */
761 while (string[0]) {
762 string++;
763 if ((*secsize)-- <= 1)
764 return NULL;
765 }
766
767 /* Skip any zero padding. */
768 while (!string[0]) {
769 string++;
770 if ((*secsize)-- <= 1)
771 return NULL;
772 }
773 return string;
774}
775
Masahiro Yamadabca2cce2018-05-09 18:50:37 +0900776static char *get_next_modinfo(struct elf_info *info, const char *tag,
777 char *prev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778{
779 char *p;
780 unsigned int taglen = strlen(tag);
Masahiro Yamadabca2cce2018-05-09 18:50:37 +0900781 char *modinfo = info->modinfo;
782 unsigned long size = info->modinfo_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783
Masahiro Yamadabca2cce2018-05-09 18:50:37 +0900784 if (prev) {
785 size -= prev - modinfo;
786 modinfo = next_string(prev, &size);
Sam Ravnborgb817f6f2006-06-09 21:53:55 +0200787 }
788
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 for (p = modinfo; p; p = next_string(p, &size)) {
790 if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
791 return p + taglen + 1;
792 }
793 return NULL;
794}
795
Masahiro Yamadabca2cce2018-05-09 18:50:37 +0900796static char *get_modinfo(struct elf_info *info, const char *tag)
Sam Ravnborgb817f6f2006-06-09 21:53:55 +0200797
798{
Masahiro Yamadabca2cce2018-05-09 18:50:37 +0900799 return get_next_modinfo(info, tag, NULL);
Sam Ravnborgb817f6f2006-06-09 21:53:55 +0200800}
801
Sam Ravnborg93684d32006-02-19 11:53:35 +0100802/**
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +0100803 * Test if string s ends in string sub
804 * return 0 if match
805 **/
806static int strrcmp(const char *s, const char *sub)
807{
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100808 int slen, sublen;
Sam Ravnborg62070fa2006-03-03 16:46:04 +0100809
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +0100810 if (!s || !sub)
811 return 1;
Sam Ravnborg62070fa2006-03-03 16:46:04 +0100812
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +0100813 slen = strlen(s);
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100814 sublen = strlen(sub);
Sam Ravnborg62070fa2006-03-03 16:46:04 +0100815
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +0100816 if ((slen == 0) || (sublen == 0))
817 return 1;
818
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100819 if (sublen > slen)
820 return 1;
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +0100821
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100822 return memcmp(s + slen - sublen, sub, sublen);
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +0100823}
824
Sam Ravnborgff13f922008-01-23 19:54:27 +0100825static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
826{
Sam Ravnborg58fb0d42008-01-23 21:13:50 +0100827 if (sym)
828 return elf->strtab + sym->st_name;
829 else
Sam Ravnborgf6667512008-02-06 21:51:18 +0100830 return "(unknown)";
Sam Ravnborgff13f922008-01-23 19:54:27 +0100831}
832
Sam Ravnborg10668222008-01-13 22:21:31 +0100833/* The pattern is an array of simple patterns.
834 * "foo" will match an exact string equal to "foo"
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100835 * "*foo" will match a string that ends with "foo"
Sam Ravnborg10668222008-01-13 22:21:31 +0100836 * "foo*" will match a string that begins with "foo"
Paul Gortmaker09c20c02015-04-20 10:20:26 +0930837 * "*foo*" will match a string that contains "foo"
Sam Ravnborg10668222008-01-13 22:21:31 +0100838 */
Trevor Keith5c725132009-09-22 16:43:38 -0700839static int match(const char *sym, const char * const pat[])
Sam Ravnborg10668222008-01-13 22:21:31 +0100840{
841 const char *p;
842 while (*pat) {
843 p = *pat++;
844 const char *endp = p + strlen(p) - 1;
845
Paul Gortmaker09c20c02015-04-20 10:20:26 +0930846 /* "*foo*" */
847 if (*p == '*' && *endp == '*') {
Denis Efremov6f02bdf2019-08-27 15:20:23 +0300848 char *bare = NOFAIL(strndup(p + 1, strlen(p) - 2));
849 char *here = strstr(sym, bare);
Paul Gortmaker09c20c02015-04-20 10:20:26 +0930850
Paul Gortmaker09c20c02015-04-20 10:20:26 +0930851 free(bare);
852 if (here != NULL)
853 return 1;
854 }
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100855 /* "*foo" */
Paul Gortmaker09c20c02015-04-20 10:20:26 +0930856 else if (*p == '*') {
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100857 if (strrcmp(sym, p + 1) == 0)
858 return 1;
859 }
Sam Ravnborg10668222008-01-13 22:21:31 +0100860 /* "foo*" */
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100861 else if (*endp == '*') {
Sam Ravnborg10668222008-01-13 22:21:31 +0100862 if (strncmp(sym, p, strlen(p) - 1) == 0)
863 return 1;
864 }
Sam Ravnborg10668222008-01-13 22:21:31 +0100865 /* no wildcards */
866 else {
867 if (strcmp(p, sym) == 0)
868 return 1;
869 }
870 }
871 /* no match */
872 return 0;
873}
874
Sam Ravnborg10668222008-01-13 22:21:31 +0100875/* sections that we do not want to do full section mismatch check on */
Mathias Krause7a3ee752014-08-27 20:28:53 +0930876static const char *const section_white_list[] =
Sam Ravnborg4391ed62009-05-04 13:05:26 +0200877{
878 ".comment*",
879 ".debug*",
Chen Gang4d10c222013-08-20 15:33:19 +0930880 ".cranges", /* sh64 */
H.J. Lu11215842010-12-15 17:11:22 -0800881 ".zdebug*", /* Compressed debug sections. */
David Howells739d8752018-03-08 09:48:46 +0000882 ".GCC.command.line", /* record-gcc-switches */
Sam Ravnborg4391ed62009-05-04 13:05:26 +0200883 ".mdebug*", /* alpha, score, mips etc. */
884 ".pdr", /* alpha, score, mips etc. */
885 ".stab*",
886 ".note*",
887 ".got*",
888 ".toc*",
Max Filippovaf42e972012-09-17 05:44:38 +0400889 ".xt.prop", /* xtensa */
890 ".xt.lit", /* xtensa */
Vineet Guptaf2e207f2013-01-21 17:18:57 +1030891 ".arcextmap*", /* arc */
892 ".gnu.linkonce.arcext*", /* arc : modules */
Noam Camusd1189c62015-10-26 19:51:46 +1030893 ".cmem*", /* EZchip */
894 ".fmt_slot*", /* EZchip */
Andi Kleenef178f92014-02-08 09:01:17 +0100895 ".gnu.lto*",
Josh Poimboeufe390f9a2017-03-01 12:04:44 -0600896 ".discard.*",
Sam Ravnborg4391ed62009-05-04 13:05:26 +0200897 NULL
898};
Sam Ravnborg10668222008-01-13 22:21:31 +0100899
Sam Ravnborge241a632008-01-28 20:13:13 +0100900/*
Anders Kaseorgb614a692009-04-23 16:49:33 -0400901 * This is used to find sections missing the SHF_ALLOC flag.
Sam Ravnborge241a632008-01-28 20:13:13 +0100902 * The cause of this is often a section specified in assembler
Anders Kaseorgb614a692009-04-23 16:49:33 -0400903 * without "ax" / "aw".
Sam Ravnborge241a632008-01-28 20:13:13 +0100904 */
Anders Kaseorgb614a692009-04-23 16:49:33 -0400905static void check_section(const char *modname, struct elf_info *elf,
Masahiro Yamadabb66fc62014-06-10 19:08:13 +0900906 Elf_Shdr *sechdr)
Sam Ravnborge241a632008-01-28 20:13:13 +0100907{
Anders Kaseorgb614a692009-04-23 16:49:33 -0400908 const char *sec = sech_name(elf, sechdr);
Sam Ravnborge241a632008-01-28 20:13:13 +0100909
Anders Kaseorgb614a692009-04-23 16:49:33 -0400910 if (sechdr->sh_type == SHT_PROGBITS &&
911 !(sechdr->sh_flags & SHF_ALLOC) &&
912 !match(sec, section_white_list)) {
913 warn("%s (%s): unexpected non-allocatable section.\n"
914 "Did you forget to use \"ax\"/\"aw\" in a .S file?\n"
915 "Note that for example <linux/init.h> contains\n"
916 "section definitions for use in .S files.\n\n",
917 modname, sec);
Sam Ravnborge241a632008-01-28 20:13:13 +0100918 }
Sam Ravnborge241a632008-01-28 20:13:13 +0100919}
920
921
922
Sam Ravnborgeb8f6892008-01-20 20:07:28 +0100923#define ALL_INIT_DATA_SECTIONS \
Rasmus Villemoesa0d8f802014-07-27 07:28:01 +0930924 ".init.setup", ".init.rodata", ".meminit.rodata", \
925 ".init.data", ".meminit.data"
Sam Ravnborgeb8f6892008-01-20 20:07:28 +0100926#define ALL_EXIT_DATA_SECTIONS \
Rasmus Villemoesa0d8f802014-07-27 07:28:01 +0930927 ".exit.data", ".memexit.data"
Sam Ravnborg10668222008-01-13 22:21:31 +0100928
Sam Ravnborgeb8f6892008-01-20 20:07:28 +0100929#define ALL_INIT_TEXT_SECTIONS \
Rasmus Villemoesa0d8f802014-07-27 07:28:01 +0930930 ".init.text", ".meminit.text"
Sam Ravnborgeb8f6892008-01-20 20:07:28 +0100931#define ALL_EXIT_TEXT_SECTIONS \
Rasmus Villemoesa0d8f802014-07-27 07:28:01 +0930932 ".exit.text", ".memexit.text"
Sam Ravnborg10668222008-01-13 22:21:31 +0100933
Sebastian Andrzej Siewiorbb15d8d2012-06-03 20:48:17 +0200934#define ALL_PCI_INIT_SECTIONS \
Rasmus Villemoesa0d8f802014-07-27 07:28:01 +0930935 ".pci_fixup_early", ".pci_fixup_header", ".pci_fixup_final", \
936 ".pci_fixup_enable", ".pci_fixup_resume", \
937 ".pci_fixup_resume_early", ".pci_fixup_suspend"
Sebastian Andrzej Siewiorbb15d8d2012-06-03 20:48:17 +0200938
Paul Gortmakere24f6622013-06-19 19:30:48 -0400939#define ALL_XXXINIT_SECTIONS MEM_INIT_SECTIONS
940#define ALL_XXXEXIT_SECTIONS MEM_EXIT_SECTIONS
Uwe Kleine-König4a31a222010-01-29 12:04:26 +0100941
942#define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS
943#define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS
Sam Ravnborg10668222008-01-13 22:21:31 +0100944
Rasmus Villemoesa0d8f802014-07-27 07:28:01 +0930945#define DATA_SECTIONS ".data", ".data.rel"
Quentin Casasnovas157d1972015-04-13 20:42:52 +0930946#define TEXT_SECTIONS ".text", ".text.unlikely", ".sched.text", \
Thomas Gleixner65538962020-03-09 22:47:17 +0100947 ".kprobes.text", ".cpuidle.text", ".noinstr.text"
Quentin Casasnovas52dc0592015-04-13 20:52:53 +0930948#define OTHER_TEXT_SECTIONS ".ref.text", ".head.text", ".spinlock.text", \
Chris Metcalf673c2c32015-07-08 17:07:41 -0400949 ".fixup", ".entry.text", ".exception.text", ".text.*", \
950 ".coldtext"
Sam Ravnborg10668222008-01-13 22:21:31 +0100951
Jan Beulichfd6c3a82009-03-12 10:58:33 +0000952#define INIT_SECTIONS ".init.*"
Jan Beulichfd6c3a82009-03-12 10:58:33 +0000953#define MEM_INIT_SECTIONS ".meminit.*"
Sam Ravnborgeb8f6892008-01-20 20:07:28 +0100954
Jan Beulichfd6c3a82009-03-12 10:58:33 +0000955#define EXIT_SECTIONS ".exit.*"
Jan Beulichfd6c3a82009-03-12 10:58:33 +0000956#define MEM_EXIT_SECTIONS ".memexit.*"
Sam Ravnborgeb8f6892008-01-20 20:07:28 +0100957
Quentin Casasnovas52dc0592015-04-13 20:52:53 +0930958#define ALL_TEXT_SECTIONS ALL_INIT_TEXT_SECTIONS, ALL_EXIT_TEXT_SECTIONS, \
959 TEXT_SECTIONS, OTHER_TEXT_SECTIONS
960
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100961/* init data sections */
Mathias Krause7a3ee752014-08-27 20:28:53 +0930962static const char *const init_data_sections[] =
963 { ALL_INIT_DATA_SECTIONS, NULL };
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100964
965/* all init sections */
Mathias Krause7a3ee752014-08-27 20:28:53 +0930966static const char *const init_sections[] = { ALL_INIT_SECTIONS, NULL };
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100967
968/* All init and exit sections (code + data) */
Mathias Krause7a3ee752014-08-27 20:28:53 +0930969static const char *const init_exit_sections[] =
Sam Ravnborgeb8f6892008-01-20 20:07:28 +0100970 {ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL };
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100971
Paul Gortmaker4a3893d2015-04-20 10:20:40 +0930972/* all text sections */
973static const char *const text_sections[] = { ALL_TEXT_SECTIONS, NULL };
974
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100975/* data section */
Mathias Krause7a3ee752014-08-27 20:28:53 +0930976static const char *const data_sections[] = { DATA_SECTIONS, NULL };
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100977
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100978
979/* symbols in .data that may refer to init/exit sections */
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +0100980#define DEFAULT_SYMBOL_WHITE_LIST \
981 "*driver", \
982 "*_template", /* scsi uses *_template a lot */ \
983 "*_timer", /* arm uses ops structures named _timer a lot */ \
984 "*_sht", /* scsi also used *_sht to some extent */ \
985 "*_ops", \
986 "*_probe", \
987 "*_probe_one", \
988 "*_console"
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100989
Mathias Krause7a3ee752014-08-27 20:28:53 +0930990static const char *const head_sections[] = { ".head.text*", NULL };
991static const char *const linker_symbols[] =
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100992 { "__init_begin", "_sinittext", "_einittext", NULL };
Paul Gortmaker4a3893d2015-04-20 10:20:40 +0930993static const char *const optim_symbols[] = { "*.constprop.*", NULL };
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100994
Sam Ravnborg588ccd72008-01-24 21:12:37 +0100995enum mismatch {
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +0100996 TEXT_TO_ANY_INIT,
997 DATA_TO_ANY_INIT,
998 TEXT_TO_ANY_EXIT,
999 DATA_TO_ANY_EXIT,
1000 XXXINIT_TO_SOME_INIT,
1001 XXXEXIT_TO_SOME_EXIT,
1002 ANY_INIT_TO_ANY_EXIT,
1003 ANY_EXIT_TO_ANY_INIT,
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001004 EXPORT_TO_INIT_EXIT,
Quentin Casasnovas52dc0592015-04-13 20:52:53 +09301005 EXTABLE_TO_NON_TEXT,
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001006};
1007
Quentin Casasnovase5d8f592015-04-13 20:55:15 +09301008/**
1009 * Describe how to match sections on different criterias:
1010 *
1011 * @fromsec: Array of sections to be matched.
1012 *
1013 * @bad_tosec: Relocations applied to a section in @fromsec to a section in
1014 * this array is forbidden (black-list). Can be empty.
1015 *
1016 * @good_tosec: Relocations applied to a section in @fromsec must be
1017 * targetting sections in this array (white-list). Can be empty.
1018 *
1019 * @mismatch: Type of mismatch.
1020 *
1021 * @symbol_white_list: Do not match a relocation to a symbol in this list
1022 * even if it is targetting a section in @bad_to_sec.
1023 *
1024 * @handler: Specific handler to call when a match is found. If NULL,
1025 * default_mismatch_handler() will be called.
1026 *
1027 */
Sam Ravnborg10668222008-01-13 22:21:31 +01001028struct sectioncheck {
1029 const char *fromsec[20];
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301030 const char *bad_tosec[20];
1031 const char *good_tosec[20];
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001032 enum mismatch mismatch;
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001033 const char *symbol_white_list[20];
Quentin Casasnovas644e8f12015-04-13 20:43:17 +09301034 void (*handler)(const char *modname, struct elf_info *elf,
1035 const struct sectioncheck* const mismatch,
1036 Elf_Rela *r, Elf_Sym *sym, const char *fromsec);
1037
Sam Ravnborg10668222008-01-13 22:21:31 +01001038};
1039
Quentin Casasnovas52dc0592015-04-13 20:52:53 +09301040static void extable_mismatch_handler(const char *modname, struct elf_info *elf,
1041 const struct sectioncheck* const mismatch,
1042 Elf_Rela *r, Elf_Sym *sym,
1043 const char *fromsec);
1044
Mathias Krause7a3ee752014-08-27 20:28:53 +09301045static const struct sectioncheck sectioncheck[] = {
Sam Ravnborg10668222008-01-13 22:21:31 +01001046/* Do not reference init/exit code/data from
1047 * normal code and data
1048 */
1049{
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001050 .fromsec = { TEXT_SECTIONS, NULL },
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301051 .bad_tosec = { ALL_INIT_SECTIONS, NULL },
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001052 .mismatch = TEXT_TO_ANY_INIT,
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001053 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001054},
1055{
1056 .fromsec = { DATA_SECTIONS, NULL },
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301057 .bad_tosec = { ALL_XXXINIT_SECTIONS, NULL },
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001058 .mismatch = DATA_TO_ANY_INIT,
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001059 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001060},
1061{
Uwe Kleine-König0db252452010-01-30 21:14:23 +01001062 .fromsec = { DATA_SECTIONS, NULL },
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301063 .bad_tosec = { INIT_SECTIONS, NULL },
Uwe Kleine-König0db252452010-01-30 21:14:23 +01001064 .mismatch = DATA_TO_ANY_INIT,
1065 .symbol_white_list = {
1066 "*_template", "*_timer", "*_sht", "*_ops",
1067 "*_probe", "*_probe_one", "*_console", NULL
1068 },
1069},
1070{
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001071 .fromsec = { TEXT_SECTIONS, NULL },
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301072 .bad_tosec = { ALL_EXIT_SECTIONS, NULL },
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001073 .mismatch = TEXT_TO_ANY_EXIT,
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001074 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001075},
1076{
1077 .fromsec = { DATA_SECTIONS, NULL },
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301078 .bad_tosec = { ALL_EXIT_SECTIONS, NULL },
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001079 .mismatch = DATA_TO_ANY_EXIT,
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001080 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
Sam Ravnborgeb8f6892008-01-20 20:07:28 +01001081},
Paul Gortmakere24f6622013-06-19 19:30:48 -04001082/* Do not reference init code/data from meminit code/data */
Sam Ravnborgeb8f6892008-01-20 20:07:28 +01001083{
Uwe Kleine-König4a31a222010-01-29 12:04:26 +01001084 .fromsec = { ALL_XXXINIT_SECTIONS, NULL },
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301085 .bad_tosec = { INIT_SECTIONS, NULL },
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001086 .mismatch = XXXINIT_TO_SOME_INIT,
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001087 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
Sam Ravnborgeb8f6892008-01-20 20:07:28 +01001088},
Paul Gortmakere24f6622013-06-19 19:30:48 -04001089/* Do not reference exit code/data from memexit code/data */
Sam Ravnborgeb8f6892008-01-20 20:07:28 +01001090{
Uwe Kleine-König4a31a222010-01-29 12:04:26 +01001091 .fromsec = { ALL_XXXEXIT_SECTIONS, NULL },
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301092 .bad_tosec = { EXIT_SECTIONS, NULL },
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001093 .mismatch = XXXEXIT_TO_SOME_EXIT,
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001094 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
Sam Ravnborg10668222008-01-13 22:21:31 +01001095},
1096/* Do not use exit code/data from init code */
1097{
Sam Ravnborgeb8f6892008-01-20 20:07:28 +01001098 .fromsec = { ALL_INIT_SECTIONS, NULL },
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301099 .bad_tosec = { ALL_EXIT_SECTIONS, NULL },
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001100 .mismatch = ANY_INIT_TO_ANY_EXIT,
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001101 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
Sam Ravnborg10668222008-01-13 22:21:31 +01001102},
1103/* Do not use init code/data from exit code */
1104{
Sam Ravnborgeb8f6892008-01-20 20:07:28 +01001105 .fromsec = { ALL_EXIT_SECTIONS, NULL },
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301106 .bad_tosec = { ALL_INIT_SECTIONS, NULL },
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001107 .mismatch = ANY_EXIT_TO_ANY_INIT,
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001108 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
Sam Ravnborg10668222008-01-13 22:21:31 +01001109},
Sebastian Andrzej Siewiorbb15d8d2012-06-03 20:48:17 +02001110{
1111 .fromsec = { ALL_PCI_INIT_SECTIONS, NULL },
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301112 .bad_tosec = { INIT_SECTIONS, NULL },
Sebastian Andrzej Siewiorbb15d8d2012-06-03 20:48:17 +02001113 .mismatch = ANY_INIT_TO_ANY_EXIT,
1114 .symbol_white_list = { NULL },
1115},
Sam Ravnborg10668222008-01-13 22:21:31 +01001116/* Do not export init/exit functions or data */
1117{
1118 .fromsec = { "__ksymtab*", NULL },
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301119 .bad_tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001120 .mismatch = EXPORT_TO_INIT_EXIT,
1121 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
Quentin Casasnovas52dc0592015-04-13 20:52:53 +09301122},
1123{
1124 .fromsec = { "__ex_table", NULL },
1125 /* If you're adding any new black-listed sections in here, consider
1126 * adding a special 'printer' for them in scripts/check_extable.
1127 */
1128 .bad_tosec = { ".altinstr_replacement", NULL },
1129 .good_tosec = {ALL_TEXT_SECTIONS , NULL},
1130 .mismatch = EXTABLE_TO_NON_TEXT,
1131 .handler = extable_mismatch_handler,
Sam Ravnborg10668222008-01-13 22:21:31 +01001132}
1133};
1134
Uwe Kleine-König0d2a6362010-01-30 16:56:20 +01001135static const struct sectioncheck *section_mismatch(
1136 const char *fromsec, const char *tosec)
Sam Ravnborg10668222008-01-13 22:21:31 +01001137{
1138 int i;
1139 int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck);
1140 const struct sectioncheck *check = &sectioncheck[0];
1141
Quentin Casasnovasc5c34392015-04-16 13:16:41 +09301142 /*
1143 * The target section could be the SHT_NUL section when we're
1144 * handling relocations to un-resolved symbols, trying to match it
David Howells739d8752018-03-08 09:48:46 +00001145 * doesn't make much sense and causes build failures on parisc
1146 * architectures.
Quentin Casasnovasc5c34392015-04-16 13:16:41 +09301147 */
1148 if (*tosec == '\0')
1149 return NULL;
1150
Sam Ravnborg10668222008-01-13 22:21:31 +01001151 for (i = 0; i < elems; i++) {
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301152 if (match(fromsec, check->fromsec)) {
1153 if (check->bad_tosec[0] && match(tosec, check->bad_tosec))
1154 return check;
1155 if (check->good_tosec[0] && !match(tosec, check->good_tosec))
1156 return check;
1157 }
Sam Ravnborg10668222008-01-13 22:21:31 +01001158 check++;
1159 }
Uwe Kleine-König0d2a6362010-01-30 16:56:20 +01001160 return NULL;
Sam Ravnborg10668222008-01-13 22:21:31 +01001161}
1162
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001163/**
1164 * Whitelist to allow certain references to pass with no warning.
Sam Ravnborg0e0d3142007-05-17 20:14:48 +02001165 *
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001166 * Pattern 1:
1167 * If a module parameter is declared __initdata and permissions=0
1168 * then this is legal despite the warning generated.
1169 * We cannot see value of permissions here, so just ignore
1170 * this pattern.
1171 * The pattern is identified by:
1172 * tosec = .init.data
Sam Ravnborg9209aed2006-03-05 00:16:26 +01001173 * fromsec = .data*
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001174 * atsym =__param*
Sam Ravnborg62070fa2006-03-03 16:46:04 +01001175 *
Rusty Russell6a841522010-08-11 23:04:16 -06001176 * Pattern 1a:
1177 * module_param_call() ops can refer to __init set function if permissions=0
1178 * The pattern is identified by:
1179 * tosec = .init.text
1180 * fromsec = .data*
1181 * atsym = __param_ops_*
1182 *
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001183 * Pattern 2:
Randy Dunlap72ee59b2006-04-15 11:17:12 -07001184 * Many drivers utilise a *driver container with references to
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001185 * add, remove, probe functions etc.
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001186 * the pattern is identified by:
Sam Ravnborg83cda2b2007-07-25 21:52:31 +02001187 * tosec = init or exit section
1188 * fromsec = data section
Sam Ravnborgdf578e72008-01-11 19:17:15 +01001189 * atsym = *driver, *_template, *_sht, *_ops, *_probe,
1190 * *probe_one, *_console, *_timer
Vivek Goyalee6a8542007-01-11 01:52:44 +01001191 *
1192 * Pattern 3:
Sam Ravnborgc9939712009-04-26 11:17:42 +02001193 * Whitelist all references from .head.text to any init section
Sam Ravnborg9bf8cb92007-02-26 17:49:06 +01001194 *
Sam Ravnborg1d8af552007-06-03 00:41:22 +02001195 * Pattern 4:
Vivek Goyalee6a8542007-01-11 01:52:44 +01001196 * Some symbols belong to init section but still it is ok to reference
1197 * these from non-init sections as these symbols don't have any memory
1198 * allocated for them and symbol address and value are same. So even
1199 * if init section is freed, its ok to reference those symbols.
1200 * For ex. symbols marking the init section boundaries.
1201 * This pattern is identified by
1202 * refsymname = __init_begin, _sinittext, _einittext
Sam Ravnborg9bf8cb92007-02-26 17:49:06 +01001203 *
Paul Gortmaker4a3893d2015-04-20 10:20:40 +09301204 * Pattern 5:
1205 * GCC may optimize static inlines when fed constant arg(s) resulting
1206 * in functions like cpumask_empty() -- generating an associated symbol
1207 * cpumask_empty.constprop.3 that appears in the audit. If the const that
1208 * is passed in comes from __init, like say nmi_ipi_mask, we get a
1209 * meaningless section warning. May need to add isra symbols too...
1210 * This pattern is identified by
1211 * tosec = init section
1212 * fromsec = text section
1213 * refsymname = *.constprop.*
1214 *
Paul Walmsleya4d26f12018-11-21 13:14:13 -08001215 * Pattern 6:
1216 * Hide section mismatch warnings for ELF local symbols. The goal
1217 * is to eliminate false positive modpost warnings caused by
1218 * compiler-generated ELF local symbol names such as ".LANCHOR1".
1219 * Autogenerated symbol names bypass modpost's "Pattern 2"
1220 * whitelisting, which relies on pattern-matching against symbol
1221 * names to work. (One situation where gcc can autogenerate ELF
1222 * local symbols is when "-fsection-anchors" is used.)
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001223 **/
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001224static int secref_whitelist(const struct sectioncheck *mismatch,
1225 const char *fromsec, const char *fromsym,
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001226 const char *tosec, const char *tosym)
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001227{
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001228 /* Check for pattern 1 */
Sam Ravnborg6c5bd232008-01-20 10:43:27 +01001229 if (match(tosec, init_data_sections) &&
1230 match(fromsec, data_sections) &&
Masahiro Yamadad62c4762018-05-09 18:50:38 +09001231 strstarts(fromsym, "__param"))
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001232 return 0;
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001233
Rusty Russell6a841522010-08-11 23:04:16 -06001234 /* Check for pattern 1a */
1235 if (strcmp(tosec, ".init.text") == 0 &&
1236 match(fromsec, data_sections) &&
Masahiro Yamadad62c4762018-05-09 18:50:38 +09001237 strstarts(fromsym, "__param_ops_"))
Rusty Russell6a841522010-08-11 23:04:16 -06001238 return 0;
1239
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001240 /* Check for pattern 2 */
Sam Ravnborg6c5bd232008-01-20 10:43:27 +01001241 if (match(tosec, init_exit_sections) &&
1242 match(fromsec, data_sections) &&
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001243 match(fromsym, mismatch->symbol_white_list))
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001244 return 0;
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001245
Sam Ravnborg9bf8cb92007-02-26 17:49:06 +01001246 /* Check for pattern 3 */
Sam Ravnborg6c5bd232008-01-20 10:43:27 +01001247 if (match(fromsec, head_sections) &&
1248 match(tosec, init_sections))
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001249 return 0;
Sam Ravnborg9bf8cb92007-02-26 17:49:06 +01001250
Sam Ravnborg1d8af552007-06-03 00:41:22 +02001251 /* Check for pattern 4 */
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001252 if (match(tosym, linker_symbols))
1253 return 0;
Sam Ravnborg9bf8cb92007-02-26 17:49:06 +01001254
Paul Gortmaker4a3893d2015-04-20 10:20:40 +09301255 /* Check for pattern 5 */
1256 if (match(fromsec, text_sections) &&
1257 match(tosec, init_sections) &&
1258 match(fromsym, optim_symbols))
1259 return 0;
1260
Paul Walmsleya4d26f12018-11-21 13:14:13 -08001261 /* Check for pattern 6 */
1262 if (strstarts(fromsym, ".L"))
1263 return 0;
1264
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001265 return 1;
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001266}
1267
Sami Tolvanen5818c682018-10-23 15:15:35 -07001268static inline int is_arm_mapping_symbol(const char *str)
1269{
1270 return str[0] == '$' && strchr("axtd", str[1])
1271 && (str[2] == '\0' || str[2] == '.');
1272}
1273
1274/*
1275 * If there's no name there, ignore it; likewise, ignore it if it's
1276 * one of the magic symbols emitted used by current ARM tools.
1277 *
1278 * Otherwise if find_symbols_between() returns those symbols, they'll
1279 * fail the whitelist tests and cause lots of false alarms ... fixable
1280 * only by merging __exit and __init sections into __text, bloating
1281 * the kernel (which is especially evil on embedded platforms).
1282 */
1283static inline int is_valid_name(struct elf_info *elf, Elf_Sym *sym)
1284{
1285 const char *name = elf->strtab + sym->st_name;
1286
1287 if (!name || !strlen(name))
1288 return 0;
1289 return !is_arm_mapping_symbol(name);
1290}
1291
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001292/**
Sam Ravnborg93684d32006-02-19 11:53:35 +01001293 * Find symbol based on relocation record info.
1294 * In some cases the symbol supplied is a valid symbol so
1295 * return refsym. If st_name != 0 we assume this is a valid symbol.
1296 * In other cases the symbol needs to be looked up in the symbol table
1297 * based on section and address.
1298 * **/
Sam Ravnborg9ad21c32008-01-18 21:04:34 +01001299static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,
Sam Ravnborg93684d32006-02-19 11:53:35 +01001300 Elf_Sym *relsym)
1301{
1302 Elf_Sym *sym;
Sam Ravnborg9ad21c32008-01-18 21:04:34 +01001303 Elf_Sym *near = NULL;
1304 Elf64_Sword distance = 20;
1305 Elf64_Sword d;
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +02001306 unsigned int relsym_secindex;
Sam Ravnborg93684d32006-02-19 11:53:35 +01001307
1308 if (relsym->st_name != 0)
1309 return relsym;
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +02001310
1311 relsym_secindex = get_secindex(elf, relsym);
Sam Ravnborg93684d32006-02-19 11:53:35 +01001312 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +02001313 if (get_secindex(elf, sym) != relsym_secindex)
Sam Ravnborg93684d32006-02-19 11:53:35 +01001314 continue;
Atsushi Nemotoae4ac122007-05-22 18:27:39 +09001315 if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
1316 continue;
Sami Tolvanen5818c682018-10-23 15:15:35 -07001317 if (!is_valid_name(elf, sym))
1318 continue;
Sam Ravnborg93684d32006-02-19 11:53:35 +01001319 if (sym->st_value == addr)
1320 return sym;
Sam Ravnborg9ad21c32008-01-18 21:04:34 +01001321 /* Find a symbol nearby - addr are maybe negative */
1322 d = sym->st_value - addr;
1323 if (d < 0)
1324 d = addr - sym->st_value;
1325 if (d < distance) {
1326 distance = d;
1327 near = sym;
1328 }
Sam Ravnborg93684d32006-02-19 11:53:35 +01001329 }
Sam Ravnborg9ad21c32008-01-18 21:04:34 +01001330 /* We need a close match */
1331 if (distance < 20)
1332 return near;
1333 else
1334 return NULL;
Sam Ravnborg93684d32006-02-19 11:53:35 +01001335}
1336
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001337/*
Sam Ravnborg43c74d12006-03-05 12:02:46 +01001338 * Find symbols before or equal addr and after addr - in the section sec.
1339 * If we find two symbols with equal offset prefer one with a valid name.
1340 * The ELF format may have a better way to detect what type of symbol
1341 * it is, but this works for now.
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001342 **/
Sam Ravnborg157c23c2008-01-22 21:44:32 +01001343static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
1344 const char *sec)
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001345{
1346 Elf_Sym *sym;
Sam Ravnborg157c23c2008-01-22 21:44:32 +01001347 Elf_Sym *near = NULL;
Sam Ravnborg157c23c2008-01-22 21:44:32 +01001348 Elf_Addr distance = ~0;
Sam Ravnborg62070fa2006-03-03 16:46:04 +01001349
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001350 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
1351 const char *symsec;
1352
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +02001353 if (is_shndx_special(sym->st_shndx))
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001354 continue;
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +02001355 symsec = sec_name(elf, get_secindex(elf, sym));
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001356 if (strcmp(symsec, sec) != 0)
1357 continue;
David Brownellda68d612007-02-20 13:58:16 -08001358 if (!is_valid_name(elf, sym))
1359 continue;
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001360 if (sym->st_value <= addr) {
Sam Ravnborg157c23c2008-01-22 21:44:32 +01001361 if ((addr - sym->st_value) < distance) {
1362 distance = addr - sym->st_value;
1363 near = sym;
1364 } else if ((addr - sym->st_value) == distance) {
1365 near = sym;
Sam Ravnborg43c74d12006-03-05 12:02:46 +01001366 }
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001367 }
1368 }
Sam Ravnborg157c23c2008-01-22 21:44:32 +01001369 return near;
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001370}
1371
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001372/*
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001373 * Convert a section name to the function/data attribute
1374 * .init.text => __init
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001375 * .memexitconst => __memconst
1376 * etc.
Andy Shevchenkocbcf14a92010-08-17 13:36:40 +03001377 *
1378 * The memory of returned value has been allocated on a heap. The user of this
1379 * method should free it after usage.
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001380*/
1381static char *sec2annotation(const char *s)
1382{
1383 if (match(s, init_exit_sections)) {
Randy Dunlap1f3aa902018-08-15 12:30:38 -07001384 char *p = NOFAIL(malloc(20));
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001385 char *r = p;
1386
1387 *p++ = '_';
1388 *p++ = '_';
1389 if (*s == '.')
1390 s++;
1391 while (*s && *s != '.')
1392 *p++ = *s++;
1393 *p = '\0';
1394 if (*s == '.')
1395 s++;
1396 if (strstr(s, "rodata") != NULL)
1397 strcat(p, "const ");
1398 else if (strstr(s, "data") != NULL)
1399 strcat(p, "data ");
1400 else
1401 strcat(p, " ");
Andy Shevchenkocbcf14a92010-08-17 13:36:40 +03001402 return r;
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001403 } else {
Randy Dunlap1f3aa902018-08-15 12:30:38 -07001404 return NOFAIL(strdup(""));
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001405 }
1406}
1407
1408static int is_function(Elf_Sym *sym)
1409{
1410 if (sym)
1411 return ELF_ST_TYPE(sym->st_info) == STT_FUNC;
1412 else
Sam Ravnborgf6667512008-02-06 21:51:18 +01001413 return -1;
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001414}
1415
Randy Dunlap00759c02011-03-15 14:13:47 -07001416static void print_section_list(const char * const list[20])
1417{
1418 const char *const *s = list;
1419
1420 while (*s) {
1421 fprintf(stderr, "%s", *s);
1422 s++;
1423 if (*s)
1424 fprintf(stderr, ", ");
1425 }
1426 fprintf(stderr, "\n");
1427}
1428
Quentin Casasnovas356ad532015-04-13 20:43:34 +09301429static inline void get_pretty_name(int is_func, const char** name, const char** name_p)
1430{
1431 switch (is_func) {
1432 case 0: *name = "variable"; *name_p = ""; break;
1433 case 1: *name = "function"; *name_p = "()"; break;
1434 default: *name = "(unknown reference)"; *name_p = ""; break;
1435 }
1436}
1437
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001438/*
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001439 * Print a warning about a section mismatch.
1440 * Try to find symbols near it so user can find it.
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001441 * Check whitelist before warning - it may be a false positive.
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001442 */
Uwe Kleine-König0d2a6362010-01-30 16:56:20 +01001443static void report_sec_mismatch(const char *modname,
1444 const struct sectioncheck *mismatch,
Masahiro Yamadabb66fc62014-06-10 19:08:13 +09001445 const char *fromsec,
1446 unsigned long long fromaddr,
1447 const char *fromsym,
1448 int from_is_func,
1449 const char *tosec, const char *tosym,
1450 int to_is_func)
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001451{
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001452 const char *from, *from_p;
1453 const char *to, *to_p;
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001454 char *prl_from;
1455 char *prl_to;
Sam Ravnborgf6667512008-02-06 21:51:18 +01001456
Sam Ravnborge5f95c82008-02-02 18:57:18 +01001457 sec_mismatch_count++;
Sam Ravnborge5f95c82008-02-02 18:57:18 +01001458
Quentin Casasnovas356ad532015-04-13 20:43:34 +09301459 get_pretty_name(from_is_func, &from, &from_p);
1460 get_pretty_name(to_is_func, &to, &to_p);
1461
Geert Uytterhoeven7c0ac492008-02-05 11:38:49 +01001462 warn("%s(%s+0x%llx): Section mismatch in reference from the %s %s%s "
1463 "to the %s %s:%s%s\n",
1464 modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec,
1465 tosym, to_p);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001466
Uwe Kleine-König0d2a6362010-01-30 16:56:20 +01001467 switch (mismatch->mismatch) {
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001468 case TEXT_TO_ANY_INIT:
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001469 prl_from = sec2annotation(fromsec);
1470 prl_to = sec2annotation(tosec);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001471 fprintf(stderr,
Sam Ravnborgf6667512008-02-06 21:51:18 +01001472 "The function %s%s() references\n"
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001473 "the %s %s%s%s.\n"
1474 "This is often because %s lacks a %s\n"
1475 "annotation or the annotation of %s is wrong.\n",
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001476 prl_from, fromsym,
1477 to, prl_to, tosym, to_p,
1478 fromsym, prl_to, tosym);
1479 free(prl_from);
1480 free(prl_to);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001481 break;
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001482 case DATA_TO_ANY_INIT: {
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001483 prl_to = sec2annotation(tosec);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001484 fprintf(stderr,
1485 "The variable %s references\n"
1486 "the %s %s%s%s\n"
1487 "If the reference is valid then annotate the\n"
Sam Ravnborg8b8b76c2009-06-06 00:18:05 +02001488 "variable with __init* or __refdata (see linux/init.h) "
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001489 "or name the variable:\n",
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001490 fromsym, to, prl_to, tosym, to_p);
Randy Dunlap00759c02011-03-15 14:13:47 -07001491 print_section_list(mismatch->symbol_white_list);
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001492 free(prl_to);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001493 break;
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001494 }
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001495 case TEXT_TO_ANY_EXIT:
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001496 prl_to = sec2annotation(tosec);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001497 fprintf(stderr,
1498 "The function %s() references a %s in an exit section.\n"
1499 "Often the %s %s%s has valid usage outside the exit section\n"
1500 "and the fix is to remove the %sannotation of %s.\n",
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001501 fromsym, to, to, tosym, to_p, prl_to, tosym);
1502 free(prl_to);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001503 break;
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001504 case DATA_TO_ANY_EXIT: {
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001505 prl_to = sec2annotation(tosec);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001506 fprintf(stderr,
1507 "The variable %s references\n"
1508 "the %s %s%s%s\n"
1509 "If the reference is valid then annotate the\n"
1510 "variable with __exit* (see linux/init.h) or "
1511 "name the variable:\n",
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001512 fromsym, to, prl_to, tosym, to_p);
Randy Dunlap00759c02011-03-15 14:13:47 -07001513 print_section_list(mismatch->symbol_white_list);
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001514 free(prl_to);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001515 break;
1516 }
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001517 case XXXINIT_TO_SOME_INIT:
1518 case XXXEXIT_TO_SOME_EXIT:
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001519 prl_from = sec2annotation(fromsec);
1520 prl_to = sec2annotation(tosec);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001521 fprintf(stderr,
1522 "The %s %s%s%s references\n"
1523 "a %s %s%s%s.\n"
1524 "If %s is only used by %s then\n"
1525 "annotate %s with a matching annotation.\n",
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001526 from, prl_from, fromsym, from_p,
1527 to, prl_to, tosym, to_p,
Geert Uytterhoevenb1d26752008-02-17 14:12:10 +01001528 tosym, fromsym, tosym);
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001529 free(prl_from);
1530 free(prl_to);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001531 break;
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001532 case ANY_INIT_TO_ANY_EXIT:
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001533 prl_from = sec2annotation(fromsec);
1534 prl_to = sec2annotation(tosec);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001535 fprintf(stderr,
1536 "The %s %s%s%s references\n"
1537 "a %s %s%s%s.\n"
1538 "This is often seen when error handling "
1539 "in the init function\n"
1540 "uses functionality in the exit path.\n"
1541 "The fix is often to remove the %sannotation of\n"
1542 "%s%s so it may be used outside an exit section.\n",
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001543 from, prl_from, fromsym, from_p,
1544 to, prl_to, tosym, to_p,
Andrew Morton5003bab2010-08-11 00:42:26 -07001545 prl_to, tosym, to_p);
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001546 free(prl_from);
1547 free(prl_to);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001548 break;
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001549 case ANY_EXIT_TO_ANY_INIT:
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001550 prl_from = sec2annotation(fromsec);
1551 prl_to = sec2annotation(tosec);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001552 fprintf(stderr,
1553 "The %s %s%s%s references\n"
1554 "a %s %s%s%s.\n"
1555 "This is often seen when error handling "
1556 "in the exit function\n"
1557 "uses functionality in the init path.\n"
1558 "The fix is often to remove the %sannotation of\n"
1559 "%s%s so it may be used outside an init section.\n",
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001560 from, prl_from, fromsym, from_p,
1561 to, prl_to, tosym, to_p,
1562 prl_to, tosym, to_p);
1563 free(prl_from);
1564 free(prl_to);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001565 break;
1566 case EXPORT_TO_INIT_EXIT:
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001567 prl_to = sec2annotation(tosec);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001568 fprintf(stderr,
1569 "The symbol %s is exported and annotated %s\n"
1570 "Fix this by removing the %sannotation of %s "
1571 "or drop the export.\n",
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001572 tosym, prl_to, prl_to, tosym);
1573 free(prl_to);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001574 break;
Quentin Casasnovas52dc0592015-04-13 20:52:53 +09301575 case EXTABLE_TO_NON_TEXT:
1576 fatal("There's a special handler for this mismatch type, "
1577 "we should never get here.");
1578 break;
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001579 }
1580 fprintf(stderr, "\n");
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001581}
1582
Quentin Casasnovas644e8f12015-04-13 20:43:17 +09301583static void default_mismatch_handler(const char *modname, struct elf_info *elf,
1584 const struct sectioncheck* const mismatch,
1585 Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
1586{
1587 const char *tosec;
1588 Elf_Sym *to;
1589 Elf_Sym *from;
1590 const char *tosym;
1591 const char *fromsym;
1592
Quentin Casasnovas644e8f12015-04-13 20:43:17 +09301593 from = find_elf_symbol2(elf, r->r_offset, fromsec);
1594 fromsym = sym_name(elf, from);
Quentin Casasnovas644e8f12015-04-13 20:43:17 +09301595
Masahiro Yamadad62c4762018-05-09 18:50:38 +09001596 if (strstarts(fromsym, "reference___initcall"))
Quentin Casasnovas644e8f12015-04-13 20:43:17 +09301597 return;
1598
Quentin Casasnovasc7a65e02015-04-13 20:43:45 +09301599 tosec = sec_name(elf, get_secindex(elf, sym));
1600 to = find_elf_symbol(elf, r->r_addend, sym);
1601 tosym = sym_name(elf, to);
1602
Quentin Casasnovas644e8f12015-04-13 20:43:17 +09301603 /* check whitelist - we may ignore it */
1604 if (secref_whitelist(mismatch,
1605 fromsec, fromsym, tosec, tosym)) {
1606 report_sec_mismatch(modname, mismatch,
1607 fromsec, r->r_offset, fromsym,
1608 is_function(from), tosec, tosym,
1609 is_function(to));
1610 }
1611}
1612
Quentin Casasnovas52dc0592015-04-13 20:52:53 +09301613static int is_executable_section(struct elf_info* elf, unsigned int section_index)
1614{
1615 if (section_index > elf->num_sections)
1616 fatal("section_index is outside elf->num_sections!\n");
1617
1618 return ((elf->sechdrs[section_index].sh_flags & SHF_EXECINSTR) == SHF_EXECINSTR);
1619}
1620
1621/*
1622 * We rely on a gross hack in section_rel[a]() calling find_extable_entry_size()
1623 * to know the sizeof(struct exception_table_entry) for the target architecture.
1624 */
1625static unsigned int extable_entry_size = 0;
Quentin Casasnovase84048a2015-04-16 13:05:36 +09301626static void find_extable_entry_size(const char* const sec, const Elf_Rela* r)
Quentin Casasnovas52dc0592015-04-13 20:52:53 +09301627{
1628 /*
1629 * If we're currently checking the second relocation within __ex_table,
1630 * that relocation offset tells us the offsetof(struct
1631 * exception_table_entry, fixup) which is equal to sizeof(struct
1632 * exception_table_entry) divided by two. We use that to our advantage
1633 * since there's no portable way to get that size as every architecture
1634 * seems to go with different sized types. Not pretty but better than
1635 * hard-coding the size for every architecture..
1636 */
Quentin Casasnovase84048a2015-04-16 13:05:36 +09301637 if (!extable_entry_size)
Quentin Casasnovas52dc0592015-04-13 20:52:53 +09301638 extable_entry_size = r->r_offset * 2;
1639}
Quentin Casasnovase84048a2015-04-16 13:05:36 +09301640
Quentin Casasnovas52dc0592015-04-13 20:52:53 +09301641static inline bool is_extable_fault_address(Elf_Rela *r)
1642{
Quentin Casasnovasd3df4de2015-04-16 13:03:32 +09301643 /*
1644 * extable_entry_size is only discovered after we've handled the
1645 * _second_ relocation in __ex_table, so only abort when we're not
1646 * handling the first reloc and extable_entry_size is zero.
1647 */
1648 if (r->r_offset && extable_entry_size == 0)
Quentin Casasnovas52dc0592015-04-13 20:52:53 +09301649 fatal("extable_entry size hasn't been discovered!\n");
1650
1651 return ((r->r_offset == 0) ||
1652 (r->r_offset % extable_entry_size == 0));
1653}
1654
Quentin Casasnovase84048a2015-04-16 13:05:36 +09301655#define is_second_extable_reloc(Start, Cur, Sec) \
1656 (((Cur) == (Start) + 1) && (strcmp("__ex_table", (Sec)) == 0))
1657
Quentin Casasnovas52dc0592015-04-13 20:52:53 +09301658static void report_extable_warnings(const char* modname, struct elf_info* elf,
1659 const struct sectioncheck* const mismatch,
1660 Elf_Rela* r, Elf_Sym* sym,
1661 const char* fromsec, const char* tosec)
1662{
1663 Elf_Sym* fromsym = find_elf_symbol2(elf, r->r_offset, fromsec);
1664 const char* fromsym_name = sym_name(elf, fromsym);
1665 Elf_Sym* tosym = find_elf_symbol(elf, r->r_addend, sym);
1666 const char* tosym_name = sym_name(elf, tosym);
1667 const char* from_pretty_name;
1668 const char* from_pretty_name_p;
1669 const char* to_pretty_name;
1670 const char* to_pretty_name_p;
1671
1672 get_pretty_name(is_function(fromsym),
1673 &from_pretty_name, &from_pretty_name_p);
1674 get_pretty_name(is_function(tosym),
1675 &to_pretty_name, &to_pretty_name_p);
1676
1677 warn("%s(%s+0x%lx): Section mismatch in reference"
1678 " from the %s %s%s to the %s %s:%s%s\n",
1679 modname, fromsec, (long)r->r_offset, from_pretty_name,
1680 fromsym_name, from_pretty_name_p,
1681 to_pretty_name, tosec, tosym_name, to_pretty_name_p);
1682
1683 if (!match(tosec, mismatch->bad_tosec) &&
1684 is_executable_section(elf, get_secindex(elf, sym)))
1685 fprintf(stderr,
1686 "The relocation at %s+0x%lx references\n"
1687 "section \"%s\" which is not in the list of\n"
1688 "authorized sections. If you're adding a new section\n"
1689 "and/or if this reference is valid, add \"%s\" to the\n"
1690 "list of authorized sections to jump to on fault.\n"
1691 "This can be achieved by adding \"%s\" to \n"
1692 "OTHER_TEXT_SECTIONS in scripts/mod/modpost.c.\n",
1693 fromsec, (long)r->r_offset, tosec, tosec, tosec);
1694}
1695
1696static void extable_mismatch_handler(const char* modname, struct elf_info *elf,
1697 const struct sectioncheck* const mismatch,
1698 Elf_Rela* r, Elf_Sym* sym,
1699 const char *fromsec)
1700{
1701 const char* tosec = sec_name(elf, get_secindex(elf, sym));
1702
1703 sec_mismatch_count++;
1704
Masahiro Yamada46c7dd52019-02-01 13:50:45 +09001705 report_extable_warnings(modname, elf, mismatch, r, sym, fromsec, tosec);
Quentin Casasnovas52dc0592015-04-13 20:52:53 +09301706
1707 if (match(tosec, mismatch->bad_tosec))
1708 fatal("The relocation at %s+0x%lx references\n"
1709 "section \"%s\" which is black-listed.\n"
1710 "Something is seriously wrong and should be fixed.\n"
1711 "You might get more information about where this is\n"
1712 "coming from by using scripts/check_extable.sh %s\n",
1713 fromsec, (long)r->r_offset, tosec, modname);
1714 else if (!is_executable_section(elf, get_secindex(elf, sym))) {
1715 if (is_extable_fault_address(r))
1716 fatal("The relocation at %s+0x%lx references\n"
1717 "section \"%s\" which is not executable, IOW\n"
1718 "it is not possible for the kernel to fault\n"
1719 "at that address. Something is seriously wrong\n"
1720 "and should be fixed.\n",
1721 fromsec, (long)r->r_offset, tosec);
1722 else
1723 fatal("The relocation at %s+0x%lx references\n"
1724 "section \"%s\" which is not executable, IOW\n"
1725 "the kernel will fault if it ever tries to\n"
1726 "jump to it. Something is seriously wrong\n"
1727 "and should be fixed.\n",
1728 fromsec, (long)r->r_offset, tosec);
1729 }
1730}
1731
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001732static void check_section_mismatch(const char *modname, struct elf_info *elf,
Masahiro Yamadabb66fc62014-06-10 19:08:13 +09001733 Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001734{
Luis de Bethencourt0cad61d2018-01-16 13:21:29 +00001735 const char *tosec = sec_name(elf, get_secindex(elf, sym));
Quentin Casasnovas644e8f12015-04-13 20:43:17 +09301736 const struct sectioncheck *mismatch = section_mismatch(fromsec, tosec);
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001737
Uwe Kleine-König0d2a6362010-01-30 16:56:20 +01001738 if (mismatch) {
Quentin Casasnovas644e8f12015-04-13 20:43:17 +09301739 if (mismatch->handler)
1740 mismatch->handler(modname, elf, mismatch,
1741 r, sym, fromsec);
1742 else
1743 default_mismatch_handler(modname, elf, mismatch,
1744 r, sym, fromsec);
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001745 }
1746}
1747
Atsushi Nemotoae4ac122007-05-22 18:27:39 +09001748static unsigned int *reloc_location(struct elf_info *elf,
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001749 Elf_Shdr *sechdr, Elf_Rela *r)
Atsushi Nemotoae4ac122007-05-22 18:27:39 +09001750{
Masahiro Yamadad2e4d052020-05-25 14:47:04 +09001751 return sym_get_data_by_offset(elf, sechdr->sh_info, r->r_offset);
Atsushi Nemotoae4ac122007-05-22 18:27:39 +09001752}
1753
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001754static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
Atsushi Nemotoae4ac122007-05-22 18:27:39 +09001755{
1756 unsigned int r_typ = ELF_R_TYPE(r->r_info);
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001757 unsigned int *location = reloc_location(elf, sechdr, r);
Atsushi Nemotoae4ac122007-05-22 18:27:39 +09001758
1759 switch (r_typ) {
1760 case R_386_32:
1761 r->r_addend = TO_NATIVE(*location);
1762 break;
1763 case R_386_PC32:
1764 r->r_addend = TO_NATIVE(*location) + 4;
1765 /* For CONFIG_RELOCATABLE=y */
1766 if (elf->hdr->e_type == ET_EXEC)
1767 r->r_addend += r->r_offset;
1768 break;
1769 }
1770 return 0;
1771}
1772
Tony Lindgren6e2e3402012-02-14 21:58:56 +01001773#ifndef R_ARM_CALL
1774#define R_ARM_CALL 28
1775#endif
1776#ifndef R_ARM_JUMP24
1777#define R_ARM_JUMP24 29
1778#endif
1779
David A. Longc9698e52014-02-14 22:41:18 +01001780#ifndef R_ARM_THM_CALL
1781#define R_ARM_THM_CALL 10
1782#endif
1783#ifndef R_ARM_THM_JUMP24
1784#define R_ARM_THM_JUMP24 30
1785#endif
1786#ifndef R_ARM_THM_JUMP19
1787#define R_ARM_THM_JUMP19 51
1788#endif
1789
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001790static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
Sam Ravnborg56a974f2007-07-16 22:39:35 +02001791{
1792 unsigned int r_typ = ELF_R_TYPE(r->r_info);
1793
1794 switch (r_typ) {
1795 case R_ARM_ABS32:
1796 /* From ARM ABI: (S + A) | T */
Sam Ravnborgdf578e72008-01-11 19:17:15 +01001797 r->r_addend = (int)(long)
Masahiro Yamadabb66fc62014-06-10 19:08:13 +09001798 (elf->symtab_start + ELF_R_SYM(r->r_info));
Sam Ravnborg56a974f2007-07-16 22:39:35 +02001799 break;
1800 case R_ARM_PC24:
Tony Lindgren6e2e3402012-02-14 21:58:56 +01001801 case R_ARM_CALL:
1802 case R_ARM_JUMP24:
David A. Longc9698e52014-02-14 22:41:18 +01001803 case R_ARM_THM_CALL:
1804 case R_ARM_THM_JUMP24:
1805 case R_ARM_THM_JUMP19:
Sam Ravnborg56a974f2007-07-16 22:39:35 +02001806 /* From ARM ABI: ((S + A) | T) - P */
Sam Ravnborgdf578e72008-01-11 19:17:15 +01001807 r->r_addend = (int)(long)(elf->hdr +
Masahiro Yamadabb66fc62014-06-10 19:08:13 +09001808 sechdr->sh_offset +
1809 (r->r_offset - sechdr->sh_addr));
Sam Ravnborg56a974f2007-07-16 22:39:35 +02001810 break;
1811 default:
1812 return 1;
1813 }
1814 return 0;
1815}
1816
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001817static int addend_mips_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
Atsushi Nemotoae4ac122007-05-22 18:27:39 +09001818{
1819 unsigned int r_typ = ELF_R_TYPE(r->r_info);
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001820 unsigned int *location = reloc_location(elf, sechdr, r);
Atsushi Nemotoae4ac122007-05-22 18:27:39 +09001821 unsigned int inst;
1822
1823 if (r_typ == R_MIPS_HI16)
1824 return 1; /* skip this */
1825 inst = TO_NATIVE(*location);
1826 switch (r_typ) {
1827 case R_MIPS_LO16:
1828 r->r_addend = inst & 0xffff;
1829 break;
1830 case R_MIPS_26:
1831 r->r_addend = (inst & 0x03ffffff) << 2;
1832 break;
1833 case R_MIPS_32:
1834 r->r_addend = inst;
1835 break;
1836 }
1837 return 0;
1838}
1839
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001840static void section_rela(const char *modname, struct elf_info *elf,
Masahiro Yamadabb66fc62014-06-10 19:08:13 +09001841 Elf_Shdr *sechdr)
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001842{
1843 Elf_Sym *sym;
1844 Elf_Rela *rela;
1845 Elf_Rela r;
1846 unsigned int r_sym;
1847 const char *fromsec;
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001848
Sam Ravnborgff13f922008-01-23 19:54:27 +01001849 Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset;
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001850 Elf_Rela *stop = (void *)start + sechdr->sh_size;
1851
Sam Ravnborgff13f922008-01-23 19:54:27 +01001852 fromsec = sech_name(elf, sechdr);
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001853 fromsec += strlen(".rela");
1854 /* if from section (name) is know good then skip it */
Anders Kaseorgb614a692009-04-23 16:49:33 -04001855 if (match(fromsec, section_white_list))
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001856 return;
Sam Ravnborge241a632008-01-28 20:13:13 +01001857
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001858 for (rela = start; rela < stop; rela++) {
1859 r.r_offset = TO_NATIVE(rela->r_offset);
1860#if KERNEL_ELFCLASS == ELFCLASS64
Sam Ravnborgff13f922008-01-23 19:54:27 +01001861 if (elf->hdr->e_machine == EM_MIPS) {
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001862 unsigned int r_typ;
1863 r_sym = ELF64_MIPS_R_SYM(rela->r_info);
1864 r_sym = TO_NATIVE(r_sym);
1865 r_typ = ELF64_MIPS_R_TYPE(rela->r_info);
1866 r.r_info = ELF64_R_INFO(r_sym, r_typ);
1867 } else {
1868 r.r_info = TO_NATIVE(rela->r_info);
1869 r_sym = ELF_R_SYM(r.r_info);
1870 }
1871#else
1872 r.r_info = TO_NATIVE(rela->r_info);
1873 r_sym = ELF_R_SYM(r.r_info);
1874#endif
1875 r.r_addend = TO_NATIVE(rela->r_addend);
1876 sym = elf->symtab_start + r_sym;
1877 /* Skip special sections */
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +02001878 if (is_shndx_special(sym->st_shndx))
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001879 continue;
Quentin Casasnovase84048a2015-04-16 13:05:36 +09301880 if (is_second_extable_reloc(start, rela, fromsec))
1881 find_extable_entry_size(fromsec, &r);
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001882 check_section_mismatch(modname, elf, &r, sym, fromsec);
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001883 }
1884}
1885
1886static void section_rel(const char *modname, struct elf_info *elf,
Masahiro Yamadabb66fc62014-06-10 19:08:13 +09001887 Elf_Shdr *sechdr)
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001888{
1889 Elf_Sym *sym;
1890 Elf_Rel *rel;
1891 Elf_Rela r;
1892 unsigned int r_sym;
1893 const char *fromsec;
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001894
Sam Ravnborgff13f922008-01-23 19:54:27 +01001895 Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset;
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001896 Elf_Rel *stop = (void *)start + sechdr->sh_size;
1897
Sam Ravnborgff13f922008-01-23 19:54:27 +01001898 fromsec = sech_name(elf, sechdr);
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001899 fromsec += strlen(".rel");
1900 /* if from section (name) is know good then skip it */
Anders Kaseorgb614a692009-04-23 16:49:33 -04001901 if (match(fromsec, section_white_list))
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001902 return;
1903
1904 for (rel = start; rel < stop; rel++) {
1905 r.r_offset = TO_NATIVE(rel->r_offset);
1906#if KERNEL_ELFCLASS == ELFCLASS64
Sam Ravnborgff13f922008-01-23 19:54:27 +01001907 if (elf->hdr->e_machine == EM_MIPS) {
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001908 unsigned int r_typ;
1909 r_sym = ELF64_MIPS_R_SYM(rel->r_info);
1910 r_sym = TO_NATIVE(r_sym);
1911 r_typ = ELF64_MIPS_R_TYPE(rel->r_info);
1912 r.r_info = ELF64_R_INFO(r_sym, r_typ);
1913 } else {
1914 r.r_info = TO_NATIVE(rel->r_info);
1915 r_sym = ELF_R_SYM(r.r_info);
1916 }
1917#else
1918 r.r_info = TO_NATIVE(rel->r_info);
1919 r_sym = ELF_R_SYM(r.r_info);
1920#endif
1921 r.r_addend = 0;
Sam Ravnborgff13f922008-01-23 19:54:27 +01001922 switch (elf->hdr->e_machine) {
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001923 case EM_386:
1924 if (addend_386_rel(elf, sechdr, &r))
1925 continue;
1926 break;
1927 case EM_ARM:
1928 if (addend_arm_rel(elf, sechdr, &r))
1929 continue;
1930 break;
1931 case EM_MIPS:
1932 if (addend_mips_rel(elf, sechdr, &r))
1933 continue;
1934 break;
1935 }
1936 sym = elf->symtab_start + r_sym;
1937 /* Skip special sections */
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +02001938 if (is_shndx_special(sym->st_shndx))
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001939 continue;
Quentin Casasnovase84048a2015-04-16 13:05:36 +09301940 if (is_second_extable_reloc(start, rel, fromsec))
1941 find_extable_entry_size(fromsec, &r);
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001942 check_section_mismatch(modname, elf, &r, sym, fromsec);
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001943 }
1944}
1945
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001946/**
1947 * A module includes a number of sections that are discarded
1948 * either when loaded or when used as built-in.
1949 * For loaded modules all functions marked __init and all data
Uwe Kleine-Königb5950762010-11-01 15:38:34 -04001950 * marked __initdata will be discarded when the module has been initialized.
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001951 * Likewise for modules used built-in the sections marked __exit
1952 * are discarded because __exit marked function are supposed to be called
Ben Dooks32be1d22008-07-29 22:33:44 -07001953 * only when a module is unloaded which never happens for built-in modules.
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001954 * The check_sec_ref() function traverses all relocation records
1955 * to find all references to a section that reference a section that will
1956 * be discarded and warns about it.
1957 **/
1958static void check_sec_ref(struct module *mod, const char *modname,
Masahiro Yamadabb66fc62014-06-10 19:08:13 +09001959 struct elf_info *elf)
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001960{
1961 int i;
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001962 Elf_Shdr *sechdrs = elf->sechdrs;
Sam Ravnborg62070fa2006-03-03 16:46:04 +01001963
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001964 /* Walk through all sections */
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +02001965 for (i = 0; i < elf->num_sections; i++) {
Anders Kaseorgb614a692009-04-23 16:49:33 -04001966 check_section(modname, elf, &elf->sechdrs[i]);
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001967 /* We want to process only relocation sections and not .init */
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001968 if (sechdrs[i].sh_type == SHT_RELA)
Sam Ravnborg10668222008-01-13 22:21:31 +01001969 section_rela(modname, elf, &elf->sechdrs[i]);
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001970 else if (sechdrs[i].sh_type == SHT_REL)
Sam Ravnborg10668222008-01-13 22:21:31 +01001971 section_rel(modname, elf, &elf->sechdrs[i]);
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001972 }
1973}
1974
Andi Kleen7d02b492014-02-08 09:01:12 +01001975static char *remove_dot(char *s)
1976{
Michal Nazarewiczfcd38ed2014-07-27 07:27:01 +09301977 size_t n = strcspn(s, ".");
Andi Kleen7d02b492014-02-08 09:01:12 +01001978
Michal Nazarewiczfcd38ed2014-07-27 07:27:01 +09301979 if (n && s[n]) {
1980 size_t m = strspn(s + n + 1, "0123456789");
1981 if (m && (s[n + m] == '.' || s[n + m] == 0))
Andi Kleen7d02b492014-02-08 09:01:12 +01001982 s[n] = 0;
Sami Tolvanen1f975cd2020-03-06 13:52:03 -08001983
1984 /* strip trailing .lto */
1985 if (strends(s, ".lto"))
1986 s[strlen(s) - 4] = '\0';
Andi Kleen7d02b492014-02-08 09:01:12 +01001987 }
1988 return s;
1989}
1990
Masahiro Yamada8b185742018-05-09 18:50:40 +09001991static void read_symbols(const char *modname)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001992{
1993 const char *symname;
1994 char *version;
Sam Ravnborgb817f6f2006-06-09 21:53:55 +02001995 char *license;
Matthias Maennichcb9b55d2019-09-06 11:32:28 +01001996 char *namespace;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997 struct module *mod;
1998 struct elf_info info = { };
1999 Elf_Sym *sym;
2000
Sam Ravnborg85bd2fd2007-02-26 15:33:52 +01002001 if (!parse_elf(&info, modname))
2002 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002003
Masahiro Yamadaa82f7942020-06-01 14:57:29 +09002004 {
2005 char *tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002006
Masahiro Yamadaa82f7942020-06-01 14:57:29 +09002007 /* strip trailing .o */
2008 tmp = NOFAIL(strdup(modname));
2009 tmp[strlen(tmp) - 2] = '\0';
Sami Tolvanen1f975cd2020-03-06 13:52:03 -08002010 /* strip trailing .lto */
2011 if (strends(tmp, ".lto"))
2012 tmp[strlen(tmp) - 4] = '\0';
Masahiro Yamadaa82f7942020-06-01 14:57:29 +09002013 mod = new_module(tmp);
2014 free(tmp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002015 }
2016
Masahiro Yamada5a438af2020-06-01 14:57:26 +09002017 if (!mod->is_vmlinux) {
Masahiro Yamada4ddea2f2020-06-01 14:57:16 +09002018 license = get_modinfo(&info, "license");
2019 if (!license)
Masahiro Yamada1731b012020-12-01 19:34:16 +09002020 error("missing MODULE_LICENSE() in %s\n", modname);
Masahiro Yamada4ddea2f2020-06-01 14:57:16 +09002021 while (license) {
2022 if (license_is_gpl_compatible(license))
2023 mod->gpl_compatible = 1;
2024 else {
2025 mod->gpl_compatible = 0;
2026 break;
2027 }
2028 license = get_next_modinfo(&info, "license", license);
Sam Ravnborgb817f6f2006-06-09 21:53:55 +02002029 }
Sam Ravnborgb817f6f2006-06-09 21:53:55 +02002030
Masahiro Yamada4ddea2f2020-06-01 14:57:16 +09002031 namespace = get_modinfo(&info, "import_ns");
2032 while (namespace) {
2033 add_namespace(&mod->imported_namespaces, namespace);
2034 namespace = get_next_modinfo(&info, "import_ns",
2035 namespace);
2036 }
Matthias Maennichcb9b55d2019-09-06 11:32:28 +01002037 }
2038
Linus Torvalds1da177e2005-04-16 15:20:36 -07002039 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
Andi Kleen7d02b492014-02-08 09:01:12 +01002040 symname = remove_dot(info.strtab + sym->st_name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002041
Masahiro Yamada9bd2a092019-11-15 02:42:23 +09002042 handle_symbol(mod, &info, sym, symname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002043 handle_moddevtable(mod, &info, sym, symname);
2044 }
Denis Efremov15bfc232019-08-01 09:06:57 +03002045
Matthias Maennich69923202019-10-18 10:31:42 +01002046 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
2047 symname = remove_dot(info.strtab + sym->st_name);
2048
Masahiro Yamada17436942019-11-15 02:42:24 +09002049 /* Apply symbol namespaces from __kstrtabns_<symbol> entries. */
Matthias Maennich69923202019-10-18 10:31:42 +01002050 if (strstarts(symname, "__kstrtabns_"))
2051 sym_update_namespace(symname + strlen("__kstrtabns_"),
2052 namespace_from_kstrtabns(&info,
2053 sym));
Masahiro Yamada17436942019-11-15 02:42:24 +09002054
2055 if (strstarts(symname, "__crc_"))
2056 handle_modversion(mod, &info, sym,
2057 symname + strlen("__crc_"));
Matthias Maennich69923202019-10-18 10:31:42 +01002058 }
2059
Denis Efremov15bfc232019-08-01 09:06:57 +03002060 // check for static EXPORT_SYMBOL_* functions && global vars
2061 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
2062 unsigned char bind = ELF_ST_BIND(sym->st_info);
2063
2064 if (bind == STB_GLOBAL || bind == STB_WEAK) {
2065 struct symbol *s =
2066 find_symbol(remove_dot(info.strtab +
2067 sym->st_name));
2068
2069 if (s)
2070 s->is_static = 0;
2071 }
2072 }
2073
Masahiro Yamada467b82d2020-06-01 14:57:22 +09002074 check_sec_ref(mod, modname, &info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002075
Masahiro Yamada5a438af2020-06-01 14:57:26 +09002076 if (!mod->is_vmlinux) {
Masahiro Yamada4ddea2f2020-06-01 14:57:16 +09002077 version = get_modinfo(&info, "version");
2078 if (version || all_versions)
2079 get_src_version(modname, mod->srcversion,
2080 sizeof(mod->srcversion) - 1);
2081 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002082
2083 parse_elf_finish(&info);
2084
Rusty Russell8c8ef422009-03-31 13:05:34 -06002085 /* Our trick to get versioning for module struct etc. - it's
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086 * never passed as an argument to an exported function, so
2087 * the automatic versioning doesn't pick it up, but it's really
2088 * important anyhow */
2089 if (modversions)
Rusty Russell8c8ef422009-03-31 13:05:34 -06002090 mod->unres = alloc_symbol("module_layout", 0, mod->unres);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002091}
2092
Rusty Russell712f9b42013-04-04 17:37:38 +10302093static void read_symbols_from_files(const char *filename)
2094{
2095 FILE *in = stdin;
2096 char fname[PATH_MAX];
2097
2098 if (strcmp(filename, "-") != 0) {
2099 in = fopen(filename, "r");
2100 if (!in)
2101 fatal("Can't open filenames file %s: %m", filename);
2102 }
2103
2104 while (fgets(fname, PATH_MAX, in) != NULL) {
2105 if (strends(fname, "\n"))
2106 fname[strlen(fname)-1] = '\0';
2107 read_symbols(fname);
2108 }
2109
2110 if (in != stdin)
2111 fclose(in);
2112}
2113
Linus Torvalds1da177e2005-04-16 15:20:36 -07002114#define SZ 500
2115
2116/* We first write the generated file into memory using the
2117 * following helper, then compare to the file on disk and
2118 * only update the later if anything changed */
2119
Sam Ravnborg5c3ead82006-01-28 17:19:35 +01002120void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf,
2121 const char *fmt, ...)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002122{
2123 char tmp[SZ];
2124 int len;
2125 va_list ap;
Sam Ravnborg62070fa2006-03-03 16:46:04 +01002126
Linus Torvalds1da177e2005-04-16 15:20:36 -07002127 va_start(ap, fmt);
2128 len = vsnprintf(tmp, SZ, fmt, ap);
Sam Ravnborg7670f022006-03-16 23:04:08 -08002129 buf_write(buf, tmp, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002130 va_end(ap);
2131}
2132
Sam Ravnborg5c3ead82006-01-28 17:19:35 +01002133void buf_write(struct buffer *buf, const char *s, int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002134{
2135 if (buf->size - buf->pos < len) {
Sam Ravnborg7670f022006-03-16 23:04:08 -08002136 buf->size += len + SZ;
Randy Dunlap1f3aa902018-08-15 12:30:38 -07002137 buf->p = NOFAIL(realloc(buf->p, buf->size));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002138 }
2139 strncpy(buf->p + buf->pos, s, len);
2140 buf->pos += len;
2141}
2142
Sam Ravnborgc96fca22006-07-01 11:44:23 +02002143static void check_for_gpl_usage(enum export exp, const char *m, const char *s)
2144{
Sam Ravnborgc96fca22006-07-01 11:44:23 +02002145 switch (exp) {
2146 case export_gpl:
Masahiro Yamada2a30bb92020-12-01 19:34:17 +09002147 error("GPL-incompatible module %s.ko uses GPL-only symbol '%s'\n",
Masahiro Yamada1be5fa62020-06-01 14:57:25 +09002148 m, s);
Sam Ravnborgc96fca22006-07-01 11:44:23 +02002149 break;
2150 case export_unused_gpl:
Masahiro Yamada2a30bb92020-12-01 19:34:17 +09002151 error("GPL-incompatible module %s.ko uses GPL-only symbol marked UNUSED '%s'\n",
Masahiro Yamada1be5fa62020-06-01 14:57:25 +09002152 m, s);
Sam Ravnborgc96fca22006-07-01 11:44:23 +02002153 break;
2154 case export_gpl_future:
Masahiro Yamada1be5fa62020-06-01 14:57:25 +09002155 warn("GPL-incompatible module %s.ko uses future GPL-only symbol '%s'\n",
2156 m, s);
Sam Ravnborgc96fca22006-07-01 11:44:23 +02002157 break;
2158 case export_plain:
2159 case export_unused:
2160 case export_unknown:
2161 /* ignore */
2162 break;
2163 }
2164}
2165
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002166static void check_for_unused(enum export exp, const char *m, const char *s)
Sam Ravnborgc96fca22006-07-01 11:44:23 +02002167{
Sam Ravnborgc96fca22006-07-01 11:44:23 +02002168 switch (exp) {
2169 case export_unused:
2170 case export_unused_gpl:
Masahiro Yamada1be5fa62020-06-01 14:57:25 +09002171 warn("module %s.ko uses symbol '%s' marked UNUSED\n",
2172 m, s);
Sam Ravnborgc96fca22006-07-01 11:44:23 +02002173 break;
2174 default:
2175 /* ignore */
2176 break;
2177 }
2178}
2179
Masahiro Yamadaba0f6422020-12-01 19:34:15 +09002180static void check_exports(struct module *mod)
Sam Ravnborgb817f6f2006-06-09 21:53:55 +02002181{
2182 struct symbol *s, *exp;
2183
2184 for (s = mod->unres; s; s = s->next) {
Andrew Morton6449bd62006-06-09 20:45:06 -07002185 const char *basename;
Sam Ravnborgb817f6f2006-06-09 21:53:55 +02002186 exp = find_symbol(s->name);
Masahiro Yamada3b415282018-11-23 16:57:23 +09002187 if (!exp || exp->module == mod) {
Masahiro Yamadaba0f6422020-12-01 19:34:15 +09002188 if (have_vmlinux && !s->weak)
Jessica Yu93c95e52020-03-06 17:02:05 +01002189 modpost_log(warn_unresolved ? LOG_WARN : LOG_ERROR,
2190 "\"%s\" [%s.ko] undefined!\n",
2191 s->name, mod->name);
Sam Ravnborgb817f6f2006-06-09 21:53:55 +02002192 continue;
Masahiro Yamada3b415282018-11-23 16:57:23 +09002193 }
Andrew Morton6449bd62006-06-09 20:45:06 -07002194 basename = strrchr(mod->name, '/');
Sam Ravnborgb817f6f2006-06-09 21:53:55 +02002195 if (basename)
2196 basename++;
Sam Ravnborgc96fca22006-07-01 11:44:23 +02002197 else
2198 basename = mod->name;
Matthias Maennichcb9b55d2019-09-06 11:32:28 +01002199
Masahiro Yamadabbc55bd2019-10-29 21:38:07 +09002200 if (exp->namespace &&
2201 !module_imports_namespace(mod, exp->namespace)) {
Jessica Yu54b77842020-03-06 17:02:06 +01002202 modpost_log(allow_missing_ns_imports ? LOG_WARN : LOG_ERROR,
2203 "module %s uses symbol %s from namespace %s, but does not import it.\n",
2204 basename, exp->name, exp->namespace);
Masahiro Yamadabbc55bd2019-10-29 21:38:07 +09002205 add_namespace(&mod->missing_namespaces, exp->namespace);
Matthias Maennichcb9b55d2019-09-06 11:32:28 +01002206 }
2207
Sam Ravnborgc96fca22006-07-01 11:44:23 +02002208 if (!mod->gpl_compatible)
2209 check_for_gpl_usage(exp->export, basename, exp->name);
2210 check_for_unused(exp->export, basename, exp->name);
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002211 }
Sam Ravnborgb817f6f2006-06-09 21:53:55 +02002212}
2213
Masahiro Yamadaba0f6422020-12-01 19:34:15 +09002214static void check_modname_len(struct module *mod)
Wanlong Gao4fd3e4e2017-06-30 22:07:03 +08002215{
2216 const char *mod_name;
2217
2218 mod_name = strrchr(mod->name, '/');
2219 if (mod_name == NULL)
2220 mod_name = mod->name;
2221 else
2222 mod_name++;
Masahiro Yamadaba0f6422020-12-01 19:34:15 +09002223 if (strlen(mod_name) >= MODULE_NAME_LEN)
Masahiro Yamada979f7482020-12-01 19:34:14 +09002224 error("module name is too long [%s.ko]\n", mod->name);
Wanlong Gao4fd3e4e2017-06-30 22:07:03 +08002225}
2226
Sam Ravnborg5c3ead82006-01-28 17:19:35 +01002227/**
2228 * Header for the generated file
2229 **/
2230static void add_header(struct buffer *b, struct module *mod)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002231{
2232 buf_printf(b, "#include <linux/module.h>\n");
Vincenzo Frascinof58dd032020-03-20 14:53:41 +00002233 /*
2234 * Include build-salt.h after module.h in order to
2235 * inherit the definitions.
2236 */
Leon Romanovsky51161bf2020-04-19 18:55:06 +03002237 buf_printf(b, "#define INCLUDE_VERMAGIC\n");
Vincenzo Frascinof58dd032020-03-20 14:53:41 +00002238 buf_printf(b, "#include <linux/build-salt.h>\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002239 buf_printf(b, "#include <linux/vermagic.h>\n");
2240 buf_printf(b, "#include <linux/compiler.h>\n");
2241 buf_printf(b, "\n");
Laura Abbott9afb7192018-07-05 17:49:37 -07002242 buf_printf(b, "BUILD_SALT;\n");
2243 buf_printf(b, "\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002244 buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
Kees Cook3e2e8572017-04-21 15:35:27 -07002245 buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002246 buf_printf(b, "\n");
Andi Kleene0f244c2013-10-23 10:57:58 +10302247 buf_printf(b, "__visible struct module __this_module\n");
Joe Perches33def842020-10-21 19:36:07 -07002248 buf_printf(b, "__section(\".gnu.linkonce.this_module\") = {\n");
Greg Kroah-Hartman3c7ec942012-04-25 11:10:15 -07002249 buf_printf(b, "\t.name = KBUILD_MODNAME,\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002250 if (mod->has_init)
Greg Kroah-Hartman3c7ec942012-04-25 11:10:15 -07002251 buf_printf(b, "\t.init = init_module,\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002252 if (mod->has_cleanup)
2253 buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n"
Greg Kroah-Hartman3c7ec942012-04-25 11:10:15 -07002254 "\t.exit = cleanup_module,\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -07002255 "#endif\n");
Greg Kroah-Hartman3c7ec942012-04-25 11:10:15 -07002256 buf_printf(b, "\t.arch = MODULE_ARCH_INIT,\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002257 buf_printf(b, "};\n");
2258}
2259
Ben Hutchings2449b8b2011-10-24 15:12:28 +02002260static void add_intree_flag(struct buffer *b, int is_intree)
2261{
2262 if (is_intree)
2263 buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n");
2264}
2265
Will McVickerda2089a2020-11-19 13:46:37 -08002266/**
2267 * add_scmversion() - Adds the MODULE_INFO macro for the scmversion.
2268 * @b: Buffer to append to.
2269 *
2270 * This function fills in the module attribute `scmversion` for the kernel
2271 * module. This is useful for determining a given module's SCM version on
2272 * device via /sys/modules/<module>/scmversion and/or using the modinfo tool.
2273 */
2274static void add_scmversion(struct buffer *b)
2275{
2276 if (module_scmversion[0] != '\0')
2277 buf_printf(b, "\nMODULE_INFO(scmversion, \"%s\");\n", module_scmversion);
2278}
2279
Andi Kleencaf75012018-01-25 15:50:28 -08002280/* Cannot check for assembler */
2281static void add_retpoline(struct buffer *b)
2282{
WANG Chaoe4f35892018-12-11 00:37:25 +08002283 buf_printf(b, "\n#ifdef CONFIG_RETPOLINE\n");
Andi Kleencaf75012018-01-25 15:50:28 -08002284 buf_printf(b, "MODULE_INFO(retpoline, \"Y\");\n");
2285 buf_printf(b, "#endif\n");
2286}
2287
Trevor Keith5c725132009-09-22 16:43:38 -07002288static void add_staging_flag(struct buffer *b, const char *name)
Greg Kroah-Hartmana9860bf2008-09-24 14:46:44 -07002289{
Masahiro Yamadad62c4762018-05-09 18:50:38 +09002290 if (strstarts(name, "drivers/staging"))
Greg Kroah-Hartmana9860bf2008-09-24 14:46:44 -07002291 buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
2292}
2293
Sam Ravnborg5c3ead82006-01-28 17:19:35 +01002294/**
2295 * Record CRCs for unresolved symbols
2296 **/
Masahiro Yamadaba0f6422020-12-01 19:34:15 +09002297static void add_versions(struct buffer *b, struct module *mod)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002298{
2299 struct symbol *s, *exp;
2300
2301 for (s = mod->unres; s; s = s->next) {
2302 exp = find_symbol(s->name);
Masahiro Yamada3b415282018-11-23 16:57:23 +09002303 if (!exp || exp->module == mod)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002304 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002305 s->module = exp->module;
2306 s->crc_valid = exp->crc_valid;
2307 s->crc = exp->crc;
2308 }
2309
2310 if (!modversions)
Masahiro Yamadaba0f6422020-12-01 19:34:15 +09002311 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002312
2313 buf_printf(b, "\n");
2314 buf_printf(b, "static const struct modversion_info ____versions[]\n");
Joe Perches33def842020-10-21 19:36:07 -07002315 buf_printf(b, "__used __section(\"__versions\") = {\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002316
2317 for (s = mod->unres; s; s = s->next) {
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002318 if (!s->module)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002319 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002320 if (!s->crc_valid) {
Sam Ravnborgcb805142006-01-28 16:57:26 +01002321 warn("\"%s\" [%s.ko] has no CRC!\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002322 s->name, mod->name);
2323 continue;
2324 }
Takashi Iwai5cfb2032015-08-08 15:16:20 +09302325 if (strlen(s->name) >= MODULE_NAME_LEN) {
Masahiro Yamada979f7482020-12-01 19:34:14 +09002326 error("too long symbol \"%s\" [%s.ko]\n",
2327 s->name, mod->name);
Takashi Iwai5cfb2032015-08-08 15:16:20 +09302328 break;
2329 }
Masahiro Yamadab2c5cdc2018-05-09 16:23:45 +09002330 buf_printf(b, "\t{ %#8x, \"%s\" },\n",
James Hogana4b6a772013-03-18 19:38:56 +10302331 s->crc, s->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002332 }
2333
2334 buf_printf(b, "};\n");
2335}
2336
Masahiro Yamadad2665ca2018-11-23 16:57:21 +09002337static void add_depends(struct buffer *b, struct module *mod)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002338{
2339 struct symbol *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002340 int first = 1;
2341
Masahiro Yamadad2665ca2018-11-23 16:57:21 +09002342 /* Clear ->seen flag of modules that own symbols needed by this. */
2343 for (s = mod->unres; s; s = s->next)
2344 if (s->module)
Masahiro Yamada5a438af2020-06-01 14:57:26 +09002345 s->module->seen = s->module->is_vmlinux;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002346
2347 buf_printf(b, "\n");
Masahiro Yamada6df7e1e2019-09-09 20:34:22 +09002348 buf_printf(b, "MODULE_INFO(depends, \"");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002349 for (s = mod->unres; s; s = s->next) {
Sam Ravnborga61b2df2007-02-26 19:46:52 +01002350 const char *p;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002351 if (!s->module)
2352 continue;
2353
2354 if (s->module->seen)
2355 continue;
2356
2357 s->module->seen = 1;
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002358 p = strrchr(s->module->name, '/');
2359 if (p)
Sam Ravnborga61b2df2007-02-26 19:46:52 +01002360 p++;
2361 else
2362 p = s->module->name;
2363 buf_printf(b, "%s%s", first ? "" : ",", p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002364 first = 0;
2365 }
Masahiro Yamada6df7e1e2019-09-09 20:34:22 +09002366 buf_printf(b, "\");\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002367}
2368
Sam Ravnborg5c3ead82006-01-28 17:19:35 +01002369static void add_srcversion(struct buffer *b, struct module *mod)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002370{
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
Masahiro Yamada436b2ac2020-06-01 14:57:12 +09002378static 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
Sam Ravnborg5c3ead82006-01-28 17:19:35 +01002397static void write_if_changed(struct buffer *b, const char *fname)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002398{
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:
Masahiro Yamada436b2ac2020-06-01 14:57:12 +09002429 write_buf(b, fname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002430}
2431
Ram Paibd5cbce2006-06-08 22:12:53 -07002432/* parse Module.symvers file. line format:
Jessica Yu51900442020-03-11 18:01:20 +01002433 * 0x12345678<tab>symbol<tab>module<tab>export<tab>namespace
Ram Paibd5cbce2006-06-08 22:12:53 -07002434 **/
Masahiro Yamada52c34162020-06-01 14:57:05 +09002435static void read_dump(const char *fname)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002436{
Masahiro Yamada70f30cf2020-06-01 14:57:20 +09002437 char *buf, *pos, *line;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002438
Masahiro Yamada70f30cf2020-06-01 14:57:20 +09002439 buf = read_text_file(fname);
2440 if (!buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002441 /* No symbol versions, silently ignore */
2442 return;
2443
Masahiro Yamada70f30cf2020-06-01 14:57:20 +09002444 pos = buf;
2445
2446 while ((line = get_line(&pos))) {
Jessica Yu51900442020-03-11 18:01:20 +01002447 char *symname, *namespace, *modname, *d, *export;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002448 unsigned int crc;
2449 struct module *mod;
Sam Ravnborg040fcc82006-01-28 22:15:55 +01002450 struct symbol *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002451
2452 if (!(symname = strchr(line, '\t')))
2453 goto fail;
2454 *symname++ = '\0';
Jessica Yu51900442020-03-11 18:01:20 +01002455 if (!(modname = strchr(symname, '\t')))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002456 goto fail;
2457 *modname++ = '\0';
Jessica Yu51900442020-03-11 18:01:20 +01002458 if (!(export = strchr(modname, '\t')))
2459 goto fail;
2460 *export++ = '\0';
2461 if (!(namespace = strchr(export, '\t')))
2462 goto fail;
2463 *namespace++ = '\0';
2464
Linus Torvalds1da177e2005-04-16 15:20:36 -07002465 crc = strtoul(line, &d, 16);
2466 if (*symname == '\0' || *modname == '\0' || *d != '\0')
2467 goto fail;
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002468 mod = find_module(modname);
2469 if (!mod) {
Jan Beulich0fa3a882009-03-12 12:28:30 +00002470 mod = new_module(modname);
Masahiro Yamada52c34162020-06-01 14:57:05 +09002471 mod->from_dump = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002472 }
Matthias Maennich9ae5bd12019-10-18 10:31:41 +01002473 s = sym_add_exported(symname, mod, export_no(export));
Denis Efremov15bfc232019-08-01 09:06:57 +03002474 s->is_static = 0;
Masahiro Yamada17436942019-11-15 02:42:24 +09002475 sym_set_crc(symname, crc);
Matthias Maennich9ae5bd12019-10-18 10:31:41 +01002476 sym_update_namespace(symname, namespace);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002477 }
Masahiro Yamada70f30cf2020-06-01 14:57:20 +09002478 free(buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002479 return;
2480fail:
Masahiro Yamada70f30cf2020-06-01 14:57:20 +09002481 free(buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002482 fatal("parse error in symbol dump file\n");
2483}
2484
Sam Ravnborg5c3ead82006-01-28 17:19:35 +01002485static void write_dump(const char *fname)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002486{
2487 struct buffer buf = { };
2488 struct symbol *symbol;
Matthias Maennichcb9b55d2019-09-06 11:32:28 +01002489 const char *namespace;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002490 int n;
2491
2492 for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
2493 symbol = symbolhash[n];
2494 while (symbol) {
Masahiro Yamadad0736af2021-03-26 03:54:09 +09002495 if (!symbol->module->from_dump) {
Matthias Maennichcb9b55d2019-09-06 11:32:28 +01002496 namespace = symbol->namespace;
2497 buf_printf(&buf, "0x%08x\t%s\t%s\t%s\t%s\n",
2498 symbol->crc, symbol->name,
Matthias Maennichcb9b55d2019-09-06 11:32:28 +01002499 symbol->module->name,
Jessica Yu51900442020-03-11 18:01:20 +01002500 export_str(symbol->export),
2501 namespace ? namespace : "");
Matthias Maennichcb9b55d2019-09-06 11:32:28 +01002502 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002503 symbol = symbol->next;
2504 }
2505 }
Masahiro Yamada436b2ac2020-06-01 14:57:12 +09002506 write_buf(&buf, fname);
Heinrich Schuchardtc7d47f22016-08-02 21:43:01 +02002507 free(buf.p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002508}
2509
Masahiro Yamadabbc55bd2019-10-29 21:38:07 +09002510static void write_namespace_deps_files(const char *fname)
Matthias Maennich1d082772019-09-06 11:32:31 +01002511{
2512 struct module *mod;
2513 struct namespace_list *ns;
2514 struct buffer ns_deps_buf = {};
2515
2516 for (mod = modules; mod; mod = mod->next) {
Matthias Maennich1d082772019-09-06 11:32:31 +01002517
Masahiro Yamada0b19d542020-06-01 14:57:27 +09002518 if (mod->from_dump || !mod->missing_namespaces)
Matthias Maennich1d082772019-09-06 11:32:31 +01002519 continue;
2520
Masahiro Yamadabbc55bd2019-10-29 21:38:07 +09002521 buf_printf(&ns_deps_buf, "%s.ko:", mod->name);
Matthias Maennich1d082772019-09-06 11:32:31 +01002522
Masahiro Yamadabbc55bd2019-10-29 21:38:07 +09002523 for (ns = mod->missing_namespaces; ns; ns = ns->next)
2524 buf_printf(&ns_deps_buf, " %s", ns->namespace);
Matthias Maennich1d082772019-09-06 11:32:31 +01002525
Masahiro Yamadabbc55bd2019-10-29 21:38:07 +09002526 buf_printf(&ns_deps_buf, "\n");
Matthias Maennich1d082772019-09-06 11:32:31 +01002527 }
Masahiro Yamada0241ea82019-11-07 00:19:59 +09002528
Masahiro Yamadabbc55bd2019-10-29 21:38:07 +09002529 write_if_changed(&ns_deps_buf, fname);
Masahiro Yamada0241ea82019-11-07 00:19:59 +09002530 free(ns_deps_buf.p);
Matthias Maennich1d082772019-09-06 11:32:31 +01002531}
2532
Masahiro Yamada79247992020-06-01 14:57:07 +09002533struct dump_list {
2534 struct dump_list *next;
Richard Hacker2d04b5a2008-02-28 09:40:52 +01002535 const char *file;
2536};
2537
Sam Ravnborg5c3ead82006-01-28 17:19:35 +01002538int main(int argc, char **argv)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002539{
2540 struct module *mod;
2541 struct buffer buf = { };
Masahiro Yamadabbc55bd2019-10-29 21:38:07 +09002542 char *missing_namespace_deps = NULL;
Rusty Russell712f9b42013-04-04 17:37:38 +10302543 char *dump_write = NULL, *files_source = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002544 int opt;
Denis Efremov15bfc232019-08-01 09:06:57 +03002545 int n;
Masahiro Yamada79247992020-06-01 14:57:07 +09002546 struct dump_list *dump_read_start = NULL;
2547 struct dump_list **dump_read_iter = &dump_read_start;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002548
Will McVickerda2089a2020-11-19 13:46:37 -08002549 while ((opt = getopt(argc, argv, "ei:mnT:o:awENd:v:")) != -1) {
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002550 switch (opt) {
Richard Hacker2d04b5a2008-02-28 09:40:52 +01002551 case 'e':
2552 external_module = 1;
Masahiro Yamadae3fb4df2020-06-01 14:57:08 +09002553 break;
2554 case 'i':
Masahiro Yamada79247992020-06-01 14:57:07 +09002555 *dump_read_iter =
2556 NOFAIL(calloc(1, sizeof(**dump_read_iter)));
2557 (*dump_read_iter)->file = optarg;
2558 dump_read_iter = &(*dump_read_iter)->next;
Richard Hacker2d04b5a2008-02-28 09:40:52 +01002559 break;
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002560 case 'm':
2561 modversions = 1;
2562 break;
Guenter Roeckeed380f2013-09-23 15:23:54 +09302563 case 'n':
2564 ignore_missing_files = 1;
2565 break;
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002566 case 'o':
2567 dump_write = optarg;
2568 break;
2569 case 'a':
2570 all_versions = 1;
2571 break;
Rusty Russell712f9b42013-04-04 17:37:38 +10302572 case 'T':
2573 files_source = optarg;
2574 break;
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002575 case 'w':
2576 warn_unresolved = 1;
2577 break;
Nicolas Boichat47490ec2015-10-06 09:44:42 +10302578 case 'E':
Masahiro Yamada1e582602020-12-01 19:34:18 +09002579 sec_mismatch_warn_only = false;
Nicolas Boichat47490ec2015-10-06 09:44:42 +10302580 break;
Jessica Yu54b77842020-03-06 17:02:06 +01002581 case 'N':
2582 allow_missing_ns_imports = 1;
2583 break;
Matthias Maennich1d082772019-09-06 11:32:31 +01002584 case 'd':
Masahiro Yamadabbc55bd2019-10-29 21:38:07 +09002585 missing_namespace_deps = optarg;
Matthias Maennich1d082772019-09-06 11:32:31 +01002586 break;
Will McVickerda2089a2020-11-19 13:46:37 -08002587 case 'v':
2588 strncpy(module_scmversion, optarg, sizeof(module_scmversion) - 1);
2589 break;
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002590 default:
2591 exit(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002592 }
2593 }
2594
Masahiro Yamada79247992020-06-01 14:57:07 +09002595 while (dump_read_start) {
2596 struct dump_list *tmp;
Masahiro Yamada2beee862020-06-01 14:57:04 +09002597
Masahiro Yamada79247992020-06-01 14:57:07 +09002598 read_dump(dump_read_start->file);
2599 tmp = dump_read_start->next;
2600 free(dump_read_start);
2601 dump_read_start = tmp;
Richard Hacker2d04b5a2008-02-28 09:40:52 +01002602 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002603
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002604 while (optind < argc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002605 read_symbols(argv[optind++]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002606
Rusty Russell712f9b42013-04-04 17:37:38 +10302607 if (files_source)
2608 read_symbols_from_files(files_source);
2609
Masahiro Yamada7e8a3232020-06-01 14:57:13 +09002610 /*
2611 * When there's no vmlinux, don't print warnings about
2612 * unresolved symbols (since there'll be too many ;)
2613 */
2614 if (!have_vmlinux)
2615 warn("Symbol info of vmlinux is missing. Unresolved symbol check will be entirely skipped.\n");
2616
Sam Ravnborgb817f6f2006-06-09 21:53:55 +02002617 for (mod = modules; mod; mod = mod->next) {
Mathias Kraused93e1712014-08-27 20:28:56 +09302618 char fname[PATH_MAX];
Andi Kleen666ab412007-11-22 03:43:10 +01002619
Masahiro Yamada0b19d542020-06-01 14:57:27 +09002620 if (mod->is_vmlinux || mod->from_dump)
Sam Ravnborgb817f6f2006-06-09 21:53:55 +02002621 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002622
2623 buf.pos = 0;
2624
Masahiro Yamadaba0f6422020-12-01 19:34:15 +09002625 check_modname_len(mod);
2626 check_exports(mod);
Matthias Maennich1d082772019-09-06 11:32:31 +01002627
Linus Torvalds1da177e2005-04-16 15:20:36 -07002628 add_header(&buf, mod);
Ben Hutchings2449b8b2011-10-24 15:12:28 +02002629 add_intree_flag(&buf, !external_module);
Andi Kleencaf75012018-01-25 15:50:28 -08002630 add_retpoline(&buf);
Greg Kroah-Hartmana9860bf2008-09-24 14:46:44 -07002631 add_staging_flag(&buf, mod->name);
Masahiro Yamadaba0f6422020-12-01 19:34:15 +09002632 add_versions(&buf, mod);
Masahiro Yamadad2665ca2018-11-23 16:57:21 +09002633 add_depends(&buf, mod);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002634 add_moddevtable(&buf, mod);
2635 add_srcversion(&buf, mod);
Will McVickerda2089a2020-11-19 13:46:37 -08002636 add_scmversion(&buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002637
2638 sprintf(fname, "%s.mod.c", mod->name);
2639 write_if_changed(&buf, fname);
2640 }
Matthias Maennich1d082772019-09-06 11:32:31 +01002641
Masahiro Yamadabbc55bd2019-10-29 21:38:07 +09002642 if (missing_namespace_deps)
2643 write_namespace_deps_files(missing_namespace_deps);
Matthias Maennich1d082772019-09-06 11:32:31 +01002644
Linus Torvalds1da177e2005-04-16 15:20:36 -07002645 if (dump_write)
2646 write_dump(dump_write);
Masahiro Yamada1e582602020-12-01 19:34:18 +09002647 if (sec_mismatch_count && !sec_mismatch_warn_only)
2648 error("Section mismatches detected.\n"
Masahiro Yamada46c7dd52019-02-01 13:50:45 +09002649 "Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n");
Denis Efremov15bfc232019-08-01 09:06:57 +03002650 for (n = 0; n < SYMBOL_HASH_SIZE; n++) {
Masahiro Yamada47346e92019-09-24 21:07:40 +09002651 struct symbol *s;
Denis Efremov15bfc232019-08-01 09:06:57 +03002652
Masahiro Yamada47346e92019-09-24 21:07:40 +09002653 for (s = symbolhash[n]; s; s = s->next) {
Denis Efremov15bfc232019-08-01 09:06:57 +03002654 if (s->is_static)
Quentin Perretef84e872020-12-01 16:52:22 +00002655 error("\"%s\" [%s] is a static %s\n",
2656 s->name, s->module->name,
2657 export_str(s->export));
Denis Efremov15bfc232019-08-01 09:06:57 +03002658 }
2659 }
2660
Heinrich Schuchardtc7d47f22016-08-02 21:43:01 +02002661 free(buf.p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662
Masahiro Yamadaba0f6422020-12-01 19:34:15 +09002663 return error_occurred ? 1 : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002664}