blob: cd885573daafbf8f1c5c0b9b36906343453509be [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
15#include <stdio.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070016#include <ctype.h>
Andrew Morton5003bab2010-08-11 00:42:26 -070017#include <string.h>
Rusty Russell712f9b42013-04-04 17:37:38 +103018#include <limits.h>
Rusty Russelld4ef1c32013-04-04 17:37:32 +103019#include <stdbool.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;
Sam Ravnborg8d8d8282007-07-20 22:36:56 +020032/* Warn about section mismatch in vmlinux if set to 1 */
33static int vmlinux_section_warnings = 1;
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;
Nicolas Boichat47490ec2015-10-06 09:44:42 +103038static int sec_mismatch_fatal = 0;
Guenter Roeckeed380f2013-09-23 15:23:54 +093039/* ignore missing files */
40static int ignore_missing_files;
Sam Ravnborg588ccd72008-01-24 21:12:37 +010041
Sam Ravnborgc96fca22006-07-01 11:44:23 +020042enum export {
43 export_plain, export_unused, export_gpl,
44 export_unused_gpl, export_gpl_future, export_unknown
45};
Linus Torvalds1da177e2005-04-16 15:20:36 -070046
Wanlong Gao4fd3e4e2017-06-30 22:07:03 +080047/* In kernel, this size is defined in linux/module.h;
48 * here we use Elf_Addr instead of long for covering cross-compile
49 */
50
51#define MODULE_NAME_LEN (64 - sizeof(Elf_Addr))
52
Andi Kleen6d9a89e2007-11-22 03:43:08 +010053#define PRINTF __attribute__ ((format (printf, 1, 2)))
54
55PRINTF void fatal(const char *fmt, ...)
Linus Torvalds1da177e2005-04-16 15:20:36 -070056{
57 va_list arglist;
58
59 fprintf(stderr, "FATAL: ");
60
61 va_start(arglist, fmt);
62 vfprintf(stderr, fmt, arglist);
63 va_end(arglist);
64
65 exit(1);
66}
67
Andi Kleen6d9a89e2007-11-22 03:43:08 +010068PRINTF void warn(const char *fmt, ...)
Linus Torvalds1da177e2005-04-16 15:20:36 -070069{
70 va_list arglist;
71
72 fprintf(stderr, "WARNING: ");
73
74 va_start(arglist, fmt);
75 vfprintf(stderr, fmt, arglist);
76 va_end(arglist);
77}
78
Andi Kleen6d9a89e2007-11-22 03:43:08 +010079PRINTF void merror(const char *fmt, ...)
Matthew Wilcox2a116652006-10-07 05:35:32 -060080{
81 va_list arglist;
82
83 fprintf(stderr, "ERROR: ");
84
85 va_start(arglist, fmt);
86 vfprintf(stderr, fmt, arglist);
87 va_end(arglist);
88}
89
Rusty Russelld4ef1c32013-04-04 17:37:32 +103090static inline bool strends(const char *str, const char *postfix)
91{
92 if (strlen(str) < strlen(postfix))
93 return false;
94
95 return strcmp(str + strlen(str) - strlen(postfix), postfix) == 0;
96}
97
Sam Ravnborg040fcc82006-01-28 22:15:55 +010098static int is_vmlinux(const char *modname)
99{
100 const char *myname;
101
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100102 myname = strrchr(modname, '/');
103 if (myname)
Sam Ravnborg040fcc82006-01-28 22:15:55 +0100104 myname++;
105 else
106 myname = modname;
107
Sam Ravnborg741f98f2007-07-17 10:54:06 +0200108 return (strcmp(myname, "vmlinux") == 0) ||
109 (strcmp(myname, "vmlinux.o") == 0);
Sam Ravnborg040fcc82006-01-28 22:15:55 +0100110}
111
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112void *do_nofail(void *ptr, const char *expr)
113{
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100114 if (!ptr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115 fatal("modpost: Memory allocation failure: %s.\n", expr);
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100116
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117 return ptr;
118}
119
120/* A list of all modules we processed */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121static struct module *modules;
122
Masahiro Yamada8b185742018-05-09 18:50:40 +0900123static struct module *find_module(const char *modname)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124{
125 struct module *mod;
126
127 for (mod = modules; mod; mod = mod->next)
128 if (strcmp(mod->name, modname) == 0)
129 break;
130 return mod;
131}
132
Rusty Russelld4ef1c32013-04-04 17:37:32 +1030133static struct module *new_module(const char *modname)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134{
135 struct module *mod;
Rusty Russelld4ef1c32013-04-04 17:37:32 +1030136 char *p;
Sam Ravnborg62070fa2006-03-03 16:46:04 +0100137
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138 mod = NOFAIL(malloc(sizeof(*mod)));
139 memset(mod, 0, sizeof(*mod));
140 p = NOFAIL(strdup(modname));
141
142 /* strip trailing .o */
Rusty Russelld4ef1c32013-04-04 17:37:32 +1030143 if (strends(p, ".o")) {
144 p[strlen(p) - 2] = '\0';
145 mod->is_dot_o = 1;
146 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147
148 /* add to list */
149 mod->name = p;
Sam Ravnborgb817f6f2006-06-09 21:53:55 +0200150 mod->gpl_compatible = -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151 mod->next = modules;
152 modules = mod;
153
154 return mod;
155}
156
157/* A hash of all exported symbols,
158 * struct symbol is also used for lists of unresolved symbols */
159
160#define SYMBOL_HASH_SIZE 1024
161
162struct symbol {
163 struct symbol *next;
164 struct module *module;
165 unsigned int crc;
166 int crc_valid;
Masahiro Yamada389eb3f2019-10-03 16:58:22 +0900167 char *namespace;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168 unsigned int weak:1;
Sam Ravnborg040fcc82006-01-28 22:15:55 +0100169 unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */
170 unsigned int kernel:1; /* 1 if symbol is from kernel
171 * (only for external modules) **/
Rusty Russellb6568b12013-11-07 12:09:13 +1030172 unsigned int preloaded:1; /* 1 if symbol from Module.symvers, or crc */
Denis Efremov15bfc232019-08-01 09:06:57 +0300173 unsigned int is_static:1; /* 1 if symbol is not global */
Ram Paibd5cbce2006-06-08 22:12:53 -0700174 enum export export; /* Type of export */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175 char name[0];
176};
177
178static struct symbol *symbolhash[SYMBOL_HASH_SIZE];
179
180/* This is based on the hash agorithm from gdbm, via tdb */
181static inline unsigned int tdb_hash(const char *name)
182{
183 unsigned value; /* Used to compute the hash value. */
184 unsigned i; /* Used to cycle through random values. */
185
186 /* Set the initial value from the key size. */
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100187 for (value = 0x238F13AF * strlen(name), i = 0; name[i]; i++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188 value = (value + (((unsigned char *)name)[i] << (i*5 % 24)));
189
190 return (1103515243 * value + 12345);
191}
192
Sam Ravnborg5c3ead82006-01-28 17:19:35 +0100193/**
194 * Allocate a new symbols for use in the hash of exported symbols or
195 * the list of unresolved symbols per module
196 **/
197static struct symbol *alloc_symbol(const char *name, unsigned int weak,
198 struct symbol *next)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199{
200 struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1));
201
202 memset(s, 0, sizeof(*s));
203 strcpy(s->name, name);
204 s->weak = weak;
205 s->next = next;
Denis Efremov15bfc232019-08-01 09:06:57 +0300206 s->is_static = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700207 return s;
208}
209
210/* For the hash of exported symbols */
Ram Paibd5cbce2006-06-08 22:12:53 -0700211static struct symbol *new_symbol(const char *name, struct module *module,
212 enum export export)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213{
214 unsigned int hash;
215 struct symbol *new;
216
217 hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
218 new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]);
219 new->module = module;
Ram Paibd5cbce2006-06-08 22:12:53 -0700220 new->export = export;
Sam Ravnborg040fcc82006-01-28 22:15:55 +0100221 return new;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222}
223
Sam Ravnborg5c3ead82006-01-28 17:19:35 +0100224static struct symbol *find_symbol(const char *name)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225{
226 struct symbol *s;
227
228 /* For our purposes, .foo matches foo. PPC64 needs this. */
229 if (name[0] == '.')
230 name++;
231
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100232 for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s = s->next) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700233 if (strcmp(s->name, name) == 0)
234 return s;
235 }
236 return NULL;
237}
238
Matthias Maennichcb9b55d2019-09-06 11:32:28 +0100239static bool contains_namespace(struct namespace_list *list,
240 const char *namespace)
241{
Masahiro Yamada76b54cf2019-10-29 21:38:09 +0900242 for (; list; list = list->next)
243 if (!strcmp(list->namespace, namespace))
Matthias Maennichcb9b55d2019-09-06 11:32:28 +0100244 return true;
245
246 return false;
247}
248
249static void add_namespace(struct namespace_list **list, const char *namespace)
250{
251 struct namespace_list *ns_entry;
252
253 if (!contains_namespace(*list, namespace)) {
254 ns_entry = NOFAIL(malloc(sizeof(struct namespace_list) +
255 strlen(namespace) + 1));
256 strcpy(ns_entry->namespace, namespace);
257 ns_entry->next = *list;
258 *list = ns_entry;
259 }
260}
261
262static bool module_imports_namespace(struct module *module,
263 const char *namespace)
264{
265 return contains_namespace(module->imported_namespaces, namespace);
266}
267
Mathias Krause7a3ee752014-08-27 20:28:53 +0930268static const struct {
Ram Paibd5cbce2006-06-08 22:12:53 -0700269 const char *str;
270 enum export export;
271} export_list[] = {
272 { .str = "EXPORT_SYMBOL", .export = export_plain },
Sam Ravnborgc96fca22006-07-01 11:44:23 +0200273 { .str = "EXPORT_UNUSED_SYMBOL", .export = export_unused },
Ram Paibd5cbce2006-06-08 22:12:53 -0700274 { .str = "EXPORT_SYMBOL_GPL", .export = export_gpl },
Sam Ravnborgc96fca22006-07-01 11:44:23 +0200275 { .str = "EXPORT_UNUSED_SYMBOL_GPL", .export = export_unused_gpl },
Ram Paibd5cbce2006-06-08 22:12:53 -0700276 { .str = "EXPORT_SYMBOL_GPL_FUTURE", .export = export_gpl_future },
277 { .str = "(unknown)", .export = export_unknown },
278};
279
280
281static const char *export_str(enum export ex)
282{
283 return export_list[ex].str;
284}
285
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100286static enum export export_no(const char *s)
Ram Paibd5cbce2006-06-08 22:12:53 -0700287{
288 int i;
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100289
Sam Ravnborg534b89a2006-07-01 10:10:19 +0200290 if (!s)
291 return export_unknown;
Ram Paibd5cbce2006-06-08 22:12:53 -0700292 for (i = 0; export_list[i].export != export_unknown; i++) {
293 if (strcmp(export_list[i].str, s) == 0)
294 return export_list[i].export;
295 }
296 return export_unknown;
297}
298
Masahiro Yamada6124c042017-09-06 16:19:05 -0700299static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr)
300{
301 return (void *)elf->hdr +
302 elf->sechdrs[elf->secindex_strings].sh_offset +
303 sechdr->sh_name;
304}
305
306static const char *sec_name(struct elf_info *elf, int secindex)
307{
308 return sech_name(elf, &elf->sechdrs[secindex]);
309}
Alessio Igor Bogani62a26352011-07-14 08:51:16 +0200310
Masahiro Yamadaafa04592019-11-15 02:42:21 +0900311static void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym)
312{
313 Elf_Shdr *sechdr = &info->sechdrs[sym->st_shndx];
314 unsigned long offset;
315
316 offset = sym->st_value;
317 if (info->hdr->e_type != ET_REL)
318 offset -= sechdr->sh_addr;
319
320 return (void *)info->hdr + sechdr->sh_offset + offset;
321}
322
Alessio Igor Bogani62a26352011-07-14 08:51:16 +0200323#define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0)
324
325static enum export export_from_secname(struct elf_info *elf, unsigned int sec)
326{
327 const char *secname = sec_name(elf, sec);
328
329 if (strstarts(secname, "___ksymtab+"))
330 return export_plain;
331 else if (strstarts(secname, "___ksymtab_unused+"))
332 return export_unused;
333 else if (strstarts(secname, "___ksymtab_gpl+"))
334 return export_gpl;
335 else if (strstarts(secname, "___ksymtab_unused_gpl+"))
336 return export_unused_gpl;
337 else if (strstarts(secname, "___ksymtab_gpl_future+"))
338 return export_gpl_future;
339 else
340 return export_unknown;
341}
342
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200343static enum export export_from_sec(struct elf_info *elf, unsigned int sec)
Ram Paibd5cbce2006-06-08 22:12:53 -0700344{
345 if (sec == elf->export_sec)
346 return export_plain;
Sam Ravnborgc96fca22006-07-01 11:44:23 +0200347 else if (sec == elf->export_unused_sec)
348 return export_unused;
Ram Paibd5cbce2006-06-08 22:12:53 -0700349 else if (sec == elf->export_gpl_sec)
350 return export_gpl;
Sam Ravnborgc96fca22006-07-01 11:44:23 +0200351 else if (sec == elf->export_unused_gpl_sec)
352 return export_unused_gpl;
Ram Paibd5cbce2006-06-08 22:12:53 -0700353 else if (sec == elf->export_gpl_future_sec)
354 return export_gpl_future;
355 else
356 return export_unknown;
357}
358
Matthias Maennich69923202019-10-18 10:31:42 +0100359static const char *namespace_from_kstrtabns(struct elf_info *info,
360 Elf_Sym *kstrtabns)
Matthias Maennichcb9b55d2019-09-06 11:32:28 +0100361{
Matthias Maennich69923202019-10-18 10:31:42 +0100362 char *value = info->ksymtab_strings + kstrtabns->st_value;
363 return value[0] ? value : NULL;
Matthias Maennichcb9b55d2019-09-06 11:32:28 +0100364}
365
Matthias Maennicha2b11182019-10-18 10:31:40 +0100366static void sym_update_namespace(const char *symname, const char *namespace)
367{
368 struct symbol *s = find_symbol(symname);
369
370 /*
371 * That symbol should have been created earlier and thus this is
372 * actually an assertion.
373 */
374 if (!s) {
375 merror("Could not update namespace(%s) for symbol %s\n",
376 namespace, symname);
377 return;
378 }
379
380 free(s->namespace);
381 s->namespace =
382 namespace && namespace[0] ? NOFAIL(strdup(namespace)) : NULL;
383}
384
Sam Ravnborg5c3ead82006-01-28 17:19:35 +0100385/**
386 * Add an exported symbol - it may have already been added without a
387 * CRC, in this case just update the CRC
388 **/
Matthias Maennich9ae5bd12019-10-18 10:31:41 +0100389static struct symbol *sym_add_exported(const char *name, struct module *mod,
390 enum export export)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391{
392 struct symbol *s = find_symbol(name);
393
394 if (!s) {
Ram Paibd5cbce2006-06-08 22:12:53 -0700395 s = new_symbol(name, mod, export);
Sam Ravnborg8e70c452006-01-28 22:22:33 +0100396 } else {
397 if (!s->preloaded) {
Matthias Maennichcb9b55d2019-09-06 11:32:28 +0100398 warn("%s: '%s' exported twice. Previous export was in %s%s\n",
399 mod->name, name, s->module->name,
400 is_vmlinux(s->module->name) ? "" : ".ko");
Trent Piepho4b219602007-10-11 16:40:10 -0700401 } else {
Paul Bollebaec30e2014-04-16 18:05:35 +0200402 /* In case Module.symvers was out of date */
Trent Piepho4b219602007-10-11 16:40:10 -0700403 s->module = mod;
Sam Ravnborg8e70c452006-01-28 22:22:33 +0100404 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405 }
Sam Ravnborg8e70c452006-01-28 22:22:33 +0100406 s->preloaded = 0;
Sam Ravnborg040fcc82006-01-28 22:15:55 +0100407 s->vmlinux = is_vmlinux(mod->name);
408 s->kernel = 0;
Ram Paibd5cbce2006-06-08 22:12:53 -0700409 s->export = export;
Sam Ravnborg040fcc82006-01-28 22:15:55 +0100410 return s;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411}
412
Sam Ravnborg040fcc82006-01-28 22:15:55 +0100413static void sym_update_crc(const char *name, struct module *mod,
Ram Paibd5cbce2006-06-08 22:12:53 -0700414 unsigned int crc, enum export export)
Sam Ravnborg040fcc82006-01-28 22:15:55 +0100415{
416 struct symbol *s = find_symbol(name);
417
Rusty Russellb6568b12013-11-07 12:09:13 +1030418 if (!s) {
Ram Paibd5cbce2006-06-08 22:12:53 -0700419 s = new_symbol(name, mod, export);
Rusty Russellb6568b12013-11-07 12:09:13 +1030420 /* Don't complain when we find it later. */
421 s->preloaded = 1;
422 }
Sam Ravnborg040fcc82006-01-28 22:15:55 +0100423 s->crc = crc;
424 s->crc_valid = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425}
426
Sam Ravnborg5c3ead82006-01-28 17:19:35 +0100427void *grab_file(const char *filename, unsigned long *size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428{
429 struct stat st;
Jesper Juhleb3d5cc2012-05-23 22:28:49 +0930430 void *map = MAP_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431 int fd;
432
433 fd = open(filename, O_RDONLY);
Jesper Juhleb3d5cc2012-05-23 22:28:49 +0930434 if (fd < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435 return NULL;
Jesper Juhleb3d5cc2012-05-23 22:28:49 +0930436 if (fstat(fd, &st))
437 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438
439 *size = st.st_size;
440 map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441
Jesper Juhleb3d5cc2012-05-23 22:28:49 +0930442failed:
443 close(fd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444 if (map == MAP_FAILED)
445 return NULL;
446 return map;
447}
448
Sam Ravnborg5c3ead82006-01-28 17:19:35 +0100449/**
450 * Return a copy of the next line in a mmap'ed file.
451 * spaces in the beginning of the line is trimmed away.
452 * Return a pointer to a static buffer.
453 **/
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100454char *get_next_line(unsigned long *pos, void *file, unsigned long size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455{
456 static char line[4096];
457 int skip = 1;
458 size_t len = 0;
459 signed char *p = (signed char *)file + *pos;
460 char *s = line;
461
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100462 for (; *pos < size ; (*pos)++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463 if (skip && isspace(*p)) {
464 p++;
465 continue;
466 }
467 skip = 0;
468 if (*p != '\n' && (*pos < size)) {
469 len++;
470 *s++ = *p++;
471 if (len > 4095)
472 break; /* Too long, stop */
473 } else {
474 /* End of string */
475 *s = '\0';
476 return line;
477 }
478 }
479 /* End of buffer */
480 return NULL;
481}
482
Sam Ravnborg5c3ead82006-01-28 17:19:35 +0100483void release_file(void *file, unsigned long size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484{
485 munmap(file, size);
486}
487
Sam Ravnborg85bd2fd2007-02-26 15:33:52 +0100488static int parse_elf(struct elf_info *info, const char *filename)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489{
490 unsigned int i;
Sam Ravnborg85bd2fd2007-02-26 15:33:52 +0100491 Elf_Ehdr *hdr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492 Elf_Shdr *sechdrs;
493 Elf_Sym *sym;
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200494 const char *secstrings;
495 unsigned int symtab_idx = ~0U, symtab_shndx_idx = ~0U;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496
497 hdr = grab_file(filename, &info->size);
498 if (!hdr) {
Guenter Roeckeed380f2013-09-23 15:23:54 +0930499 if (ignore_missing_files) {
500 fprintf(stderr, "%s: %s (ignored)\n", filename,
501 strerror(errno));
502 return 0;
503 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504 perror(filename);
Sam Ravnborg6803dc02006-06-24 23:46:54 +0200505 exit(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506 }
507 info->hdr = hdr;
Sam Ravnborg85bd2fd2007-02-26 15:33:52 +0100508 if (info->size < sizeof(*hdr)) {
509 /* file too small, assume this is an empty .o file */
510 return 0;
511 }
512 /* Is this a valid ELF file? */
513 if ((hdr->e_ident[EI_MAG0] != ELFMAG0) ||
514 (hdr->e_ident[EI_MAG1] != ELFMAG1) ||
515 (hdr->e_ident[EI_MAG2] != ELFMAG2) ||
516 (hdr->e_ident[EI_MAG3] != ELFMAG3)) {
517 /* Not an ELF file - silently ignore it */
518 return 0;
519 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520 /* Fix endianness in ELF header */
Anders Kaseorg7d875a02009-05-03 22:02:55 +0200521 hdr->e_type = TO_NATIVE(hdr->e_type);
522 hdr->e_machine = TO_NATIVE(hdr->e_machine);
523 hdr->e_version = TO_NATIVE(hdr->e_version);
524 hdr->e_entry = TO_NATIVE(hdr->e_entry);
525 hdr->e_phoff = TO_NATIVE(hdr->e_phoff);
526 hdr->e_shoff = TO_NATIVE(hdr->e_shoff);
527 hdr->e_flags = TO_NATIVE(hdr->e_flags);
528 hdr->e_ehsize = TO_NATIVE(hdr->e_ehsize);
529 hdr->e_phentsize = TO_NATIVE(hdr->e_phentsize);
530 hdr->e_phnum = TO_NATIVE(hdr->e_phnum);
531 hdr->e_shentsize = TO_NATIVE(hdr->e_shentsize);
532 hdr->e_shnum = TO_NATIVE(hdr->e_shnum);
533 hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534 sechdrs = (void *)hdr + hdr->e_shoff;
535 info->sechdrs = sechdrs;
536
Petr Stetiara83710e2007-08-27 12:15:07 +0200537 /* Check if file offset is correct */
538 if (hdr->e_shoff > info->size) {
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100539 fatal("section header offset=%lu in file '%s' is bigger than "
540 "filesize=%lu\n", (unsigned long)hdr->e_shoff,
541 filename, info->size);
Petr Stetiara83710e2007-08-27 12:15:07 +0200542 return 0;
543 }
544
Anders Kaseorg68457562011-05-19 16:55:27 -0600545 if (hdr->e_shnum == SHN_UNDEF) {
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200546 /*
547 * There are more than 64k sections,
548 * read count from .sh_size.
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200549 */
550 info->num_sections = TO_NATIVE(sechdrs[0].sh_size);
551 }
552 else {
553 info->num_sections = hdr->e_shnum;
554 }
555 if (hdr->e_shstrndx == SHN_XINDEX) {
Anders Kaseorg68457562011-05-19 16:55:27 -0600556 info->secindex_strings = TO_NATIVE(sechdrs[0].sh_link);
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200557 }
558 else {
559 info->secindex_strings = hdr->e_shstrndx;
560 }
561
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562 /* Fix endianness in section headers */
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200563 for (i = 0; i < info->num_sections; i++) {
Anders Kaseorg7d875a02009-05-03 22:02:55 +0200564 sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name);
565 sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type);
566 sechdrs[i].sh_flags = TO_NATIVE(sechdrs[i].sh_flags);
567 sechdrs[i].sh_addr = TO_NATIVE(sechdrs[i].sh_addr);
568 sechdrs[i].sh_offset = TO_NATIVE(sechdrs[i].sh_offset);
569 sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size);
570 sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link);
571 sechdrs[i].sh_info = TO_NATIVE(sechdrs[i].sh_info);
572 sechdrs[i].sh_addralign = TO_NATIVE(sechdrs[i].sh_addralign);
573 sechdrs[i].sh_entsize = TO_NATIVE(sechdrs[i].sh_entsize);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 }
575 /* Find symbol table. */
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200576 secstrings = (void *)hdr + sechdrs[info->secindex_strings].sh_offset;
577 for (i = 1; i < info->num_sections; i++) {
Ram Paibd5cbce2006-06-08 22:12:53 -0700578 const char *secname;
Tejun Heo56fc82c2009-02-06 00:48:02 +0900579 int nobits = sechdrs[i].sh_type == SHT_NOBITS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580
Tejun Heo56fc82c2009-02-06 00:48:02 +0900581 if (!nobits && sechdrs[i].sh_offset > info->size) {
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100582 fatal("%s is truncated. sechdrs[i].sh_offset=%lu > "
583 "sizeof(*hrd)=%zu\n", filename,
584 (unsigned long)sechdrs[i].sh_offset,
585 sizeof(*hdr));
Sam Ravnborg85bd2fd2007-02-26 15:33:52 +0100586 return 0;
587 }
Ram Paibd5cbce2006-06-08 22:12:53 -0700588 secname = secstrings + sechdrs[i].sh_name;
589 if (strcmp(secname, ".modinfo") == 0) {
Tejun Heo56fc82c2009-02-06 00:48:02 +0900590 if (nobits)
591 fatal("%s has NOBITS .modinfo\n", filename);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592 info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
593 info->modinfo_len = sechdrs[i].sh_size;
Ram Paibd5cbce2006-06-08 22:12:53 -0700594 } else if (strcmp(secname, "__ksymtab") == 0)
595 info->export_sec = i;
Sam Ravnborgc96fca22006-07-01 11:44:23 +0200596 else if (strcmp(secname, "__ksymtab_unused") == 0)
597 info->export_unused_sec = i;
Ram Paibd5cbce2006-06-08 22:12:53 -0700598 else if (strcmp(secname, "__ksymtab_gpl") == 0)
599 info->export_gpl_sec = i;
Sam Ravnborgc96fca22006-07-01 11:44:23 +0200600 else if (strcmp(secname, "__ksymtab_unused_gpl") == 0)
601 info->export_unused_gpl_sec = i;
Ram Paibd5cbce2006-06-08 22:12:53 -0700602 else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
603 info->export_gpl_future_sec = i;
Matthias Maennich69923202019-10-18 10:31:42 +0100604 else if (strcmp(secname, "__ksymtab_strings") == 0)
605 info->ksymtab_strings = (void *)hdr +
606 sechdrs[i].sh_offset -
607 sechdrs[i].sh_addr;
Ram Paibd5cbce2006-06-08 22:12:53 -0700608
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200609 if (sechdrs[i].sh_type == SHT_SYMTAB) {
610 unsigned int sh_link_idx;
611 symtab_idx = i;
612 info->symtab_start = (void *)hdr +
613 sechdrs[i].sh_offset;
614 info->symtab_stop = (void *)hdr +
615 sechdrs[i].sh_offset + sechdrs[i].sh_size;
Anders Kaseorg68457562011-05-19 16:55:27 -0600616 sh_link_idx = sechdrs[i].sh_link;
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200617 info->strtab = (void *)hdr +
618 sechdrs[sh_link_idx].sh_offset;
619 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200621 /* 32bit section no. table? ("more than 64k sections") */
622 if (sechdrs[i].sh_type == SHT_SYMTAB_SHNDX) {
623 symtab_shndx_idx = i;
624 info->symtab_shndx_start = (void *)hdr +
625 sechdrs[i].sh_offset;
626 info->symtab_shndx_stop = (void *)hdr +
627 sechdrs[i].sh_offset + sechdrs[i].sh_size;
628 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629 }
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100630 if (!info->symtab_start)
Sam Ravnborgcb805142006-01-28 16:57:26 +0100631 fatal("%s has no symtab?\n", filename);
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100632
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633 /* Fix endianness in symbols */
634 for (sym = info->symtab_start; sym < info->symtab_stop; sym++) {
635 sym->st_shndx = TO_NATIVE(sym->st_shndx);
636 sym->st_name = TO_NATIVE(sym->st_name);
637 sym->st_value = TO_NATIVE(sym->st_value);
638 sym->st_size = TO_NATIVE(sym->st_size);
639 }
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200640
641 if (symtab_shndx_idx != ~0U) {
642 Elf32_Word *p;
Anders Kaseorg68457562011-05-19 16:55:27 -0600643 if (symtab_idx != sechdrs[symtab_shndx_idx].sh_link)
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200644 fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n",
Anders Kaseorg68457562011-05-19 16:55:27 -0600645 filename, sechdrs[symtab_shndx_idx].sh_link,
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +0200646 symtab_idx);
647 /* Fix endianness */
648 for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop;
649 p++)
650 *p = TO_NATIVE(*p);
651 }
652
Sam Ravnborg85bd2fd2007-02-26 15:33:52 +0100653 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654}
655
Sam Ravnborg5c3ead82006-01-28 17:19:35 +0100656static void parse_elf_finish(struct elf_info *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657{
658 release_file(info->hdr, info->size);
659}
660
Sam Ravnborg4d7365d2008-06-12 15:02:55 +0200661static int ignore_undef_symbol(struct elf_info *info, const char *symname)
662{
663 /* ignore __this_module, it will be resolved shortly */
Masahiro Yamadab2c5cdc2018-05-09 16:23:45 +0900664 if (strcmp(symname, "__this_module") == 0)
Sam Ravnborg4d7365d2008-06-12 15:02:55 +0200665 return 1;
666 /* ignore global offset table */
667 if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0)
668 return 1;
669 if (info->hdr->e_machine == EM_PPC)
670 /* Special register function linked on all modules during final link of .ko */
Masahiro Yamadad62c4762018-05-09 18:50:38 +0900671 if (strstarts(symname, "_restgpr_") ||
672 strstarts(symname, "_savegpr_") ||
673 strstarts(symname, "_rest32gpr_") ||
674 strstarts(symname, "_save32gpr_") ||
675 strstarts(symname, "_restvr_") ||
676 strstarts(symname, "_savevr_"))
Sam Ravnborg4d7365d2008-06-12 15:02:55 +0200677 return 1;
Stephen Rothwell7fca5dc2010-06-29 20:08:42 +0000678 if (info->hdr->e_machine == EM_PPC64)
679 /* Special register function linked on all modules during final link of .ko */
Masahiro Yamadad62c4762018-05-09 18:50:38 +0900680 if (strstarts(symname, "_restgpr0_") ||
681 strstarts(symname, "_savegpr0_") ||
682 strstarts(symname, "_restvr_") ||
683 strstarts(symname, "_savevr_") ||
Alan Modrac1536932016-01-15 20:52:22 +1100684 strcmp(symname, ".TOC.") == 0)
Stephen Rothwell7fca5dc2010-06-29 20:08:42 +0000685 return 1;
Sam Ravnborg4d7365d2008-06-12 15:02:55 +0200686 /* Do not ignore this symbol */
687 return 0;
688}
689
Sam Ravnborg5c3ead82006-01-28 17:19:35 +0100690static void handle_modversions(struct module *mod, struct elf_info *info,
691 Elf_Sym *sym, const char *symname)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692{
693 unsigned int crc;
Alessio Igor Bogani62a26352011-07-14 08:51:16 +0200694 enum export export;
Nicholas Piggind8c1eb82016-11-24 03:41:42 +1100695 bool is_crc = false;
Masahiro Yamada389eb3f2019-10-03 16:58:22 +0900696 const char *name;
Alessio Igor Bogani62a26352011-07-14 08:51:16 +0200697
Frank Rowand258f7422012-04-09 17:59:03 -0700698 if ((!is_vmlinux(mod->name) || mod->is_dot_o) &&
Masahiro Yamadad62c4762018-05-09 18:50:38 +0900699 strstarts(symname, "__ksymtab"))
Alessio Igor Bogani62a26352011-07-14 08:51:16 +0200700 export = export_from_secname(info, get_secindex(info, sym));
701 else
702 export = export_from_sec(info, get_secindex(info, sym));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703
Andi Kleenb5064652013-11-12 15:08:38 -0800704 /* CRC'd symbol */
Masahiro Yamadad62c4762018-05-09 18:50:38 +0900705 if (strstarts(symname, "__crc_")) {
Nicholas Piggind8c1eb82016-11-24 03:41:42 +1100706 is_crc = true;
Andi Kleenb5064652013-11-12 15:08:38 -0800707 crc = (unsigned int) sym->st_value;
Ard Biesheuvel56067812017-02-03 09:54:05 +0000708 if (sym->st_shndx != SHN_UNDEF && sym->st_shndx != SHN_ABS) {
709 unsigned int *crcp;
710
711 /* symbol points to the CRC in the ELF object */
Masahiro Yamadaafa04592019-11-15 02:42:21 +0900712 crcp = sym_get_data(info, sym);
Fredrik Noring54a71512019-03-27 19:12:50 +0100713 crc = TO_NATIVE(*crcp);
Ard Biesheuvel56067812017-02-03 09:54:05 +0000714 }
Masahiro Yamadab2c5cdc2018-05-09 16:23:45 +0900715 sym_update_crc(symname + strlen("__crc_"), mod, crc,
Andi Kleenb5064652013-11-12 15:08:38 -0800716 export);
717 }
718
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719 switch (sym->st_shndx) {
720 case SHN_COMMON:
Masahiro Yamadad62c4762018-05-09 18:50:38 +0900721 if (strstarts(symname, "__gnu_lto_")) {
Andi Kleenef178f92014-02-08 09:01:17 +0100722 /* Should warn here, but modpost runs before the linker */
723 } else
724 warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726 case SHN_UNDEF:
727 /* undefined symbol */
728 if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL &&
729 ELF_ST_BIND(sym->st_info) != STB_WEAK)
730 break;
Sam Ravnborg4d7365d2008-06-12 15:02:55 +0200731 if (ignore_undef_symbol(info, symname))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732 break;
Ben Colline8d529012005-08-19 13:44:57 -0700733/* cope with newer glibc (2.3.4 or higher) STT_ definition in elf.h */
734#if defined(STT_REGISTER) || defined(STT_SPARC_REGISTER)
735/* add compatibility with older glibc */
736#ifndef STT_SPARC_REGISTER
737#define STT_SPARC_REGISTER STT_REGISTER
738#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 if (info->hdr->e_machine == EM_SPARC ||
740 info->hdr->e_machine == EM_SPARCV9) {
741 /* Ignore register directives. */
Ben Colline8d529012005-08-19 13:44:57 -0700742 if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743 break;
Sam Ravnborg62070fa2006-03-03 16:46:04 +0100744 if (symname[0] == '.') {
Randy Dunlap1f3aa902018-08-15 12:30:38 -0700745 char *munged = NOFAIL(strdup(symname));
Sam Ravnborg62070fa2006-03-03 16:46:04 +0100746 munged[0] = '_';
747 munged[1] = toupper(munged[1]);
748 symname = munged;
749 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750 }
751#endif
Sam Ravnborg62070fa2006-03-03 16:46:04 +0100752
Nicholas Piggind8c1eb82016-11-24 03:41:42 +1100753 if (is_crc) {
754 const char *e = is_vmlinux(mod->name) ?"":".ko";
Masahiro Yamadab2c5cdc2018-05-09 16:23:45 +0900755 warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n",
756 symname + strlen("__crc_"), mod->name, e);
Nicholas Piggind8c1eb82016-11-24 03:41:42 +1100757 }
Rusty Russellb92021b2013-03-15 15:04:17 +1030758 mod->unres = alloc_symbol(symname,
759 ELF_ST_BIND(sym->st_info) == STB_WEAK,
760 mod->unres);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761 break;
762 default:
763 /* All exported symbols */
Masahiro Yamadad62c4762018-05-09 18:50:38 +0900764 if (strstarts(symname, "__ksymtab_")) {
Matthias Maennichcb9b55d2019-09-06 11:32:28 +0100765 name = symname + strlen("__ksymtab_");
Matthias Maennich9ae5bd12019-10-18 10:31:41 +0100766 sym_add_exported(name, mod, export);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767 }
Masahiro Yamadab2c5cdc2018-05-09 16:23:45 +0900768 if (strcmp(symname, "init_module") == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769 mod->has_init = 1;
Masahiro Yamadab2c5cdc2018-05-09 16:23:45 +0900770 if (strcmp(symname, "cleanup_module") == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 mod->has_cleanup = 1;
772 break;
773 }
774}
775
Sam Ravnborg5c3ead82006-01-28 17:19:35 +0100776/**
777 * Parse tag=value strings from .modinfo section
778 **/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779static char *next_string(char *string, unsigned long *secsize)
780{
781 /* Skip non-zero chars */
782 while (string[0]) {
783 string++;
784 if ((*secsize)-- <= 1)
785 return NULL;
786 }
787
788 /* Skip any zero padding. */
789 while (!string[0]) {
790 string++;
791 if ((*secsize)-- <= 1)
792 return NULL;
793 }
794 return string;
795}
796
Masahiro Yamadabca2cce2018-05-09 18:50:37 +0900797static char *get_next_modinfo(struct elf_info *info, const char *tag,
798 char *prev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799{
800 char *p;
801 unsigned int taglen = strlen(tag);
Masahiro Yamadabca2cce2018-05-09 18:50:37 +0900802 char *modinfo = info->modinfo;
803 unsigned long size = info->modinfo_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804
Masahiro Yamadabca2cce2018-05-09 18:50:37 +0900805 if (prev) {
806 size -= prev - modinfo;
807 modinfo = next_string(prev, &size);
Sam Ravnborgb817f6f2006-06-09 21:53:55 +0200808 }
809
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810 for (p = modinfo; p; p = next_string(p, &size)) {
811 if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
812 return p + taglen + 1;
813 }
814 return NULL;
815}
816
Masahiro Yamadabca2cce2018-05-09 18:50:37 +0900817static char *get_modinfo(struct elf_info *info, const char *tag)
Sam Ravnborgb817f6f2006-06-09 21:53:55 +0200818
819{
Masahiro Yamadabca2cce2018-05-09 18:50:37 +0900820 return get_next_modinfo(info, tag, NULL);
Sam Ravnborgb817f6f2006-06-09 21:53:55 +0200821}
822
Sam Ravnborg93684d32006-02-19 11:53:35 +0100823/**
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +0100824 * Test if string s ends in string sub
825 * return 0 if match
826 **/
827static int strrcmp(const char *s, const char *sub)
828{
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100829 int slen, sublen;
Sam Ravnborg62070fa2006-03-03 16:46:04 +0100830
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +0100831 if (!s || !sub)
832 return 1;
Sam Ravnborg62070fa2006-03-03 16:46:04 +0100833
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +0100834 slen = strlen(s);
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100835 sublen = strlen(sub);
Sam Ravnborg62070fa2006-03-03 16:46:04 +0100836
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +0100837 if ((slen == 0) || (sublen == 0))
838 return 1;
839
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100840 if (sublen > slen)
841 return 1;
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +0100842
Sam Ravnborgdf578e72008-01-11 19:17:15 +0100843 return memcmp(s + slen - sublen, sub, sublen);
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +0100844}
845
Sam Ravnborgff13f922008-01-23 19:54:27 +0100846static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
847{
Sam Ravnborg58fb0d42008-01-23 21:13:50 +0100848 if (sym)
849 return elf->strtab + sym->st_name;
850 else
Sam Ravnborgf6667512008-02-06 21:51:18 +0100851 return "(unknown)";
Sam Ravnborgff13f922008-01-23 19:54:27 +0100852}
853
Sam Ravnborg10668222008-01-13 22:21:31 +0100854/* The pattern is an array of simple patterns.
855 * "foo" will match an exact string equal to "foo"
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100856 * "*foo" will match a string that ends with "foo"
Sam Ravnborg10668222008-01-13 22:21:31 +0100857 * "foo*" will match a string that begins with "foo"
Paul Gortmaker09c20c02015-04-20 10:20:26 +0930858 * "*foo*" will match a string that contains "foo"
Sam Ravnborg10668222008-01-13 22:21:31 +0100859 */
Trevor Keith5c725132009-09-22 16:43:38 -0700860static int match(const char *sym, const char * const pat[])
Sam Ravnborg10668222008-01-13 22:21:31 +0100861{
862 const char *p;
863 while (*pat) {
864 p = *pat++;
865 const char *endp = p + strlen(p) - 1;
866
Paul Gortmaker09c20c02015-04-20 10:20:26 +0930867 /* "*foo*" */
868 if (*p == '*' && *endp == '*') {
Denis Efremov6f02bdf2019-08-27 15:20:23 +0300869 char *bare = NOFAIL(strndup(p + 1, strlen(p) - 2));
870 char *here = strstr(sym, bare);
Paul Gortmaker09c20c02015-04-20 10:20:26 +0930871
Paul Gortmaker09c20c02015-04-20 10:20:26 +0930872 free(bare);
873 if (here != NULL)
874 return 1;
875 }
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100876 /* "*foo" */
Paul Gortmaker09c20c02015-04-20 10:20:26 +0930877 else if (*p == '*') {
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100878 if (strrcmp(sym, p + 1) == 0)
879 return 1;
880 }
Sam Ravnborg10668222008-01-13 22:21:31 +0100881 /* "foo*" */
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100882 else if (*endp == '*') {
Sam Ravnborg10668222008-01-13 22:21:31 +0100883 if (strncmp(sym, p, strlen(p) - 1) == 0)
884 return 1;
885 }
Sam Ravnborg10668222008-01-13 22:21:31 +0100886 /* no wildcards */
887 else {
888 if (strcmp(p, sym) == 0)
889 return 1;
890 }
891 }
892 /* no match */
893 return 0;
894}
895
Sam Ravnborg10668222008-01-13 22:21:31 +0100896/* sections that we do not want to do full section mismatch check on */
Mathias Krause7a3ee752014-08-27 20:28:53 +0930897static const char *const section_white_list[] =
Sam Ravnborg4391ed62009-05-04 13:05:26 +0200898{
899 ".comment*",
900 ".debug*",
Chen Gang4d10c222013-08-20 15:33:19 +0930901 ".cranges", /* sh64 */
H.J. Lu11215842010-12-15 17:11:22 -0800902 ".zdebug*", /* Compressed debug sections. */
David Howells739d8752018-03-08 09:48:46 +0000903 ".GCC.command.line", /* record-gcc-switches */
Sam Ravnborg4391ed62009-05-04 13:05:26 +0200904 ".mdebug*", /* alpha, score, mips etc. */
905 ".pdr", /* alpha, score, mips etc. */
906 ".stab*",
907 ".note*",
908 ".got*",
909 ".toc*",
Max Filippovaf42e972012-09-17 05:44:38 +0400910 ".xt.prop", /* xtensa */
911 ".xt.lit", /* xtensa */
Vineet Guptaf2e207f2013-01-21 17:18:57 +1030912 ".arcextmap*", /* arc */
913 ".gnu.linkonce.arcext*", /* arc : modules */
Noam Camusd1189c62015-10-26 19:51:46 +1030914 ".cmem*", /* EZchip */
915 ".fmt_slot*", /* EZchip */
Andi Kleenef178f92014-02-08 09:01:17 +0100916 ".gnu.lto*",
Josh Poimboeufe390f9a2017-03-01 12:04:44 -0600917 ".discard.*",
Sam Ravnborg4391ed62009-05-04 13:05:26 +0200918 NULL
919};
Sam Ravnborg10668222008-01-13 22:21:31 +0100920
Sam Ravnborge241a632008-01-28 20:13:13 +0100921/*
Anders Kaseorgb614a692009-04-23 16:49:33 -0400922 * This is used to find sections missing the SHF_ALLOC flag.
Sam Ravnborge241a632008-01-28 20:13:13 +0100923 * The cause of this is often a section specified in assembler
Anders Kaseorgb614a692009-04-23 16:49:33 -0400924 * without "ax" / "aw".
Sam Ravnborge241a632008-01-28 20:13:13 +0100925 */
Anders Kaseorgb614a692009-04-23 16:49:33 -0400926static void check_section(const char *modname, struct elf_info *elf,
Masahiro Yamadabb66fc62014-06-10 19:08:13 +0900927 Elf_Shdr *sechdr)
Sam Ravnborge241a632008-01-28 20:13:13 +0100928{
Anders Kaseorgb614a692009-04-23 16:49:33 -0400929 const char *sec = sech_name(elf, sechdr);
Sam Ravnborge241a632008-01-28 20:13:13 +0100930
Anders Kaseorgb614a692009-04-23 16:49:33 -0400931 if (sechdr->sh_type == SHT_PROGBITS &&
932 !(sechdr->sh_flags & SHF_ALLOC) &&
933 !match(sec, section_white_list)) {
934 warn("%s (%s): unexpected non-allocatable section.\n"
935 "Did you forget to use \"ax\"/\"aw\" in a .S file?\n"
936 "Note that for example <linux/init.h> contains\n"
937 "section definitions for use in .S files.\n\n",
938 modname, sec);
Sam Ravnborge241a632008-01-28 20:13:13 +0100939 }
Sam Ravnborge241a632008-01-28 20:13:13 +0100940}
941
942
943
Sam Ravnborgeb8f6892008-01-20 20:07:28 +0100944#define ALL_INIT_DATA_SECTIONS \
Rasmus Villemoesa0d8f802014-07-27 07:28:01 +0930945 ".init.setup", ".init.rodata", ".meminit.rodata", \
946 ".init.data", ".meminit.data"
Sam Ravnborgeb8f6892008-01-20 20:07:28 +0100947#define ALL_EXIT_DATA_SECTIONS \
Rasmus Villemoesa0d8f802014-07-27 07:28:01 +0930948 ".exit.data", ".memexit.data"
Sam Ravnborg10668222008-01-13 22:21:31 +0100949
Sam Ravnborgeb8f6892008-01-20 20:07:28 +0100950#define ALL_INIT_TEXT_SECTIONS \
Rasmus Villemoesa0d8f802014-07-27 07:28:01 +0930951 ".init.text", ".meminit.text"
Sam Ravnborgeb8f6892008-01-20 20:07:28 +0100952#define ALL_EXIT_TEXT_SECTIONS \
Rasmus Villemoesa0d8f802014-07-27 07:28:01 +0930953 ".exit.text", ".memexit.text"
Sam Ravnborg10668222008-01-13 22:21:31 +0100954
Sebastian Andrzej Siewiorbb15d8d2012-06-03 20:48:17 +0200955#define ALL_PCI_INIT_SECTIONS \
Rasmus Villemoesa0d8f802014-07-27 07:28:01 +0930956 ".pci_fixup_early", ".pci_fixup_header", ".pci_fixup_final", \
957 ".pci_fixup_enable", ".pci_fixup_resume", \
958 ".pci_fixup_resume_early", ".pci_fixup_suspend"
Sebastian Andrzej Siewiorbb15d8d2012-06-03 20:48:17 +0200959
Paul Gortmakere24f6622013-06-19 19:30:48 -0400960#define ALL_XXXINIT_SECTIONS MEM_INIT_SECTIONS
961#define ALL_XXXEXIT_SECTIONS MEM_EXIT_SECTIONS
Uwe Kleine-König4a31a222010-01-29 12:04:26 +0100962
963#define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS
964#define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS
Sam Ravnborg10668222008-01-13 22:21:31 +0100965
Rasmus Villemoesa0d8f802014-07-27 07:28:01 +0930966#define DATA_SECTIONS ".data", ".data.rel"
Quentin Casasnovas157d1972015-04-13 20:42:52 +0930967#define TEXT_SECTIONS ".text", ".text.unlikely", ".sched.text", \
Chris Metcalf6727ad92016-10-07 17:02:55 -0700968 ".kprobes.text", ".cpuidle.text"
Quentin Casasnovas52dc0592015-04-13 20:52:53 +0930969#define OTHER_TEXT_SECTIONS ".ref.text", ".head.text", ".spinlock.text", \
Chris Metcalf673c2c32015-07-08 17:07:41 -0400970 ".fixup", ".entry.text", ".exception.text", ".text.*", \
971 ".coldtext"
Sam Ravnborg10668222008-01-13 22:21:31 +0100972
Jan Beulichfd6c3a82009-03-12 10:58:33 +0000973#define INIT_SECTIONS ".init.*"
Jan Beulichfd6c3a82009-03-12 10:58:33 +0000974#define MEM_INIT_SECTIONS ".meminit.*"
Sam Ravnborgeb8f6892008-01-20 20:07:28 +0100975
Jan Beulichfd6c3a82009-03-12 10:58:33 +0000976#define EXIT_SECTIONS ".exit.*"
Jan Beulichfd6c3a82009-03-12 10:58:33 +0000977#define MEM_EXIT_SECTIONS ".memexit.*"
Sam Ravnborgeb8f6892008-01-20 20:07:28 +0100978
Quentin Casasnovas52dc0592015-04-13 20:52:53 +0930979#define ALL_TEXT_SECTIONS ALL_INIT_TEXT_SECTIONS, ALL_EXIT_TEXT_SECTIONS, \
980 TEXT_SECTIONS, OTHER_TEXT_SECTIONS
981
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100982/* init data sections */
Mathias Krause7a3ee752014-08-27 20:28:53 +0930983static const char *const init_data_sections[] =
984 { ALL_INIT_DATA_SECTIONS, NULL };
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100985
986/* all init sections */
Mathias Krause7a3ee752014-08-27 20:28:53 +0930987static const char *const init_sections[] = { ALL_INIT_SECTIONS, NULL };
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100988
989/* All init and exit sections (code + data) */
Mathias Krause7a3ee752014-08-27 20:28:53 +0930990static const char *const init_exit_sections[] =
Sam Ravnborgeb8f6892008-01-20 20:07:28 +0100991 {ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL };
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100992
Paul Gortmaker4a3893d2015-04-20 10:20:40 +0930993/* all text sections */
994static const char *const text_sections[] = { ALL_TEXT_SECTIONS, NULL };
995
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100996/* data section */
Mathias Krause7a3ee752014-08-27 20:28:53 +0930997static const char *const data_sections[] = { DATA_SECTIONS, NULL };
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100998
Sam Ravnborg6c5bd232008-01-20 10:43:27 +0100999
1000/* symbols in .data that may refer to init/exit sections */
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001001#define DEFAULT_SYMBOL_WHITE_LIST \
1002 "*driver", \
1003 "*_template", /* scsi uses *_template a lot */ \
1004 "*_timer", /* arm uses ops structures named _timer a lot */ \
1005 "*_sht", /* scsi also used *_sht to some extent */ \
1006 "*_ops", \
1007 "*_probe", \
1008 "*_probe_one", \
1009 "*_console"
Sam Ravnborg6c5bd232008-01-20 10:43:27 +01001010
Mathias Krause7a3ee752014-08-27 20:28:53 +09301011static const char *const head_sections[] = { ".head.text*", NULL };
1012static const char *const linker_symbols[] =
Sam Ravnborg6c5bd232008-01-20 10:43:27 +01001013 { "__init_begin", "_sinittext", "_einittext", NULL };
Paul Gortmaker4a3893d2015-04-20 10:20:40 +09301014static const char *const optim_symbols[] = { "*.constprop.*", NULL };
Sam Ravnborg6c5bd232008-01-20 10:43:27 +01001015
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001016enum mismatch {
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001017 TEXT_TO_ANY_INIT,
1018 DATA_TO_ANY_INIT,
1019 TEXT_TO_ANY_EXIT,
1020 DATA_TO_ANY_EXIT,
1021 XXXINIT_TO_SOME_INIT,
1022 XXXEXIT_TO_SOME_EXIT,
1023 ANY_INIT_TO_ANY_EXIT,
1024 ANY_EXIT_TO_ANY_INIT,
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001025 EXPORT_TO_INIT_EXIT,
Quentin Casasnovas52dc0592015-04-13 20:52:53 +09301026 EXTABLE_TO_NON_TEXT,
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001027};
1028
Quentin Casasnovase5d8f592015-04-13 20:55:15 +09301029/**
1030 * Describe how to match sections on different criterias:
1031 *
1032 * @fromsec: Array of sections to be matched.
1033 *
1034 * @bad_tosec: Relocations applied to a section in @fromsec to a section in
1035 * this array is forbidden (black-list). Can be empty.
1036 *
1037 * @good_tosec: Relocations applied to a section in @fromsec must be
1038 * targetting sections in this array (white-list). Can be empty.
1039 *
1040 * @mismatch: Type of mismatch.
1041 *
1042 * @symbol_white_list: Do not match a relocation to a symbol in this list
1043 * even if it is targetting a section in @bad_to_sec.
1044 *
1045 * @handler: Specific handler to call when a match is found. If NULL,
1046 * default_mismatch_handler() will be called.
1047 *
1048 */
Sam Ravnborg10668222008-01-13 22:21:31 +01001049struct sectioncheck {
1050 const char *fromsec[20];
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301051 const char *bad_tosec[20];
1052 const char *good_tosec[20];
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001053 enum mismatch mismatch;
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001054 const char *symbol_white_list[20];
Quentin Casasnovas644e8f12015-04-13 20:43:17 +09301055 void (*handler)(const char *modname, struct elf_info *elf,
1056 const struct sectioncheck* const mismatch,
1057 Elf_Rela *r, Elf_Sym *sym, const char *fromsec);
1058
Sam Ravnborg10668222008-01-13 22:21:31 +01001059};
1060
Quentin Casasnovas52dc0592015-04-13 20:52:53 +09301061static void extable_mismatch_handler(const char *modname, struct elf_info *elf,
1062 const struct sectioncheck* const mismatch,
1063 Elf_Rela *r, Elf_Sym *sym,
1064 const char *fromsec);
1065
Mathias Krause7a3ee752014-08-27 20:28:53 +09301066static const struct sectioncheck sectioncheck[] = {
Sam Ravnborg10668222008-01-13 22:21:31 +01001067/* Do not reference init/exit code/data from
1068 * normal code and data
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_INIT_SECTIONS, NULL },
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001073 .mismatch = TEXT_TO_ANY_INIT,
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_XXXINIT_SECTIONS, NULL },
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001079 .mismatch = DATA_TO_ANY_INIT,
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001080 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001081},
1082{
Uwe Kleine-König0db252452010-01-30 21:14:23 +01001083 .fromsec = { DATA_SECTIONS, NULL },
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301084 .bad_tosec = { INIT_SECTIONS, NULL },
Uwe Kleine-König0db252452010-01-30 21:14:23 +01001085 .mismatch = DATA_TO_ANY_INIT,
1086 .symbol_white_list = {
1087 "*_template", "*_timer", "*_sht", "*_ops",
1088 "*_probe", "*_probe_one", "*_console", NULL
1089 },
1090},
1091{
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001092 .fromsec = { TEXT_SECTIONS, NULL },
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301093 .bad_tosec = { ALL_EXIT_SECTIONS, NULL },
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001094 .mismatch = TEXT_TO_ANY_EXIT,
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001095 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001096},
1097{
1098 .fromsec = { DATA_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 = DATA_TO_ANY_EXIT,
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001101 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
Sam Ravnborgeb8f6892008-01-20 20:07:28 +01001102},
Paul Gortmakere24f6622013-06-19 19:30:48 -04001103/* Do not reference init code/data from meminit code/data */
Sam Ravnborgeb8f6892008-01-20 20:07:28 +01001104{
Uwe Kleine-König4a31a222010-01-29 12:04:26 +01001105 .fromsec = { ALL_XXXINIT_SECTIONS, NULL },
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301106 .bad_tosec = { INIT_SECTIONS, NULL },
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001107 .mismatch = XXXINIT_TO_SOME_INIT,
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001108 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
Sam Ravnborgeb8f6892008-01-20 20:07:28 +01001109},
Paul Gortmakere24f6622013-06-19 19:30:48 -04001110/* Do not reference exit code/data from memexit code/data */
Sam Ravnborgeb8f6892008-01-20 20:07:28 +01001111{
Uwe Kleine-König4a31a222010-01-29 12:04:26 +01001112 .fromsec = { ALL_XXXEXIT_SECTIONS, NULL },
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301113 .bad_tosec = { EXIT_SECTIONS, NULL },
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001114 .mismatch = XXXEXIT_TO_SOME_EXIT,
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001115 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
Sam Ravnborg10668222008-01-13 22:21:31 +01001116},
1117/* Do not use exit code/data from init code */
1118{
Sam Ravnborgeb8f6892008-01-20 20:07:28 +01001119 .fromsec = { ALL_INIT_SECTIONS, NULL },
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301120 .bad_tosec = { ALL_EXIT_SECTIONS, NULL },
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001121 .mismatch = ANY_INIT_TO_ANY_EXIT,
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001122 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
Sam Ravnborg10668222008-01-13 22:21:31 +01001123},
1124/* Do not use init code/data from exit code */
1125{
Sam Ravnborgeb8f6892008-01-20 20:07:28 +01001126 .fromsec = { ALL_EXIT_SECTIONS, NULL },
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301127 .bad_tosec = { ALL_INIT_SECTIONS, NULL },
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001128 .mismatch = ANY_EXIT_TO_ANY_INIT,
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001129 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
Sam Ravnborg10668222008-01-13 22:21:31 +01001130},
Sebastian Andrzej Siewiorbb15d8d2012-06-03 20:48:17 +02001131{
1132 .fromsec = { ALL_PCI_INIT_SECTIONS, NULL },
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301133 .bad_tosec = { INIT_SECTIONS, NULL },
Sebastian Andrzej Siewiorbb15d8d2012-06-03 20:48:17 +02001134 .mismatch = ANY_INIT_TO_ANY_EXIT,
1135 .symbol_white_list = { NULL },
1136},
Sam Ravnborg10668222008-01-13 22:21:31 +01001137/* Do not export init/exit functions or data */
1138{
1139 .fromsec = { "__ksymtab*", NULL },
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301140 .bad_tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001141 .mismatch = EXPORT_TO_INIT_EXIT,
1142 .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
Quentin Casasnovas52dc0592015-04-13 20:52:53 +09301143},
1144{
1145 .fromsec = { "__ex_table", NULL },
1146 /* If you're adding any new black-listed sections in here, consider
1147 * adding a special 'printer' for them in scripts/check_extable.
1148 */
1149 .bad_tosec = { ".altinstr_replacement", NULL },
1150 .good_tosec = {ALL_TEXT_SECTIONS , NULL},
1151 .mismatch = EXTABLE_TO_NON_TEXT,
1152 .handler = extable_mismatch_handler,
Sam Ravnborg10668222008-01-13 22:21:31 +01001153}
1154};
1155
Uwe Kleine-König0d2a6362010-01-30 16:56:20 +01001156static const struct sectioncheck *section_mismatch(
1157 const char *fromsec, const char *tosec)
Sam Ravnborg10668222008-01-13 22:21:31 +01001158{
1159 int i;
1160 int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck);
1161 const struct sectioncheck *check = &sectioncheck[0];
1162
Quentin Casasnovasc5c34392015-04-16 13:16:41 +09301163 /*
1164 * The target section could be the SHT_NUL section when we're
1165 * handling relocations to un-resolved symbols, trying to match it
David Howells739d8752018-03-08 09:48:46 +00001166 * doesn't make much sense and causes build failures on parisc
1167 * architectures.
Quentin Casasnovasc5c34392015-04-16 13:16:41 +09301168 */
1169 if (*tosec == '\0')
1170 return NULL;
1171
Sam Ravnborg10668222008-01-13 22:21:31 +01001172 for (i = 0; i < elems; i++) {
Quentin Casasnovas050e57f2015-04-13 20:41:04 +09301173 if (match(fromsec, check->fromsec)) {
1174 if (check->bad_tosec[0] && match(tosec, check->bad_tosec))
1175 return check;
1176 if (check->good_tosec[0] && !match(tosec, check->good_tosec))
1177 return check;
1178 }
Sam Ravnborg10668222008-01-13 22:21:31 +01001179 check++;
1180 }
Uwe Kleine-König0d2a6362010-01-30 16:56:20 +01001181 return NULL;
Sam Ravnborg10668222008-01-13 22:21:31 +01001182}
1183
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001184/**
1185 * Whitelist to allow certain references to pass with no warning.
Sam Ravnborg0e0d3142007-05-17 20:14:48 +02001186 *
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001187 * Pattern 1:
1188 * If a module parameter is declared __initdata and permissions=0
1189 * then this is legal despite the warning generated.
1190 * We cannot see value of permissions here, so just ignore
1191 * this pattern.
1192 * The pattern is identified by:
1193 * tosec = .init.data
Sam Ravnborg9209aed2006-03-05 00:16:26 +01001194 * fromsec = .data*
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001195 * atsym =__param*
Sam Ravnborg62070fa2006-03-03 16:46:04 +01001196 *
Rusty Russell6a841522010-08-11 23:04:16 -06001197 * Pattern 1a:
1198 * module_param_call() ops can refer to __init set function if permissions=0
1199 * The pattern is identified by:
1200 * tosec = .init.text
1201 * fromsec = .data*
1202 * atsym = __param_ops_*
1203 *
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001204 * Pattern 2:
Randy Dunlap72ee59b2006-04-15 11:17:12 -07001205 * Many drivers utilise a *driver container with references to
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001206 * add, remove, probe functions etc.
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001207 * the pattern is identified by:
Sam Ravnborg83cda2b2007-07-25 21:52:31 +02001208 * tosec = init or exit section
1209 * fromsec = data section
Sam Ravnborgdf578e72008-01-11 19:17:15 +01001210 * atsym = *driver, *_template, *_sht, *_ops, *_probe,
1211 * *probe_one, *_console, *_timer
Vivek Goyalee6a8542007-01-11 01:52:44 +01001212 *
1213 * Pattern 3:
Sam Ravnborgc9939712009-04-26 11:17:42 +02001214 * Whitelist all references from .head.text to any init section
Sam Ravnborg9bf8cb92007-02-26 17:49:06 +01001215 *
Sam Ravnborg1d8af552007-06-03 00:41:22 +02001216 * Pattern 4:
Vivek Goyalee6a8542007-01-11 01:52:44 +01001217 * Some symbols belong to init section but still it is ok to reference
1218 * these from non-init sections as these symbols don't have any memory
1219 * allocated for them and symbol address and value are same. So even
1220 * if init section is freed, its ok to reference those symbols.
1221 * For ex. symbols marking the init section boundaries.
1222 * This pattern is identified by
1223 * refsymname = __init_begin, _sinittext, _einittext
Sam Ravnborg9bf8cb92007-02-26 17:49:06 +01001224 *
Paul Gortmaker4a3893d2015-04-20 10:20:40 +09301225 * Pattern 5:
1226 * GCC may optimize static inlines when fed constant arg(s) resulting
1227 * in functions like cpumask_empty() -- generating an associated symbol
1228 * cpumask_empty.constprop.3 that appears in the audit. If the const that
1229 * is passed in comes from __init, like say nmi_ipi_mask, we get a
1230 * meaningless section warning. May need to add isra symbols too...
1231 * This pattern is identified by
1232 * tosec = init section
1233 * fromsec = text section
1234 * refsymname = *.constprop.*
1235 *
Paul Walmsleya4d26f12018-11-21 13:14:13 -08001236 * Pattern 6:
1237 * Hide section mismatch warnings for ELF local symbols. The goal
1238 * is to eliminate false positive modpost warnings caused by
1239 * compiler-generated ELF local symbol names such as ".LANCHOR1".
1240 * Autogenerated symbol names bypass modpost's "Pattern 2"
1241 * whitelisting, which relies on pattern-matching against symbol
1242 * names to work. (One situation where gcc can autogenerate ELF
1243 * local symbols is when "-fsection-anchors" is used.)
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001244 **/
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001245static int secref_whitelist(const struct sectioncheck *mismatch,
1246 const char *fromsec, const char *fromsym,
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001247 const char *tosec, const char *tosym)
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001248{
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001249 /* Check for pattern 1 */
Sam Ravnborg6c5bd232008-01-20 10:43:27 +01001250 if (match(tosec, init_data_sections) &&
1251 match(fromsec, data_sections) &&
Masahiro Yamadad62c4762018-05-09 18:50:38 +09001252 strstarts(fromsym, "__param"))
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001253 return 0;
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001254
Rusty Russell6a841522010-08-11 23:04:16 -06001255 /* Check for pattern 1a */
1256 if (strcmp(tosec, ".init.text") == 0 &&
1257 match(fromsec, data_sections) &&
Masahiro Yamadad62c4762018-05-09 18:50:38 +09001258 strstarts(fromsym, "__param_ops_"))
Rusty Russell6a841522010-08-11 23:04:16 -06001259 return 0;
1260
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001261 /* Check for pattern 2 */
Sam Ravnborg6c5bd232008-01-20 10:43:27 +01001262 if (match(tosec, init_exit_sections) &&
1263 match(fromsec, data_sections) &&
Uwe Kleine-Königaf92a822010-01-30 20:52:50 +01001264 match(fromsym, mismatch->symbol_white_list))
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001265 return 0;
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001266
Sam Ravnborg9bf8cb92007-02-26 17:49:06 +01001267 /* Check for pattern 3 */
Sam Ravnborg6c5bd232008-01-20 10:43:27 +01001268 if (match(fromsec, head_sections) &&
1269 match(tosec, init_sections))
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001270 return 0;
Sam Ravnborg9bf8cb92007-02-26 17:49:06 +01001271
Sam Ravnborg1d8af552007-06-03 00:41:22 +02001272 /* Check for pattern 4 */
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001273 if (match(tosym, linker_symbols))
1274 return 0;
Sam Ravnborg9bf8cb92007-02-26 17:49:06 +01001275
Paul Gortmaker4a3893d2015-04-20 10:20:40 +09301276 /* Check for pattern 5 */
1277 if (match(fromsec, text_sections) &&
1278 match(tosec, init_sections) &&
1279 match(fromsym, optim_symbols))
1280 return 0;
1281
Paul Walmsleya4d26f12018-11-21 13:14:13 -08001282 /* Check for pattern 6 */
1283 if (strstarts(fromsym, ".L"))
1284 return 0;
1285
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001286 return 1;
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001287}
1288
Sami Tolvanen5818c682018-10-23 15:15:35 -07001289static inline int is_arm_mapping_symbol(const char *str)
1290{
1291 return str[0] == '$' && strchr("axtd", str[1])
1292 && (str[2] == '\0' || str[2] == '.');
1293}
1294
1295/*
1296 * If there's no name there, ignore it; likewise, ignore it if it's
1297 * one of the magic symbols emitted used by current ARM tools.
1298 *
1299 * Otherwise if find_symbols_between() returns those symbols, they'll
1300 * fail the whitelist tests and cause lots of false alarms ... fixable
1301 * only by merging __exit and __init sections into __text, bloating
1302 * the kernel (which is especially evil on embedded platforms).
1303 */
1304static inline int is_valid_name(struct elf_info *elf, Elf_Sym *sym)
1305{
1306 const char *name = elf->strtab + sym->st_name;
1307
1308 if (!name || !strlen(name))
1309 return 0;
1310 return !is_arm_mapping_symbol(name);
1311}
1312
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001313/**
Sam Ravnborg93684d32006-02-19 11:53:35 +01001314 * Find symbol based on relocation record info.
1315 * In some cases the symbol supplied is a valid symbol so
1316 * return refsym. If st_name != 0 we assume this is a valid symbol.
1317 * In other cases the symbol needs to be looked up in the symbol table
1318 * based on section and address.
1319 * **/
Sam Ravnborg9ad21c32008-01-18 21:04:34 +01001320static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,
Sam Ravnborg93684d32006-02-19 11:53:35 +01001321 Elf_Sym *relsym)
1322{
1323 Elf_Sym *sym;
Sam Ravnborg9ad21c32008-01-18 21:04:34 +01001324 Elf_Sym *near = NULL;
1325 Elf64_Sword distance = 20;
1326 Elf64_Sword d;
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +02001327 unsigned int relsym_secindex;
Sam Ravnborg93684d32006-02-19 11:53:35 +01001328
1329 if (relsym->st_name != 0)
1330 return relsym;
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +02001331
1332 relsym_secindex = get_secindex(elf, relsym);
Sam Ravnborg93684d32006-02-19 11:53:35 +01001333 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +02001334 if (get_secindex(elf, sym) != relsym_secindex)
Sam Ravnborg93684d32006-02-19 11:53:35 +01001335 continue;
Atsushi Nemotoae4ac122007-05-22 18:27:39 +09001336 if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
1337 continue;
Sami Tolvanen5818c682018-10-23 15:15:35 -07001338 if (!is_valid_name(elf, sym))
1339 continue;
Sam Ravnborg93684d32006-02-19 11:53:35 +01001340 if (sym->st_value == addr)
1341 return sym;
Sam Ravnborg9ad21c32008-01-18 21:04:34 +01001342 /* Find a symbol nearby - addr are maybe negative */
1343 d = sym->st_value - addr;
1344 if (d < 0)
1345 d = addr - sym->st_value;
1346 if (d < distance) {
1347 distance = d;
1348 near = sym;
1349 }
Sam Ravnborg93684d32006-02-19 11:53:35 +01001350 }
Sam Ravnborg9ad21c32008-01-18 21:04:34 +01001351 /* We need a close match */
1352 if (distance < 20)
1353 return near;
1354 else
1355 return NULL;
Sam Ravnborg93684d32006-02-19 11:53:35 +01001356}
1357
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001358/*
Sam Ravnborg43c74d12006-03-05 12:02:46 +01001359 * Find symbols before or equal addr and after addr - in the section sec.
1360 * If we find two symbols with equal offset prefer one with a valid name.
1361 * The ELF format may have a better way to detect what type of symbol
1362 * it is, but this works for now.
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001363 **/
Sam Ravnborg157c23c2008-01-22 21:44:32 +01001364static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
1365 const char *sec)
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001366{
1367 Elf_Sym *sym;
Sam Ravnborg157c23c2008-01-22 21:44:32 +01001368 Elf_Sym *near = NULL;
Sam Ravnborg157c23c2008-01-22 21:44:32 +01001369 Elf_Addr distance = ~0;
Sam Ravnborg62070fa2006-03-03 16:46:04 +01001370
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001371 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
1372 const char *symsec;
1373
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +02001374 if (is_shndx_special(sym->st_shndx))
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001375 continue;
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +02001376 symsec = sec_name(elf, get_secindex(elf, sym));
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001377 if (strcmp(symsec, sec) != 0)
1378 continue;
David Brownellda68d612007-02-20 13:58:16 -08001379 if (!is_valid_name(elf, sym))
1380 continue;
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001381 if (sym->st_value <= addr) {
Sam Ravnborg157c23c2008-01-22 21:44:32 +01001382 if ((addr - sym->st_value) < distance) {
1383 distance = addr - sym->st_value;
1384 near = sym;
1385 } else if ((addr - sym->st_value) == distance) {
1386 near = sym;
Sam Ravnborg43c74d12006-03-05 12:02:46 +01001387 }
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001388 }
1389 }
Sam Ravnborg157c23c2008-01-22 21:44:32 +01001390 return near;
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001391}
1392
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001393/*
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001394 * Convert a section name to the function/data attribute
1395 * .init.text => __init
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001396 * .memexitconst => __memconst
1397 * etc.
Andy Shevchenkocbcf14a92010-08-17 13:36:40 +03001398 *
1399 * The memory of returned value has been allocated on a heap. The user of this
1400 * method should free it after usage.
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001401*/
1402static char *sec2annotation(const char *s)
1403{
1404 if (match(s, init_exit_sections)) {
Randy Dunlap1f3aa902018-08-15 12:30:38 -07001405 char *p = NOFAIL(malloc(20));
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001406 char *r = p;
1407
1408 *p++ = '_';
1409 *p++ = '_';
1410 if (*s == '.')
1411 s++;
1412 while (*s && *s != '.')
1413 *p++ = *s++;
1414 *p = '\0';
1415 if (*s == '.')
1416 s++;
1417 if (strstr(s, "rodata") != NULL)
1418 strcat(p, "const ");
1419 else if (strstr(s, "data") != NULL)
1420 strcat(p, "data ");
1421 else
1422 strcat(p, " ");
Andy Shevchenkocbcf14a92010-08-17 13:36:40 +03001423 return r;
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001424 } else {
Randy Dunlap1f3aa902018-08-15 12:30:38 -07001425 return NOFAIL(strdup(""));
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001426 }
1427}
1428
1429static int is_function(Elf_Sym *sym)
1430{
1431 if (sym)
1432 return ELF_ST_TYPE(sym->st_info) == STT_FUNC;
1433 else
Sam Ravnborgf6667512008-02-06 21:51:18 +01001434 return -1;
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001435}
1436
Randy Dunlap00759c02011-03-15 14:13:47 -07001437static void print_section_list(const char * const list[20])
1438{
1439 const char *const *s = list;
1440
1441 while (*s) {
1442 fprintf(stderr, "%s", *s);
1443 s++;
1444 if (*s)
1445 fprintf(stderr, ", ");
1446 }
1447 fprintf(stderr, "\n");
1448}
1449
Quentin Casasnovas356ad532015-04-13 20:43:34 +09301450static inline void get_pretty_name(int is_func, const char** name, const char** name_p)
1451{
1452 switch (is_func) {
1453 case 0: *name = "variable"; *name_p = ""; break;
1454 case 1: *name = "function"; *name_p = "()"; break;
1455 default: *name = "(unknown reference)"; *name_p = ""; break;
1456 }
1457}
1458
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001459/*
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001460 * Print a warning about a section mismatch.
1461 * Try to find symbols near it so user can find it.
Sam Ravnborg4c8fbca2006-02-26 22:18:11 +01001462 * Check whitelist before warning - it may be a false positive.
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001463 */
Uwe Kleine-König0d2a6362010-01-30 16:56:20 +01001464static void report_sec_mismatch(const char *modname,
1465 const struct sectioncheck *mismatch,
Masahiro Yamadabb66fc62014-06-10 19:08:13 +09001466 const char *fromsec,
1467 unsigned long long fromaddr,
1468 const char *fromsym,
1469 int from_is_func,
1470 const char *tosec, const char *tosym,
1471 int to_is_func)
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001472{
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001473 const char *from, *from_p;
1474 const char *to, *to_p;
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001475 char *prl_from;
1476 char *prl_to;
Sam Ravnborgf6667512008-02-06 21:51:18 +01001477
Sam Ravnborge5f95c82008-02-02 18:57:18 +01001478 sec_mismatch_count++;
Sam Ravnborge5f95c82008-02-02 18:57:18 +01001479
Quentin Casasnovas356ad532015-04-13 20:43:34 +09301480 get_pretty_name(from_is_func, &from, &from_p);
1481 get_pretty_name(to_is_func, &to, &to_p);
1482
Geert Uytterhoeven7c0ac492008-02-05 11:38:49 +01001483 warn("%s(%s+0x%llx): Section mismatch in reference from the %s %s%s "
1484 "to the %s %s:%s%s\n",
1485 modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec,
1486 tosym, to_p);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001487
Uwe Kleine-König0d2a6362010-01-30 16:56:20 +01001488 switch (mismatch->mismatch) {
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001489 case TEXT_TO_ANY_INIT:
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001490 prl_from = sec2annotation(fromsec);
1491 prl_to = sec2annotation(tosec);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001492 fprintf(stderr,
Sam Ravnborgf6667512008-02-06 21:51:18 +01001493 "The function %s%s() references\n"
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001494 "the %s %s%s%s.\n"
1495 "This is often because %s lacks a %s\n"
1496 "annotation or the annotation of %s is wrong.\n",
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001497 prl_from, fromsym,
1498 to, prl_to, tosym, to_p,
1499 fromsym, prl_to, tosym);
1500 free(prl_from);
1501 free(prl_to);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001502 break;
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001503 case DATA_TO_ANY_INIT: {
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001504 prl_to = sec2annotation(tosec);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001505 fprintf(stderr,
1506 "The variable %s references\n"
1507 "the %s %s%s%s\n"
1508 "If the reference is valid then annotate the\n"
Sam Ravnborg8b8b76c2009-06-06 00:18:05 +02001509 "variable with __init* or __refdata (see linux/init.h) "
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001510 "or name the variable:\n",
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001511 fromsym, to, prl_to, tosym, to_p);
Randy Dunlap00759c02011-03-15 14:13:47 -07001512 print_section_list(mismatch->symbol_white_list);
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001513 free(prl_to);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001514 break;
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001515 }
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001516 case TEXT_TO_ANY_EXIT:
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001517 prl_to = sec2annotation(tosec);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001518 fprintf(stderr,
1519 "The function %s() references a %s in an exit section.\n"
1520 "Often the %s %s%s has valid usage outside the exit section\n"
1521 "and the fix is to remove the %sannotation of %s.\n",
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001522 fromsym, to, to, tosym, to_p, prl_to, tosym);
1523 free(prl_to);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001524 break;
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001525 case DATA_TO_ANY_EXIT: {
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001526 prl_to = sec2annotation(tosec);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001527 fprintf(stderr,
1528 "The variable %s references\n"
1529 "the %s %s%s%s\n"
1530 "If the reference is valid then annotate the\n"
1531 "variable with __exit* (see linux/init.h) or "
1532 "name the variable:\n",
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001533 fromsym, to, prl_to, tosym, to_p);
Randy Dunlap00759c02011-03-15 14:13:47 -07001534 print_section_list(mismatch->symbol_white_list);
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001535 free(prl_to);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001536 break;
1537 }
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001538 case XXXINIT_TO_SOME_INIT:
1539 case XXXEXIT_TO_SOME_EXIT:
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001540 prl_from = sec2annotation(fromsec);
1541 prl_to = sec2annotation(tosec);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001542 fprintf(stderr,
1543 "The %s %s%s%s references\n"
1544 "a %s %s%s%s.\n"
1545 "If %s is only used by %s then\n"
1546 "annotate %s with a matching annotation.\n",
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001547 from, prl_from, fromsym, from_p,
1548 to, prl_to, tosym, to_p,
Geert Uytterhoevenb1d26752008-02-17 14:12:10 +01001549 tosym, fromsym, tosym);
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001550 free(prl_from);
1551 free(prl_to);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001552 break;
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001553 case ANY_INIT_TO_ANY_EXIT:
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001554 prl_from = sec2annotation(fromsec);
1555 prl_to = sec2annotation(tosec);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001556 fprintf(stderr,
1557 "The %s %s%s%s references\n"
1558 "a %s %s%s%s.\n"
1559 "This is often seen when error handling "
1560 "in the init function\n"
1561 "uses functionality in the exit path.\n"
1562 "The fix is often to remove the %sannotation of\n"
1563 "%s%s so it may be used outside an exit section.\n",
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001564 from, prl_from, fromsym, from_p,
1565 to, prl_to, tosym, to_p,
Andrew Morton5003bab2010-08-11 00:42:26 -07001566 prl_to, tosym, to_p);
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001567 free(prl_from);
1568 free(prl_to);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001569 break;
Uwe Kleine-Königbbd3f4f2010-01-30 16:35:47 +01001570 case ANY_EXIT_TO_ANY_INIT:
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001571 prl_from = sec2annotation(fromsec);
1572 prl_to = sec2annotation(tosec);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001573 fprintf(stderr,
1574 "The %s %s%s%s references\n"
1575 "a %s %s%s%s.\n"
1576 "This is often seen when error handling "
1577 "in the exit function\n"
1578 "uses functionality in the init path.\n"
1579 "The fix is often to remove the %sannotation of\n"
1580 "%s%s so it may be used outside an init section.\n",
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001581 from, prl_from, fromsym, from_p,
1582 to, prl_to, tosym, to_p,
1583 prl_to, tosym, to_p);
1584 free(prl_from);
1585 free(prl_to);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001586 break;
1587 case EXPORT_TO_INIT_EXIT:
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001588 prl_to = sec2annotation(tosec);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001589 fprintf(stderr,
1590 "The symbol %s is exported and annotated %s\n"
1591 "Fix this by removing the %sannotation of %s "
1592 "or drop the export.\n",
Alexey Fomenko37ed19d2010-08-09 17:20:24 -07001593 tosym, prl_to, prl_to, tosym);
1594 free(prl_to);
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001595 break;
Quentin Casasnovas52dc0592015-04-13 20:52:53 +09301596 case EXTABLE_TO_NON_TEXT:
1597 fatal("There's a special handler for this mismatch type, "
1598 "we should never get here.");
1599 break;
Sam Ravnborg588ccd72008-01-24 21:12:37 +01001600 }
1601 fprintf(stderr, "\n");
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001602}
1603
Quentin Casasnovas644e8f12015-04-13 20:43:17 +09301604static void default_mismatch_handler(const char *modname, struct elf_info *elf,
1605 const struct sectioncheck* const mismatch,
1606 Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
1607{
1608 const char *tosec;
1609 Elf_Sym *to;
1610 Elf_Sym *from;
1611 const char *tosym;
1612 const char *fromsym;
1613
Quentin Casasnovas644e8f12015-04-13 20:43:17 +09301614 from = find_elf_symbol2(elf, r->r_offset, fromsec);
1615 fromsym = sym_name(elf, from);
Quentin Casasnovas644e8f12015-04-13 20:43:17 +09301616
Masahiro Yamadad62c4762018-05-09 18:50:38 +09001617 if (strstarts(fromsym, "reference___initcall"))
Quentin Casasnovas644e8f12015-04-13 20:43:17 +09301618 return;
1619
Quentin Casasnovasc7a65e02015-04-13 20:43:45 +09301620 tosec = sec_name(elf, get_secindex(elf, sym));
1621 to = find_elf_symbol(elf, r->r_addend, sym);
1622 tosym = sym_name(elf, to);
1623
Quentin Casasnovas644e8f12015-04-13 20:43:17 +09301624 /* check whitelist - we may ignore it */
1625 if (secref_whitelist(mismatch,
1626 fromsec, fromsym, tosec, tosym)) {
1627 report_sec_mismatch(modname, mismatch,
1628 fromsec, r->r_offset, fromsym,
1629 is_function(from), tosec, tosym,
1630 is_function(to));
1631 }
1632}
1633
Quentin Casasnovas52dc0592015-04-13 20:52:53 +09301634static int is_executable_section(struct elf_info* elf, unsigned int section_index)
1635{
1636 if (section_index > elf->num_sections)
1637 fatal("section_index is outside elf->num_sections!\n");
1638
1639 return ((elf->sechdrs[section_index].sh_flags & SHF_EXECINSTR) == SHF_EXECINSTR);
1640}
1641
1642/*
1643 * We rely on a gross hack in section_rel[a]() calling find_extable_entry_size()
1644 * to know the sizeof(struct exception_table_entry) for the target architecture.
1645 */
1646static unsigned int extable_entry_size = 0;
Quentin Casasnovase84048a2015-04-16 13:05:36 +09301647static void find_extable_entry_size(const char* const sec, const Elf_Rela* r)
Quentin Casasnovas52dc0592015-04-13 20:52:53 +09301648{
1649 /*
1650 * If we're currently checking the second relocation within __ex_table,
1651 * that relocation offset tells us the offsetof(struct
1652 * exception_table_entry, fixup) which is equal to sizeof(struct
1653 * exception_table_entry) divided by two. We use that to our advantage
1654 * since there's no portable way to get that size as every architecture
1655 * seems to go with different sized types. Not pretty but better than
1656 * hard-coding the size for every architecture..
1657 */
Quentin Casasnovase84048a2015-04-16 13:05:36 +09301658 if (!extable_entry_size)
Quentin Casasnovas52dc0592015-04-13 20:52:53 +09301659 extable_entry_size = r->r_offset * 2;
1660}
Quentin Casasnovase84048a2015-04-16 13:05:36 +09301661
Quentin Casasnovas52dc0592015-04-13 20:52:53 +09301662static inline bool is_extable_fault_address(Elf_Rela *r)
1663{
Quentin Casasnovasd3df4de2015-04-16 13:03:32 +09301664 /*
1665 * extable_entry_size is only discovered after we've handled the
1666 * _second_ relocation in __ex_table, so only abort when we're not
1667 * handling the first reloc and extable_entry_size is zero.
1668 */
1669 if (r->r_offset && extable_entry_size == 0)
Quentin Casasnovas52dc0592015-04-13 20:52:53 +09301670 fatal("extable_entry size hasn't been discovered!\n");
1671
1672 return ((r->r_offset == 0) ||
1673 (r->r_offset % extable_entry_size == 0));
1674}
1675
Quentin Casasnovase84048a2015-04-16 13:05:36 +09301676#define is_second_extable_reloc(Start, Cur, Sec) \
1677 (((Cur) == (Start) + 1) && (strcmp("__ex_table", (Sec)) == 0))
1678
Quentin Casasnovas52dc0592015-04-13 20:52:53 +09301679static void report_extable_warnings(const char* modname, struct elf_info* elf,
1680 const struct sectioncheck* const mismatch,
1681 Elf_Rela* r, Elf_Sym* sym,
1682 const char* fromsec, const char* tosec)
1683{
1684 Elf_Sym* fromsym = find_elf_symbol2(elf, r->r_offset, fromsec);
1685 const char* fromsym_name = sym_name(elf, fromsym);
1686 Elf_Sym* tosym = find_elf_symbol(elf, r->r_addend, sym);
1687 const char* tosym_name = sym_name(elf, tosym);
1688 const char* from_pretty_name;
1689 const char* from_pretty_name_p;
1690 const char* to_pretty_name;
1691 const char* to_pretty_name_p;
1692
1693 get_pretty_name(is_function(fromsym),
1694 &from_pretty_name, &from_pretty_name_p);
1695 get_pretty_name(is_function(tosym),
1696 &to_pretty_name, &to_pretty_name_p);
1697
1698 warn("%s(%s+0x%lx): Section mismatch in reference"
1699 " from the %s %s%s to the %s %s:%s%s\n",
1700 modname, fromsec, (long)r->r_offset, from_pretty_name,
1701 fromsym_name, from_pretty_name_p,
1702 to_pretty_name, tosec, tosym_name, to_pretty_name_p);
1703
1704 if (!match(tosec, mismatch->bad_tosec) &&
1705 is_executable_section(elf, get_secindex(elf, sym)))
1706 fprintf(stderr,
1707 "The relocation at %s+0x%lx references\n"
1708 "section \"%s\" which is not in the list of\n"
1709 "authorized sections. If you're adding a new section\n"
1710 "and/or if this reference is valid, add \"%s\" to the\n"
1711 "list of authorized sections to jump to on fault.\n"
1712 "This can be achieved by adding \"%s\" to \n"
1713 "OTHER_TEXT_SECTIONS in scripts/mod/modpost.c.\n",
1714 fromsec, (long)r->r_offset, tosec, tosec, tosec);
1715}
1716
1717static void extable_mismatch_handler(const char* modname, struct elf_info *elf,
1718 const struct sectioncheck* const mismatch,
1719 Elf_Rela* r, Elf_Sym* sym,
1720 const char *fromsec)
1721{
1722 const char* tosec = sec_name(elf, get_secindex(elf, sym));
1723
1724 sec_mismatch_count++;
1725
Masahiro Yamada46c7dd52019-02-01 13:50:45 +09001726 report_extable_warnings(modname, elf, mismatch, r, sym, fromsec, tosec);
Quentin Casasnovas52dc0592015-04-13 20:52:53 +09301727
1728 if (match(tosec, mismatch->bad_tosec))
1729 fatal("The relocation at %s+0x%lx references\n"
1730 "section \"%s\" which is black-listed.\n"
1731 "Something is seriously wrong and should be fixed.\n"
1732 "You might get more information about where this is\n"
1733 "coming from by using scripts/check_extable.sh %s\n",
1734 fromsec, (long)r->r_offset, tosec, modname);
1735 else if (!is_executable_section(elf, get_secindex(elf, sym))) {
1736 if (is_extable_fault_address(r))
1737 fatal("The relocation at %s+0x%lx references\n"
1738 "section \"%s\" which is not executable, IOW\n"
1739 "it is not possible for the kernel to fault\n"
1740 "at that address. Something is seriously wrong\n"
1741 "and should be fixed.\n",
1742 fromsec, (long)r->r_offset, tosec);
1743 else
1744 fatal("The relocation at %s+0x%lx references\n"
1745 "section \"%s\" which is not executable, IOW\n"
1746 "the kernel will fault if it ever tries to\n"
1747 "jump to it. Something is seriously wrong\n"
1748 "and should be fixed.\n",
1749 fromsec, (long)r->r_offset, tosec);
1750 }
1751}
1752
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001753static void check_section_mismatch(const char *modname, struct elf_info *elf,
Masahiro Yamadabb66fc62014-06-10 19:08:13 +09001754 Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001755{
Luis de Bethencourt0cad61d2018-01-16 13:21:29 +00001756 const char *tosec = sec_name(elf, get_secindex(elf, sym));
Quentin Casasnovas644e8f12015-04-13 20:43:17 +09301757 const struct sectioncheck *mismatch = section_mismatch(fromsec, tosec);
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001758
Uwe Kleine-König0d2a6362010-01-30 16:56:20 +01001759 if (mismatch) {
Quentin Casasnovas644e8f12015-04-13 20:43:17 +09301760 if (mismatch->handler)
1761 mismatch->handler(modname, elf, mismatch,
1762 r, sym, fromsec);
1763 else
1764 default_mismatch_handler(modname, elf, mismatch,
1765 r, sym, fromsec);
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001766 }
1767}
1768
Atsushi Nemotoae4ac122007-05-22 18:27:39 +09001769static unsigned int *reloc_location(struct elf_info *elf,
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001770 Elf_Shdr *sechdr, Elf_Rela *r)
Atsushi Nemotoae4ac122007-05-22 18:27:39 +09001771{
1772 Elf_Shdr *sechdrs = elf->sechdrs;
Anders Kaseorg68457562011-05-19 16:55:27 -06001773 int section = sechdr->sh_info;
Atsushi Nemotoae4ac122007-05-22 18:27:39 +09001774
1775 return (void *)elf->hdr + sechdrs[section].sh_offset +
Olof Johansson731ece42010-12-10 02:09:23 -06001776 r->r_offset;
Atsushi Nemotoae4ac122007-05-22 18:27:39 +09001777}
1778
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001779static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
Atsushi Nemotoae4ac122007-05-22 18:27:39 +09001780{
1781 unsigned int r_typ = ELF_R_TYPE(r->r_info);
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001782 unsigned int *location = reloc_location(elf, sechdr, r);
Atsushi Nemotoae4ac122007-05-22 18:27:39 +09001783
1784 switch (r_typ) {
1785 case R_386_32:
1786 r->r_addend = TO_NATIVE(*location);
1787 break;
1788 case R_386_PC32:
1789 r->r_addend = TO_NATIVE(*location) + 4;
1790 /* For CONFIG_RELOCATABLE=y */
1791 if (elf->hdr->e_type == ET_EXEC)
1792 r->r_addend += r->r_offset;
1793 break;
1794 }
1795 return 0;
1796}
1797
Tony Lindgren6e2e3402012-02-14 21:58:56 +01001798#ifndef R_ARM_CALL
1799#define R_ARM_CALL 28
1800#endif
1801#ifndef R_ARM_JUMP24
1802#define R_ARM_JUMP24 29
1803#endif
1804
David A. Longc9698e52014-02-14 22:41:18 +01001805#ifndef R_ARM_THM_CALL
1806#define R_ARM_THM_CALL 10
1807#endif
1808#ifndef R_ARM_THM_JUMP24
1809#define R_ARM_THM_JUMP24 30
1810#endif
1811#ifndef R_ARM_THM_JUMP19
1812#define R_ARM_THM_JUMP19 51
1813#endif
1814
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001815static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
Sam Ravnborg56a974f2007-07-16 22:39:35 +02001816{
1817 unsigned int r_typ = ELF_R_TYPE(r->r_info);
1818
1819 switch (r_typ) {
1820 case R_ARM_ABS32:
1821 /* From ARM ABI: (S + A) | T */
Sam Ravnborgdf578e72008-01-11 19:17:15 +01001822 r->r_addend = (int)(long)
Masahiro Yamadabb66fc62014-06-10 19:08:13 +09001823 (elf->symtab_start + ELF_R_SYM(r->r_info));
Sam Ravnborg56a974f2007-07-16 22:39:35 +02001824 break;
1825 case R_ARM_PC24:
Tony Lindgren6e2e3402012-02-14 21:58:56 +01001826 case R_ARM_CALL:
1827 case R_ARM_JUMP24:
David A. Longc9698e52014-02-14 22:41:18 +01001828 case R_ARM_THM_CALL:
1829 case R_ARM_THM_JUMP24:
1830 case R_ARM_THM_JUMP19:
Sam Ravnborg56a974f2007-07-16 22:39:35 +02001831 /* From ARM ABI: ((S + A) | T) - P */
Sam Ravnborgdf578e72008-01-11 19:17:15 +01001832 r->r_addend = (int)(long)(elf->hdr +
Masahiro Yamadabb66fc62014-06-10 19:08:13 +09001833 sechdr->sh_offset +
1834 (r->r_offset - sechdr->sh_addr));
Sam Ravnborg56a974f2007-07-16 22:39:35 +02001835 break;
1836 default:
1837 return 1;
1838 }
1839 return 0;
1840}
1841
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001842static int addend_mips_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
Atsushi Nemotoae4ac122007-05-22 18:27:39 +09001843{
1844 unsigned int r_typ = ELF_R_TYPE(r->r_info);
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001845 unsigned int *location = reloc_location(elf, sechdr, r);
Atsushi Nemotoae4ac122007-05-22 18:27:39 +09001846 unsigned int inst;
1847
1848 if (r_typ == R_MIPS_HI16)
1849 return 1; /* skip this */
1850 inst = TO_NATIVE(*location);
1851 switch (r_typ) {
1852 case R_MIPS_LO16:
1853 r->r_addend = inst & 0xffff;
1854 break;
1855 case R_MIPS_26:
1856 r->r_addend = (inst & 0x03ffffff) << 2;
1857 break;
1858 case R_MIPS_32:
1859 r->r_addend = inst;
1860 break;
1861 }
1862 return 0;
1863}
1864
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001865static void section_rela(const char *modname, struct elf_info *elf,
Masahiro Yamadabb66fc62014-06-10 19:08:13 +09001866 Elf_Shdr *sechdr)
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001867{
1868 Elf_Sym *sym;
1869 Elf_Rela *rela;
1870 Elf_Rela r;
1871 unsigned int r_sym;
1872 const char *fromsec;
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001873
Sam Ravnborgff13f922008-01-23 19:54:27 +01001874 Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset;
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001875 Elf_Rela *stop = (void *)start + sechdr->sh_size;
1876
Sam Ravnborgff13f922008-01-23 19:54:27 +01001877 fromsec = sech_name(elf, sechdr);
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001878 fromsec += strlen(".rela");
1879 /* if from section (name) is know good then skip it */
Anders Kaseorgb614a692009-04-23 16:49:33 -04001880 if (match(fromsec, section_white_list))
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001881 return;
Sam Ravnborge241a632008-01-28 20:13:13 +01001882
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001883 for (rela = start; rela < stop; rela++) {
1884 r.r_offset = TO_NATIVE(rela->r_offset);
1885#if KERNEL_ELFCLASS == ELFCLASS64
Sam Ravnborgff13f922008-01-23 19:54:27 +01001886 if (elf->hdr->e_machine == EM_MIPS) {
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001887 unsigned int r_typ;
1888 r_sym = ELF64_MIPS_R_SYM(rela->r_info);
1889 r_sym = TO_NATIVE(r_sym);
1890 r_typ = ELF64_MIPS_R_TYPE(rela->r_info);
1891 r.r_info = ELF64_R_INFO(r_sym, r_typ);
1892 } else {
1893 r.r_info = TO_NATIVE(rela->r_info);
1894 r_sym = ELF_R_SYM(r.r_info);
1895 }
1896#else
1897 r.r_info = TO_NATIVE(rela->r_info);
1898 r_sym = ELF_R_SYM(r.r_info);
1899#endif
1900 r.r_addend = TO_NATIVE(rela->r_addend);
1901 sym = elf->symtab_start + r_sym;
1902 /* Skip special sections */
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +02001903 if (is_shndx_special(sym->st_shndx))
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001904 continue;
Quentin Casasnovase84048a2015-04-16 13:05:36 +09301905 if (is_second_extable_reloc(start, rela, fromsec))
1906 find_extable_entry_size(fromsec, &r);
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001907 check_section_mismatch(modname, elf, &r, sym, fromsec);
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001908 }
1909}
1910
1911static void section_rel(const char *modname, struct elf_info *elf,
Masahiro Yamadabb66fc62014-06-10 19:08:13 +09001912 Elf_Shdr *sechdr)
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001913{
1914 Elf_Sym *sym;
1915 Elf_Rel *rel;
1916 Elf_Rela r;
1917 unsigned int r_sym;
1918 const char *fromsec;
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001919
Sam Ravnborgff13f922008-01-23 19:54:27 +01001920 Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset;
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001921 Elf_Rel *stop = (void *)start + sechdr->sh_size;
1922
Sam Ravnborgff13f922008-01-23 19:54:27 +01001923 fromsec = sech_name(elf, sechdr);
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001924 fromsec += strlen(".rel");
1925 /* if from section (name) is know good then skip it */
Anders Kaseorgb614a692009-04-23 16:49:33 -04001926 if (match(fromsec, section_white_list))
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001927 return;
1928
1929 for (rel = start; rel < stop; rel++) {
1930 r.r_offset = TO_NATIVE(rel->r_offset);
1931#if KERNEL_ELFCLASS == ELFCLASS64
Sam Ravnborgff13f922008-01-23 19:54:27 +01001932 if (elf->hdr->e_machine == EM_MIPS) {
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001933 unsigned int r_typ;
1934 r_sym = ELF64_MIPS_R_SYM(rel->r_info);
1935 r_sym = TO_NATIVE(r_sym);
1936 r_typ = ELF64_MIPS_R_TYPE(rel->r_info);
1937 r.r_info = ELF64_R_INFO(r_sym, r_typ);
1938 } else {
1939 r.r_info = TO_NATIVE(rel->r_info);
1940 r_sym = ELF_R_SYM(r.r_info);
1941 }
1942#else
1943 r.r_info = TO_NATIVE(rel->r_info);
1944 r_sym = ELF_R_SYM(r.r_info);
1945#endif
1946 r.r_addend = 0;
Sam Ravnborgff13f922008-01-23 19:54:27 +01001947 switch (elf->hdr->e_machine) {
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001948 case EM_386:
1949 if (addend_386_rel(elf, sechdr, &r))
1950 continue;
1951 break;
1952 case EM_ARM:
1953 if (addend_arm_rel(elf, sechdr, &r))
1954 continue;
1955 break;
1956 case EM_MIPS:
1957 if (addend_mips_rel(elf, sechdr, &r))
1958 continue;
1959 break;
1960 }
1961 sym = elf->symtab_start + r_sym;
1962 /* Skip special sections */
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +02001963 if (is_shndx_special(sym->st_shndx))
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001964 continue;
Quentin Casasnovase84048a2015-04-16 13:05:36 +09301965 if (is_second_extable_reloc(start, rel, fromsec))
1966 find_extable_entry_size(fromsec, &r);
Sam Ravnborg58fb0d42008-01-23 21:13:50 +01001967 check_section_mismatch(modname, elf, &r, sym, fromsec);
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001968 }
1969}
1970
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001971/**
1972 * A module includes a number of sections that are discarded
1973 * either when loaded or when used as built-in.
1974 * For loaded modules all functions marked __init and all data
Uwe Kleine-Königb5950762010-11-01 15:38:34 -04001975 * marked __initdata will be discarded when the module has been initialized.
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001976 * Likewise for modules used built-in the sections marked __exit
1977 * are discarded because __exit marked function are supposed to be called
Ben Dooks32be1d22008-07-29 22:33:44 -07001978 * only when a module is unloaded which never happens for built-in modules.
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001979 * The check_sec_ref() function traverses all relocation records
1980 * to find all references to a section that reference a section that will
1981 * be discarded and warns about it.
1982 **/
1983static void check_sec_ref(struct module *mod, const char *modname,
Masahiro Yamadabb66fc62014-06-10 19:08:13 +09001984 struct elf_info *elf)
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001985{
1986 int i;
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001987 Elf_Shdr *sechdrs = elf->sechdrs;
Sam Ravnborg62070fa2006-03-03 16:46:04 +01001988
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001989 /* Walk through all sections */
Denys Vlasenko1ce53ad2010-07-29 01:47:53 +02001990 for (i = 0; i < elf->num_sections; i++) {
Anders Kaseorgb614a692009-04-23 16:49:33 -04001991 check_section(modname, elf, &elf->sechdrs[i]);
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001992 /* We want to process only relocation sections and not .init */
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001993 if (sechdrs[i].sh_type == SHT_RELA)
Sam Ravnborg10668222008-01-13 22:21:31 +01001994 section_rela(modname, elf, &elf->sechdrs[i]);
Sam Ravnborg5b24c072008-01-18 21:49:29 +01001995 else if (sechdrs[i].sh_type == SHT_REL)
Sam Ravnborg10668222008-01-13 22:21:31 +01001996 section_rel(modname, elf, &elf->sechdrs[i]);
Sam Ravnborgb39927c2006-02-17 22:42:02 +01001997 }
1998}
1999
Andi Kleen7d02b492014-02-08 09:01:12 +01002000static char *remove_dot(char *s)
2001{
Michal Nazarewiczfcd38ed2014-07-27 07:27:01 +09302002 size_t n = strcspn(s, ".");
Andi Kleen7d02b492014-02-08 09:01:12 +01002003
Michal Nazarewiczfcd38ed2014-07-27 07:27:01 +09302004 if (n && s[n]) {
2005 size_t m = strspn(s + n + 1, "0123456789");
2006 if (m && (s[n + m] == '.' || s[n + m] == 0))
Andi Kleen7d02b492014-02-08 09:01:12 +01002007 s[n] = 0;
2008 }
2009 return s;
2010}
2011
Masahiro Yamada8b185742018-05-09 18:50:40 +09002012static void read_symbols(const char *modname)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002013{
2014 const char *symname;
2015 char *version;
Sam Ravnborgb817f6f2006-06-09 21:53:55 +02002016 char *license;
Matthias Maennichcb9b55d2019-09-06 11:32:28 +01002017 char *namespace;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002018 struct module *mod;
2019 struct elf_info info = { };
2020 Elf_Sym *sym;
2021
Sam Ravnborg85bd2fd2007-02-26 15:33:52 +01002022 if (!parse_elf(&info, modname))
2023 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002024
2025 mod = new_module(modname);
2026
2027 /* When there's no vmlinux, don't print warnings about
2028 * unresolved symbols (since there'll be too many ;) */
2029 if (is_vmlinux(modname)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002030 have_vmlinux = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002031 mod->skip = 1;
2032 }
2033
Masahiro Yamadabca2cce2018-05-09 18:50:37 +09002034 license = get_modinfo(&info, "license");
Randy Dunlapba1029c2017-11-12 11:21:45 -08002035 if (!license && !is_vmlinux(modname))
Sam Ravnborg2fa36562008-04-26 21:07:26 +02002036 warn("modpost: missing MODULE_LICENSE() in %s\n"
2037 "see include/linux/module.h for "
2038 "more information\n", modname);
Sam Ravnborgb817f6f2006-06-09 21:53:55 +02002039 while (license) {
2040 if (license_is_gpl_compatible(license))
2041 mod->gpl_compatible = 1;
2042 else {
2043 mod->gpl_compatible = 0;
2044 break;
2045 }
Masahiro Yamadabca2cce2018-05-09 18:50:37 +09002046 license = get_next_modinfo(&info, "license", license);
Sam Ravnborgb817f6f2006-06-09 21:53:55 +02002047 }
2048
Matthias Maennichcb9b55d2019-09-06 11:32:28 +01002049 namespace = get_modinfo(&info, "import_ns");
2050 while (namespace) {
2051 add_namespace(&mod->imported_namespaces, namespace);
2052 namespace = get_next_modinfo(&info, "import_ns", namespace);
2053 }
2054
Linus Torvalds1da177e2005-04-16 15:20:36 -07002055 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
Andi Kleen7d02b492014-02-08 09:01:12 +01002056 symname = remove_dot(info.strtab + sym->st_name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002057
2058 handle_modversions(mod, &info, sym, symname);
2059 handle_moddevtable(mod, &info, sym, symname);
2060 }
Denis Efremov15bfc232019-08-01 09:06:57 +03002061
Matthias Maennich69923202019-10-18 10:31:42 +01002062 /* Apply symbol namespaces from __kstrtabns_<symbol> entries. */
2063 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
2064 symname = remove_dot(info.strtab + sym->st_name);
2065
2066 if (strstarts(symname, "__kstrtabns_"))
2067 sym_update_namespace(symname + strlen("__kstrtabns_"),
2068 namespace_from_kstrtabns(&info,
2069 sym));
2070 }
2071
Denis Efremov15bfc232019-08-01 09:06:57 +03002072 // check for static EXPORT_SYMBOL_* functions && global vars
2073 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
2074 unsigned char bind = ELF_ST_BIND(sym->st_info);
2075
2076 if (bind == STB_GLOBAL || bind == STB_WEAK) {
2077 struct symbol *s =
2078 find_symbol(remove_dot(info.strtab +
2079 sym->st_name));
2080
2081 if (s)
2082 s->is_static = 0;
2083 }
2084 }
2085
Masahiro Yamada074a04f2018-05-09 18:50:39 +09002086 if (!is_vmlinux(modname) || vmlinux_section_warnings)
Sam Ravnborg10668222008-01-13 22:21:31 +01002087 check_sec_ref(mod, modname, &info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002088
Masahiro Yamadabca2cce2018-05-09 18:50:37 +09002089 version = get_modinfo(&info, "version");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002090 if (version)
2091 maybe_frob_rcs_version(modname, version, info.modinfo,
2092 version - (char *)info.hdr);
2093 if (version || (all_versions && !is_vmlinux(modname)))
2094 get_src_version(modname, mod->srcversion,
2095 sizeof(mod->srcversion)-1);
2096
2097 parse_elf_finish(&info);
2098
Rusty Russell8c8ef422009-03-31 13:05:34 -06002099 /* Our trick to get versioning for module struct etc. - it's
Linus Torvalds1da177e2005-04-16 15:20:36 -07002100 * never passed as an argument to an exported function, so
2101 * the automatic versioning doesn't pick it up, but it's really
2102 * important anyhow */
2103 if (modversions)
Rusty Russell8c8ef422009-03-31 13:05:34 -06002104 mod->unres = alloc_symbol("module_layout", 0, mod->unres);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002105}
2106
Rusty Russell712f9b42013-04-04 17:37:38 +10302107static void read_symbols_from_files(const char *filename)
2108{
2109 FILE *in = stdin;
2110 char fname[PATH_MAX];
2111
2112 if (strcmp(filename, "-") != 0) {
2113 in = fopen(filename, "r");
2114 if (!in)
2115 fatal("Can't open filenames file %s: %m", filename);
2116 }
2117
2118 while (fgets(fname, PATH_MAX, in) != NULL) {
2119 if (strends(fname, "\n"))
2120 fname[strlen(fname)-1] = '\0';
2121 read_symbols(fname);
2122 }
2123
2124 if (in != stdin)
2125 fclose(in);
2126}
2127
Linus Torvalds1da177e2005-04-16 15:20:36 -07002128#define SZ 500
2129
2130/* We first write the generated file into memory using the
2131 * following helper, then compare to the file on disk and
2132 * only update the later if anything changed */
2133
Sam Ravnborg5c3ead82006-01-28 17:19:35 +01002134void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf,
2135 const char *fmt, ...)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002136{
2137 char tmp[SZ];
2138 int len;
2139 va_list ap;
Sam Ravnborg62070fa2006-03-03 16:46:04 +01002140
Linus Torvalds1da177e2005-04-16 15:20:36 -07002141 va_start(ap, fmt);
2142 len = vsnprintf(tmp, SZ, fmt, ap);
Sam Ravnborg7670f022006-03-16 23:04:08 -08002143 buf_write(buf, tmp, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002144 va_end(ap);
2145}
2146
Sam Ravnborg5c3ead82006-01-28 17:19:35 +01002147void buf_write(struct buffer *buf, const char *s, int len)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002148{
2149 if (buf->size - buf->pos < len) {
Sam Ravnborg7670f022006-03-16 23:04:08 -08002150 buf->size += len + SZ;
Randy Dunlap1f3aa902018-08-15 12:30:38 -07002151 buf->p = NOFAIL(realloc(buf->p, buf->size));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002152 }
2153 strncpy(buf->p + buf->pos, s, len);
2154 buf->pos += len;
2155}
2156
Sam Ravnborgc96fca22006-07-01 11:44:23 +02002157static void check_for_gpl_usage(enum export exp, const char *m, const char *s)
2158{
2159 const char *e = is_vmlinux(m) ?"":".ko";
2160
2161 switch (exp) {
2162 case export_gpl:
2163 fatal("modpost: GPL-incompatible module %s%s "
2164 "uses GPL-only symbol '%s'\n", m, e, s);
2165 break;
2166 case export_unused_gpl:
2167 fatal("modpost: GPL-incompatible module %s%s "
2168 "uses GPL-only symbol marked UNUSED '%s'\n", m, e, s);
2169 break;
2170 case export_gpl_future:
2171 warn("modpost: GPL-incompatible module %s%s "
2172 "uses future GPL-only symbol '%s'\n", m, e, s);
2173 break;
2174 case export_plain:
2175 case export_unused:
2176 case export_unknown:
2177 /* ignore */
2178 break;
2179 }
2180}
2181
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002182static void check_for_unused(enum export exp, const char *m, const char *s)
Sam Ravnborgc96fca22006-07-01 11:44:23 +02002183{
2184 const char *e = is_vmlinux(m) ?"":".ko";
2185
2186 switch (exp) {
2187 case export_unused:
2188 case export_unused_gpl:
2189 warn("modpost: module %s%s "
2190 "uses symbol '%s' marked UNUSED\n", m, e, s);
2191 break;
2192 default:
2193 /* ignore */
2194 break;
2195 }
2196}
2197
Masahiro Yamada3b415282018-11-23 16:57:23 +09002198static int check_exports(struct module *mod)
Sam Ravnborgb817f6f2006-06-09 21:53:55 +02002199{
2200 struct symbol *s, *exp;
Masahiro Yamada3b415282018-11-23 16:57:23 +09002201 int err = 0;
Sam Ravnborgb817f6f2006-06-09 21:53:55 +02002202
2203 for (s = mod->unres; s; s = s->next) {
Andrew Morton6449bd62006-06-09 20:45:06 -07002204 const char *basename;
Sam Ravnborgb817f6f2006-06-09 21:53:55 +02002205 exp = find_symbol(s->name);
Masahiro Yamada3b415282018-11-23 16:57:23 +09002206 if (!exp || exp->module == mod) {
2207 if (have_vmlinux && !s->weak) {
2208 if (warn_unresolved) {
2209 warn("\"%s\" [%s.ko] undefined!\n",
2210 s->name, mod->name);
2211 } else {
2212 merror("\"%s\" [%s.ko] undefined!\n",
2213 s->name, mod->name);
2214 err = 1;
2215 }
2216 }
Sam Ravnborgb817f6f2006-06-09 21:53:55 +02002217 continue;
Masahiro Yamada3b415282018-11-23 16:57:23 +09002218 }
Andrew Morton6449bd62006-06-09 20:45:06 -07002219 basename = strrchr(mod->name, '/');
Sam Ravnborgb817f6f2006-06-09 21:53:55 +02002220 if (basename)
2221 basename++;
Sam Ravnborgc96fca22006-07-01 11:44:23 +02002222 else
2223 basename = mod->name;
Matthias Maennichcb9b55d2019-09-06 11:32:28 +01002224
Masahiro Yamadabbc55bd2019-10-29 21:38:07 +09002225 if (exp->namespace &&
2226 !module_imports_namespace(mod, exp->namespace)) {
2227 warn("module %s uses symbol %s from namespace %s, but does not import it.\n",
2228 basename, exp->name, exp->namespace);
2229 add_namespace(&mod->missing_namespaces, exp->namespace);
Matthias Maennichcb9b55d2019-09-06 11:32:28 +01002230 }
2231
Sam Ravnborgc96fca22006-07-01 11:44:23 +02002232 if (!mod->gpl_compatible)
2233 check_for_gpl_usage(exp->export, basename, exp->name);
2234 check_for_unused(exp->export, basename, exp->name);
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002235 }
Masahiro Yamada3b415282018-11-23 16:57:23 +09002236
2237 return err;
Sam Ravnborgb817f6f2006-06-09 21:53:55 +02002238}
2239
Wanlong Gao4fd3e4e2017-06-30 22:07:03 +08002240static int check_modname_len(struct module *mod)
2241{
2242 const char *mod_name;
2243
2244 mod_name = strrchr(mod->name, '/');
2245 if (mod_name == NULL)
2246 mod_name = mod->name;
2247 else
2248 mod_name++;
2249 if (strlen(mod_name) >= MODULE_NAME_LEN) {
2250 merror("module name is too long [%s.ko]\n", mod->name);
2251 return 1;
2252 }
2253
2254 return 0;
2255}
2256
Sam Ravnborg5c3ead82006-01-28 17:19:35 +01002257/**
2258 * Header for the generated file
2259 **/
2260static void add_header(struct buffer *b, struct module *mod)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002261{
Laura Abbott9afb7192018-07-05 17:49:37 -07002262 buf_printf(b, "#include <linux/build-salt.h>\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002263 buf_printf(b, "#include <linux/module.h>\n");
2264 buf_printf(b, "#include <linux/vermagic.h>\n");
2265 buf_printf(b, "#include <linux/compiler.h>\n");
2266 buf_printf(b, "\n");
Laura Abbott9afb7192018-07-05 17:49:37 -07002267 buf_printf(b, "BUILD_SALT;\n");
2268 buf_printf(b, "\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002269 buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
Kees Cook3e2e8572017-04-21 15:35:27 -07002270 buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002271 buf_printf(b, "\n");
Andi Kleene0f244c2013-10-23 10:57:58 +10302272 buf_printf(b, "__visible struct module __this_module\n");
Masahiro Yamadaa3d0cb02019-09-09 20:34:23 +09002273 buf_printf(b, "__section(.gnu.linkonce.this_module) = {\n");
Greg Kroah-Hartman3c7ec942012-04-25 11:10:15 -07002274 buf_printf(b, "\t.name = KBUILD_MODNAME,\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002275 if (mod->has_init)
Greg Kroah-Hartman3c7ec942012-04-25 11:10:15 -07002276 buf_printf(b, "\t.init = init_module,\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002277 if (mod->has_cleanup)
2278 buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n"
Greg Kroah-Hartman3c7ec942012-04-25 11:10:15 -07002279 "\t.exit = cleanup_module,\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -07002280 "#endif\n");
Greg Kroah-Hartman3c7ec942012-04-25 11:10:15 -07002281 buf_printf(b, "\t.arch = MODULE_ARCH_INIT,\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002282 buf_printf(b, "};\n");
2283}
2284
Ben Hutchings2449b8b2011-10-24 15:12:28 +02002285static void add_intree_flag(struct buffer *b, int is_intree)
2286{
2287 if (is_intree)
2288 buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n");
2289}
2290
Andi Kleencaf75012018-01-25 15:50:28 -08002291/* Cannot check for assembler */
2292static void add_retpoline(struct buffer *b)
2293{
WANG Chaoe4f35892018-12-11 00:37:25 +08002294 buf_printf(b, "\n#ifdef CONFIG_RETPOLINE\n");
Andi Kleencaf75012018-01-25 15:50:28 -08002295 buf_printf(b, "MODULE_INFO(retpoline, \"Y\");\n");
2296 buf_printf(b, "#endif\n");
2297}
2298
Trevor Keith5c725132009-09-22 16:43:38 -07002299static void add_staging_flag(struct buffer *b, const char *name)
Greg Kroah-Hartmana9860bf2008-09-24 14:46:44 -07002300{
Masahiro Yamadad62c4762018-05-09 18:50:38 +09002301 if (strstarts(name, "drivers/staging"))
Greg Kroah-Hartmana9860bf2008-09-24 14:46:44 -07002302 buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
2303}
2304
Sam Ravnborg5c3ead82006-01-28 17:19:35 +01002305/**
2306 * Record CRCs for unresolved symbols
2307 **/
Kirill Korotaevc53ddac2006-09-07 13:08:54 -07002308static int add_versions(struct buffer *b, struct module *mod)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002309{
2310 struct symbol *s, *exp;
Kirill Korotaevc53ddac2006-09-07 13:08:54 -07002311 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002312
2313 for (s = mod->unres; s; s = s->next) {
2314 exp = find_symbol(s->name);
Masahiro Yamada3b415282018-11-23 16:57:23 +09002315 if (!exp || exp->module == mod)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002316 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002317 s->module = exp->module;
2318 s->crc_valid = exp->crc_valid;
2319 s->crc = exp->crc;
2320 }
2321
2322 if (!modversions)
Kirill Korotaevc53ddac2006-09-07 13:08:54 -07002323 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002324
2325 buf_printf(b, "\n");
2326 buf_printf(b, "static const struct modversion_info ____versions[]\n");
Masahiro Yamadaa3d0cb02019-09-09 20:34:23 +09002327 buf_printf(b, "__used __section(__versions) = {\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002328
2329 for (s = mod->unres; s; s = s->next) {
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002330 if (!s->module)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002331 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002332 if (!s->crc_valid) {
Sam Ravnborgcb805142006-01-28 16:57:26 +01002333 warn("\"%s\" [%s.ko] has no CRC!\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002334 s->name, mod->name);
2335 continue;
2336 }
Takashi Iwai5cfb2032015-08-08 15:16:20 +09302337 if (strlen(s->name) >= MODULE_NAME_LEN) {
2338 merror("too long symbol \"%s\" [%s.ko]\n",
2339 s->name, mod->name);
2340 err = 1;
2341 break;
2342 }
Masahiro Yamadab2c5cdc2018-05-09 16:23:45 +09002343 buf_printf(b, "\t{ %#8x, \"%s\" },\n",
James Hogana4b6a772013-03-18 19:38:56 +10302344 s->crc, s->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002345 }
2346
2347 buf_printf(b, "};\n");
Kirill Korotaevc53ddac2006-09-07 13:08:54 -07002348
2349 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002350}
2351
Masahiro Yamadad2665ca2018-11-23 16:57:21 +09002352static void add_depends(struct buffer *b, struct module *mod)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002353{
2354 struct symbol *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002355 int first = 1;
2356
Masahiro Yamadad2665ca2018-11-23 16:57:21 +09002357 /* Clear ->seen flag of modules that own symbols needed by this. */
2358 for (s = mod->unres; s; s = s->next)
2359 if (s->module)
2360 s->module->seen = is_vmlinux(s->module->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002361
2362 buf_printf(b, "\n");
Masahiro Yamada6df7e1e2019-09-09 20:34:22 +09002363 buf_printf(b, "MODULE_INFO(depends, \"");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002364 for (s = mod->unres; s; s = s->next) {
Sam Ravnborga61b2df2007-02-26 19:46:52 +01002365 const char *p;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002366 if (!s->module)
2367 continue;
2368
2369 if (s->module->seen)
2370 continue;
2371
2372 s->module->seen = 1;
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002373 p = strrchr(s->module->name, '/');
2374 if (p)
Sam Ravnborga61b2df2007-02-26 19:46:52 +01002375 p++;
2376 else
2377 p = s->module->name;
2378 buf_printf(b, "%s%s", first ? "" : ",", p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002379 first = 0;
2380 }
Masahiro Yamada6df7e1e2019-09-09 20:34:22 +09002381 buf_printf(b, "\");\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002382}
2383
Sam Ravnborg5c3ead82006-01-28 17:19:35 +01002384static void add_srcversion(struct buffer *b, struct module *mod)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002385{
2386 if (mod->srcversion[0]) {
2387 buf_printf(b, "\n");
2388 buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n",
2389 mod->srcversion);
2390 }
2391}
2392
Sam Ravnborg5c3ead82006-01-28 17:19:35 +01002393static void write_if_changed(struct buffer *b, const char *fname)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002394{
2395 char *tmp;
2396 FILE *file;
2397 struct stat st;
2398
2399 file = fopen(fname, "r");
2400 if (!file)
2401 goto write;
2402
2403 if (fstat(fileno(file), &st) < 0)
2404 goto close_write;
2405
2406 if (st.st_size != b->pos)
2407 goto close_write;
2408
2409 tmp = NOFAIL(malloc(b->pos));
2410 if (fread(tmp, 1, b->pos, file) != b->pos)
2411 goto free_write;
2412
2413 if (memcmp(tmp, b->p, b->pos) != 0)
2414 goto free_write;
2415
2416 free(tmp);
2417 fclose(file);
2418 return;
2419
2420 free_write:
2421 free(tmp);
2422 close_write:
2423 fclose(file);
2424 write:
2425 file = fopen(fname, "w");
2426 if (!file) {
2427 perror(fname);
2428 exit(1);
2429 }
2430 if (fwrite(b->p, 1, b->pos, file) != b->pos) {
2431 perror(fname);
2432 exit(1);
2433 }
2434 fclose(file);
2435}
2436
Ram Paibd5cbce2006-06-08 22:12:53 -07002437/* parse Module.symvers file. line format:
Sam Ravnborg534b89a2006-07-01 10:10:19 +02002438 * 0x12345678<tab>symbol<tab>module[[<tab>export]<tab>something]
Ram Paibd5cbce2006-06-08 22:12:53 -07002439 **/
Sam Ravnborg040fcc82006-01-28 22:15:55 +01002440static void read_dump(const char *fname, unsigned int kernel)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002441{
2442 unsigned long size, pos = 0;
2443 void *file = grab_file(fname, &size);
2444 char *line;
2445
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002446 if (!file)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002447 /* No symbol versions, silently ignore */
2448 return;
2449
2450 while ((line = get_next_line(&pos, file, size))) {
Matthias Maennichcb9b55d2019-09-06 11:32:28 +01002451 char *symname, *namespace, *modname, *d, *export, *end;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002452 unsigned int crc;
2453 struct module *mod;
Sam Ravnborg040fcc82006-01-28 22:15:55 +01002454 struct symbol *s;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002455
2456 if (!(symname = strchr(line, '\t')))
2457 goto fail;
2458 *symname++ = '\0';
Matthias Maennichcb9b55d2019-09-06 11:32:28 +01002459 if (!(namespace = strchr(symname, '\t')))
2460 goto fail;
2461 *namespace++ = '\0';
2462 if (!(modname = strchr(namespace, '\t')))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002463 goto fail;
2464 *modname++ = '\0';
Laurent Riffard9ac545b2006-06-11 08:02:06 +02002465 if ((export = strchr(modname, '\t')) != NULL)
Ram Paibd5cbce2006-06-08 22:12:53 -07002466 *export++ = '\0';
Sam Ravnborg534b89a2006-07-01 10:10:19 +02002467 if (export && ((end = strchr(export, '\t')) != NULL))
2468 *end = '\0';
Linus Torvalds1da177e2005-04-16 15:20:36 -07002469 crc = strtoul(line, &d, 16);
2470 if (*symname == '\0' || *modname == '\0' || *d != '\0')
2471 goto fail;
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002472 mod = find_module(modname);
2473 if (!mod) {
2474 if (is_vmlinux(modname))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002475 have_vmlinux = 1;
Jan Beulich0fa3a882009-03-12 12:28:30 +00002476 mod = new_module(modname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002477 mod->skip = 1;
2478 }
Matthias Maennich9ae5bd12019-10-18 10:31:41 +01002479 s = sym_add_exported(symname, mod, export_no(export));
Sam Ravnborg8e70c452006-01-28 22:22:33 +01002480 s->kernel = kernel;
2481 s->preloaded = 1;
Denis Efremov15bfc232019-08-01 09:06:57 +03002482 s->is_static = 0;
Ram Paibd5cbce2006-06-08 22:12:53 -07002483 sym_update_crc(symname, mod, crc, export_no(export));
Matthias Maennich9ae5bd12019-10-18 10:31:41 +01002484 sym_update_namespace(symname, namespace);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002485 }
Christian Engelmayer2ee41e62014-04-28 11:34:32 +09302486 release_file(file, size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002487 return;
2488fail:
Christian Engelmayer2ee41e62014-04-28 11:34:32 +09302489 release_file(file, size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002490 fatal("parse error in symbol dump file\n");
2491}
2492
Sam Ravnborg040fcc82006-01-28 22:15:55 +01002493/* For normal builds always dump all symbols.
2494 * For external modules only dump symbols
2495 * that are not read from kernel Module.symvers.
2496 **/
2497static int dump_sym(struct symbol *sym)
2498{
2499 if (!external_module)
2500 return 1;
2501 if (sym->vmlinux || sym->kernel)
2502 return 0;
2503 return 1;
2504}
Sam Ravnborg62070fa2006-03-03 16:46:04 +01002505
Sam Ravnborg5c3ead82006-01-28 17:19:35 +01002506static void write_dump(const char *fname)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002507{
2508 struct buffer buf = { };
2509 struct symbol *symbol;
Matthias Maennichcb9b55d2019-09-06 11:32:28 +01002510 const char *namespace;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002511 int n;
2512
2513 for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
2514 symbol = symbolhash[n];
2515 while (symbol) {
Matthias Maennichcb9b55d2019-09-06 11:32:28 +01002516 if (dump_sym(symbol)) {
2517 namespace = symbol->namespace;
2518 buf_printf(&buf, "0x%08x\t%s\t%s\t%s\t%s\n",
2519 symbol->crc, symbol->name,
2520 namespace ? namespace : "",
2521 symbol->module->name,
2522 export_str(symbol->export));
2523 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002524 symbol = symbol->next;
2525 }
2526 }
2527 write_if_changed(&buf, fname);
Heinrich Schuchardtc7d47f22016-08-02 21:43:01 +02002528 free(buf.p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002529}
2530
Masahiro Yamadabbc55bd2019-10-29 21:38:07 +09002531static void write_namespace_deps_files(const char *fname)
Matthias Maennich1d082772019-09-06 11:32:31 +01002532{
2533 struct module *mod;
2534 struct namespace_list *ns;
2535 struct buffer ns_deps_buf = {};
2536
2537 for (mod = modules; mod; mod = mod->next) {
Matthias Maennich1d082772019-09-06 11:32:31 +01002538
Masahiro Yamadabbc55bd2019-10-29 21:38:07 +09002539 if (mod->skip || !mod->missing_namespaces)
Matthias Maennich1d082772019-09-06 11:32:31 +01002540 continue;
2541
Masahiro Yamadabbc55bd2019-10-29 21:38:07 +09002542 buf_printf(&ns_deps_buf, "%s.ko:", mod->name);
Matthias Maennich1d082772019-09-06 11:32:31 +01002543
Masahiro Yamadabbc55bd2019-10-29 21:38:07 +09002544 for (ns = mod->missing_namespaces; ns; ns = ns->next)
2545 buf_printf(&ns_deps_buf, " %s", ns->namespace);
Matthias Maennich1d082772019-09-06 11:32:31 +01002546
Masahiro Yamadabbc55bd2019-10-29 21:38:07 +09002547 buf_printf(&ns_deps_buf, "\n");
Matthias Maennich1d082772019-09-06 11:32:31 +01002548 }
Masahiro Yamada0241ea82019-11-07 00:19:59 +09002549
Masahiro Yamadabbc55bd2019-10-29 21:38:07 +09002550 write_if_changed(&ns_deps_buf, fname);
Masahiro Yamada0241ea82019-11-07 00:19:59 +09002551 free(ns_deps_buf.p);
Matthias Maennich1d082772019-09-06 11:32:31 +01002552}
2553
Richard Hacker2d04b5a2008-02-28 09:40:52 +01002554struct ext_sym_list {
2555 struct ext_sym_list *next;
2556 const char *file;
2557};
2558
Sam Ravnborg5c3ead82006-01-28 17:19:35 +01002559int main(int argc, char **argv)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002560{
2561 struct module *mod;
2562 struct buffer buf = { };
Masahiro Yamada39808e42019-10-03 19:29:14 +09002563 char *kernel_read = NULL;
Masahiro Yamadabbc55bd2019-10-29 21:38:07 +09002564 char *missing_namespace_deps = NULL;
Rusty Russell712f9b42013-04-04 17:37:38 +10302565 char *dump_write = NULL, *files_source = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002566 int opt;
Kirill Korotaevc53ddac2006-09-07 13:08:54 -07002567 int err;
Denis Efremov15bfc232019-08-01 09:06:57 +03002568 int n;
Richard Hacker2d04b5a2008-02-28 09:40:52 +01002569 struct ext_sym_list *extsym_iter;
2570 struct ext_sym_list *extsym_start = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002571
Masahiro Yamadabbc55bd2019-10-29 21:38:07 +09002572 while ((opt = getopt(argc, argv, "i:e:mnsT:o:awEd:")) != -1) {
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002573 switch (opt) {
2574 case 'i':
2575 kernel_read = optarg;
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002576 external_module = 1;
2577 break;
Richard Hacker2d04b5a2008-02-28 09:40:52 +01002578 case 'e':
2579 external_module = 1;
2580 extsym_iter =
2581 NOFAIL(malloc(sizeof(*extsym_iter)));
2582 extsym_iter->next = extsym_start;
2583 extsym_iter->file = optarg;
2584 extsym_start = extsym_iter;
2585 break;
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002586 case 'm':
2587 modversions = 1;
2588 break;
Guenter Roeckeed380f2013-09-23 15:23:54 +09302589 case 'n':
2590 ignore_missing_files = 1;
2591 break;
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002592 case 'o':
2593 dump_write = optarg;
2594 break;
2595 case 'a':
2596 all_versions = 1;
2597 break;
2598 case 's':
2599 vmlinux_section_warnings = 0;
2600 break;
Rusty Russell712f9b42013-04-04 17:37:38 +10302601 case 'T':
2602 files_source = optarg;
2603 break;
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002604 case 'w':
2605 warn_unresolved = 1;
2606 break;
Nicolas Boichat47490ec2015-10-06 09:44:42 +10302607 case 'E':
2608 sec_mismatch_fatal = 1;
2609 break;
Matthias Maennich1d082772019-09-06 11:32:31 +01002610 case 'd':
Masahiro Yamadabbc55bd2019-10-29 21:38:07 +09002611 missing_namespace_deps = optarg;
Matthias Maennich1d082772019-09-06 11:32:31 +01002612 break;
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002613 default:
2614 exit(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002615 }
2616 }
2617
Sam Ravnborg040fcc82006-01-28 22:15:55 +01002618 if (kernel_read)
2619 read_dump(kernel_read, 1);
Richard Hacker2d04b5a2008-02-28 09:40:52 +01002620 while (extsym_start) {
2621 read_dump(extsym_start->file, 0);
2622 extsym_iter = extsym_start->next;
2623 free(extsym_start);
2624 extsym_start = extsym_iter;
2625 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002626
Sam Ravnborgdf578e72008-01-11 19:17:15 +01002627 while (optind < argc)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002628 read_symbols(argv[optind++]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002629
Rusty Russell712f9b42013-04-04 17:37:38 +10302630 if (files_source)
2631 read_symbols_from_files(files_source);
2632
Kirill Korotaevc53ddac2006-09-07 13:08:54 -07002633 err = 0;
2634
Sam Ravnborgb817f6f2006-06-09 21:53:55 +02002635 for (mod = modules; mod; mod = mod->next) {
Mathias Kraused93e1712014-08-27 20:28:56 +09302636 char fname[PATH_MAX];
Andi Kleen666ab412007-11-22 03:43:10 +01002637
Sam Ravnborgb817f6f2006-06-09 21:53:55 +02002638 if (mod->skip)
2639 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002640
2641 buf.pos = 0;
2642
Wanlong Gao4fd3e4e2017-06-30 22:07:03 +08002643 err |= check_modname_len(mod);
Masahiro Yamada3b415282018-11-23 16:57:23 +09002644 err |= check_exports(mod);
Matthias Maennich1d082772019-09-06 11:32:31 +01002645
Linus Torvalds1da177e2005-04-16 15:20:36 -07002646 add_header(&buf, mod);
Ben Hutchings2449b8b2011-10-24 15:12:28 +02002647 add_intree_flag(&buf, !external_module);
Andi Kleencaf75012018-01-25 15:50:28 -08002648 add_retpoline(&buf);
Greg Kroah-Hartmana9860bf2008-09-24 14:46:44 -07002649 add_staging_flag(&buf, mod->name);
Kirill Korotaevc53ddac2006-09-07 13:08:54 -07002650 err |= add_versions(&buf, mod);
Masahiro Yamadad2665ca2018-11-23 16:57:21 +09002651 add_depends(&buf, mod);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002652 add_moddevtable(&buf, mod);
2653 add_srcversion(&buf, mod);
2654
2655 sprintf(fname, "%s.mod.c", mod->name);
2656 write_if_changed(&buf, fname);
2657 }
Matthias Maennich1d082772019-09-06 11:32:31 +01002658
Masahiro Yamadabbc55bd2019-10-29 21:38:07 +09002659 if (missing_namespace_deps)
2660 write_namespace_deps_files(missing_namespace_deps);
Matthias Maennich1d082772019-09-06 11:32:31 +01002661
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662 if (dump_write)
2663 write_dump(dump_write);
Masahiro Yamada46c7dd52019-02-01 13:50:45 +09002664 if (sec_mismatch_count && sec_mismatch_fatal)
2665 fatal("modpost: Section mismatches detected.\n"
2666 "Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n");
Denis Efremov15bfc232019-08-01 09:06:57 +03002667 for (n = 0; n < SYMBOL_HASH_SIZE; n++) {
Masahiro Yamada47346e92019-09-24 21:07:40 +09002668 struct symbol *s;
Denis Efremov15bfc232019-08-01 09:06:57 +03002669
Masahiro Yamada47346e92019-09-24 21:07:40 +09002670 for (s = symbolhash[n]; s; s = s->next) {
2671 /*
2672 * Do not check "vmlinux". This avoids the same warnings
2673 * shown twice, and false-positives for ARCH=um.
2674 */
2675 if (is_vmlinux(s->module->name) && !s->module->is_dot_o)
2676 continue;
2677
Denis Efremov15bfc232019-08-01 09:06:57 +03002678 if (s->is_static)
2679 warn("\"%s\" [%s] is a static %s\n",
2680 s->name, s->module->name,
2681 export_str(s->export));
Denis Efremov15bfc232019-08-01 09:06:57 +03002682 }
2683 }
2684
Heinrich Schuchardtc7d47f22016-08-02 21:43:01 +02002685 free(buf.p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002686
Kirill Korotaevc53ddac2006-09-07 13:08:54 -07002687 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002688}