Blame view

scripts/mod/modpost.c 65.6 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
  /* Postprocess module symbol versions
   *
   * Copyright 2003       Kai Germaschewski
   * Copyright 2002-2004  Rusty Russell, IBM Corporation
df578e7d8   Sam Ravnborg   kbuild: clean up ...
5
   * Copyright 2006-2008  Sam Ravnborg
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6
7
8
9
10
11
12
   * Based in part on module-init-tools/depmod.c,file2alias
   *
   * This software may be used and distributed according to the terms
   * of the GNU General Public License, incorporated herein by reference.
   *
   * Usage: modpost vmlinux module1.o module2.o ...
   */
b2e3e658b   Mathieu Desnoyers   Linux Kernel Mark...
13
14
  #define _GNU_SOURCE
  #include <stdio.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15
  #include <ctype.h>
5003bab82   Andrew Morton   fix "scripts/mod/...
16
  #include <string.h>
712f9b468   Rusty Russell   modpost: add -T o...
17
  #include <limits.h>
d4ef1c30e   Rusty Russell   modpost: minor cl...
18
  #include <stdbool.h>
eed380f3f   Guenter Roeck   modpost: Optional...
19
  #include <errno.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20
  #include "modpost.h"
b817f6fef   Sam Ravnborg   kbuild: check lic...
21
  #include "../../include/linux/license.h"
9e1b9b807   Alan Jenkins   module: make MODU...
22

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
  /* Are we using CONFIG_MODVERSIONS? */
7a3ee7538   Mathias Krause   modpost: reduce v...
24
  static int modversions = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
  /* Warn about undefined symbols? (do so if we have vmlinux) */
7a3ee7538   Mathias Krause   modpost: reduce v...
26
  static int have_vmlinux = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
  /* Is CONFIG_MODULE_SRCVERSION_ALL set? */
  static int all_versions = 0;
040fcc819   Sam Ravnborg   kbuild: improved ...
29
30
  /* If we are modposting external module set to 1 */
  static int external_module = 0;
8d8d8289d   Sam Ravnborg   kbuild: do not do...
31
32
  /* Warn about section mismatch in vmlinux if set to 1 */
  static int vmlinux_section_warnings = 1;
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
33
34
  /* Only warn about unresolved symbols */
  static int warn_unresolved = 0;
bd5cbcedf   Ram Pai   kbuild: export-ty...
35
  /* How a symbol is exported */
588ccd732   Sam Ravnborg   kbuild: add verbo...
36
37
  static int sec_mismatch_count = 0;
  static int sec_mismatch_verbose = 1;
47490ec14   Nicolas Boichat   modpost: Add flag...
38
  static int sec_mismatch_fatal = 0;
eed380f3f   Guenter Roeck   modpost: Optional...
39
40
  /* ignore missing files */
  static int ignore_missing_files;
588ccd732   Sam Ravnborg   kbuild: add verbo...
41

c96fca213   Sam Ravnborg   kbuild: warn when...
42
43
44
45
  enum export {
  	export_plain,      export_unused,     export_gpl,
  	export_unused_gpl, export_gpl_future, export_unknown
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46

4fd3e4ef1   Wanlong Gao   modpost: abort if...
47
48
49
50
51
  /* In kernel, this size is defined in linux/module.h;
   * here we use Elf_Addr instead of long for covering cross-compile
   */
  
  #define MODULE_NAME_LEN (64 - sizeof(Elf_Addr))
6d9a89ea4   Andi Kleen   kbuild: declare t...
52
53
54
  #define PRINTF __attribute__ ((format (printf, 1, 2)))
  
  PRINTF void fatal(const char *fmt, ...)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55
56
57
58
59
60
61
62
63
64
65
  {
  	va_list arglist;
  
  	fprintf(stderr, "FATAL: ");
  
  	va_start(arglist, fmt);
  	vfprintf(stderr, fmt, arglist);
  	va_end(arglist);
  
  	exit(1);
  }
6d9a89ea4   Andi Kleen   kbuild: declare t...
66
  PRINTF void warn(const char *fmt, ...)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67
68
69
70
71
72
73
74
75
  {
  	va_list arglist;
  
  	fprintf(stderr, "WARNING: ");
  
  	va_start(arglist, fmt);
  	vfprintf(stderr, fmt, arglist);
  	va_end(arglist);
  }
6d9a89ea4   Andi Kleen   kbuild: declare t...
76
  PRINTF void merror(const char *fmt, ...)
2a1166594   Matthew Wilcox   kbuild: distingui...
77
78
79
80
81
82
83
84
85
  {
  	va_list arglist;
  
  	fprintf(stderr, "ERROR: ");
  
  	va_start(arglist, fmt);
  	vfprintf(stderr, fmt, arglist);
  	va_end(arglist);
  }
d4ef1c30e   Rusty Russell   modpost: minor cl...
86
87
88
89
90
91
92
  static inline bool strends(const char *str, const char *postfix)
  {
  	if (strlen(str) < strlen(postfix))
  		return false;
  
  	return strcmp(str + strlen(str) - strlen(postfix), postfix) == 0;
  }
040fcc819   Sam Ravnborg   kbuild: improved ...
93
94
95
  static int is_vmlinux(const char *modname)
  {
  	const char *myname;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
96
97
  	myname = strrchr(modname, '/');
  	if (myname)
040fcc819   Sam Ravnborg   kbuild: improved ...
98
99
100
  		myname++;
  	else
  		myname = modname;
741f98fe2   Sam Ravnborg   kbuild: do sectio...
101
102
  	return (strcmp(myname, "vmlinux") == 0) ||
  	       (strcmp(myname, "vmlinux.o") == 0);
040fcc819   Sam Ravnborg   kbuild: improved ...
103
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
104
105
  void *do_nofail(void *ptr, const char *expr)
  {
df578e7d8   Sam Ravnborg   kbuild: clean up ...
106
  	if (!ptr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
107
108
  		fatal("modpost: Memory allocation failure: %s.
  ", expr);
df578e7d8   Sam Ravnborg   kbuild: clean up ...
109

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
110
111
112
113
  	return ptr;
  }
  
  /* A list of all modules we processed */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
114
  static struct module *modules;
8b1857436   Masahiro Yamada   modpost: constify...
115
  static struct module *find_module(const char *modname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
117
118
119
120
121
122
123
  {
  	struct module *mod;
  
  	for (mod = modules; mod; mod = mod->next)
  		if (strcmp(mod->name, modname) == 0)
  			break;
  	return mod;
  }
d4ef1c30e   Rusty Russell   modpost: minor cl...
124
  static struct module *new_module(const char *modname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
125
126
  {
  	struct module *mod;
d4ef1c30e   Rusty Russell   modpost: minor cl...
127
  	char *p;
62070fa42   Sam Ravnborg   kbuild: kill trai...
128

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
129
130
131
132
133
  	mod = NOFAIL(malloc(sizeof(*mod)));
  	memset(mod, 0, sizeof(*mod));
  	p = NOFAIL(strdup(modname));
  
  	/* strip trailing .o */
d4ef1c30e   Rusty Russell   modpost: minor cl...
134
135
136
137
  	if (strends(p, ".o")) {
  		p[strlen(p) - 2] = '\0';
  		mod->is_dot_o = 1;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138
139
140
  
  	/* add to list */
  	mod->name = p;
b817f6fef   Sam Ravnborg   kbuild: check lic...
141
  	mod->gpl_compatible = -1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
  	mod->next = modules;
  	modules = mod;
  
  	return mod;
  }
  
  /* A hash of all exported symbols,
   * struct symbol is also used for lists of unresolved symbols */
  
  #define SYMBOL_HASH_SIZE 1024
  
  struct symbol {
  	struct symbol *next;
  	struct module *module;
  	unsigned int crc;
  	int crc_valid;
  	unsigned int weak:1;
040fcc819   Sam Ravnborg   kbuild: improved ...
159
160
161
  	unsigned int vmlinux:1;    /* 1 if symbol is defined in vmlinux */
  	unsigned int kernel:1;     /* 1 if symbol is from kernel
  				    *  (only for external modules) **/
b6568b1a1   Rusty Russell   modpost: fix bogu...
162
  	unsigned int preloaded:1;  /* 1 if symbol from Module.symvers, or crc */
bd5cbcedf   Ram Pai   kbuild: export-ty...
163
  	enum export  export;       /* Type of export */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
164
165
166
167
168
169
170
171
172
173
174
175
  	char name[0];
  };
  
  static struct symbol *symbolhash[SYMBOL_HASH_SIZE];
  
  /* This is based on the hash agorithm from gdbm, via tdb */
  static inline unsigned int tdb_hash(const char *name)
  {
  	unsigned value;	/* Used to compute the hash value.  */
  	unsigned   i;	/* Used to cycle through random values. */
  
  	/* Set the initial value from the key size. */
df578e7d8   Sam Ravnborg   kbuild: clean up ...
176
  	for (value = 0x238F13AF * strlen(name), i = 0; name[i]; i++)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
177
178
179
180
  		value = (value + (((unsigned char *)name)[i] << (i*5 % 24)));
  
  	return (1103515243 * value + 12345);
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
181
182
183
184
185
186
  /**
   * Allocate a new symbols for use in the hash of exported symbols or
   * the list of unresolved symbols per module
   **/
  static struct symbol *alloc_symbol(const char *name, unsigned int weak,
  				   struct symbol *next)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
187
188
189
190
191
192
193
194
195
196
197
  {
  	struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1));
  
  	memset(s, 0, sizeof(*s));
  	strcpy(s->name, name);
  	s->weak = weak;
  	s->next = next;
  	return s;
  }
  
  /* For the hash of exported symbols */
bd5cbcedf   Ram Pai   kbuild: export-ty...
198
199
  static struct symbol *new_symbol(const char *name, struct module *module,
  				 enum export export)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
200
201
202
203
204
205
206
  {
  	unsigned int hash;
  	struct symbol *new;
  
  	hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
  	new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]);
  	new->module = module;
bd5cbcedf   Ram Pai   kbuild: export-ty...
207
  	new->export = export;
040fcc819   Sam Ravnborg   kbuild: improved ...
208
  	return new;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
209
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
210
  static struct symbol *find_symbol(const char *name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
211
212
213
214
215
216
  {
  	struct symbol *s;
  
  	/* For our purposes, .foo matches foo.  PPC64 needs this. */
  	if (name[0] == '.')
  		name++;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
217
  	for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s = s->next) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218
219
220
221
222
  		if (strcmp(s->name, name) == 0)
  			return s;
  	}
  	return NULL;
  }
7a3ee7538   Mathias Krause   modpost: reduce v...
223
  static const struct {
bd5cbcedf   Ram Pai   kbuild: export-ty...
224
225
226
227
  	const char *str;
  	enum export export;
  } export_list[] = {
  	{ .str = "EXPORT_SYMBOL",            .export = export_plain },
c96fca213   Sam Ravnborg   kbuild: warn when...
228
  	{ .str = "EXPORT_UNUSED_SYMBOL",     .export = export_unused },
bd5cbcedf   Ram Pai   kbuild: export-ty...
229
  	{ .str = "EXPORT_SYMBOL_GPL",        .export = export_gpl },
c96fca213   Sam Ravnborg   kbuild: warn when...
230
  	{ .str = "EXPORT_UNUSED_SYMBOL_GPL", .export = export_unused_gpl },
bd5cbcedf   Ram Pai   kbuild: export-ty...
231
232
233
234
235
236
237
238
239
  	{ .str = "EXPORT_SYMBOL_GPL_FUTURE", .export = export_gpl_future },
  	{ .str = "(unknown)",                .export = export_unknown },
  };
  
  
  static const char *export_str(enum export ex)
  {
  	return export_list[ex].str;
  }
df578e7d8   Sam Ravnborg   kbuild: clean up ...
240
  static enum export export_no(const char *s)
bd5cbcedf   Ram Pai   kbuild: export-ty...
241
242
  {
  	int i;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
243

534b89a9f   Sam Ravnborg   kbuild: fix segv ...
244
245
  	if (!s)
  		return export_unknown;
bd5cbcedf   Ram Pai   kbuild: export-ty...
246
247
248
249
250
251
  	for (i = 0; export_list[i].export != export_unknown; i++) {
  		if (strcmp(export_list[i].str, s) == 0)
  			return export_list[i].export;
  	}
  	return export_unknown;
  }
6124c04c1   Masahiro Yamada   modpost: simplify...
252
253
254
255
256
257
258
259
260
261
262
  static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr)
  {
  	return (void *)elf->hdr +
  		elf->sechdrs[elf->secindex_strings].sh_offset +
  		sechdr->sh_name;
  }
  
  static const char *sec_name(struct elf_info *elf, int secindex)
  {
  	return sech_name(elf, &elf->sechdrs[secindex]);
  }
62a263561   Alessio Igor Bogani   modpost: Fix modp...
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
  
  #define strstarts(str, prefix) (strncmp(str, prefix, strlen(prefix)) == 0)
  
  static enum export export_from_secname(struct elf_info *elf, unsigned int sec)
  {
  	const char *secname = sec_name(elf, sec);
  
  	if (strstarts(secname, "___ksymtab+"))
  		return export_plain;
  	else if (strstarts(secname, "___ksymtab_unused+"))
  		return export_unused;
  	else if (strstarts(secname, "___ksymtab_gpl+"))
  		return export_gpl;
  	else if (strstarts(secname, "___ksymtab_unused_gpl+"))
  		return export_unused_gpl;
  	else if (strstarts(secname, "___ksymtab_gpl_future+"))
  		return export_gpl_future;
  	else
  		return export_unknown;
  }
1ce53adf1   Denys Vlasenko   modpost: support ...
283
  static enum export export_from_sec(struct elf_info *elf, unsigned int sec)
bd5cbcedf   Ram Pai   kbuild: export-ty...
284
285
286
  {
  	if (sec == elf->export_sec)
  		return export_plain;
c96fca213   Sam Ravnborg   kbuild: warn when...
287
288
  	else if (sec == elf->export_unused_sec)
  		return export_unused;
bd5cbcedf   Ram Pai   kbuild: export-ty...
289
290
  	else if (sec == elf->export_gpl_sec)
  		return export_gpl;
c96fca213   Sam Ravnborg   kbuild: warn when...
291
292
  	else if (sec == elf->export_unused_gpl_sec)
  		return export_unused_gpl;
bd5cbcedf   Ram Pai   kbuild: export-ty...
293
294
295
296
297
  	else if (sec == elf->export_gpl_future_sec)
  		return export_gpl_future;
  	else
  		return export_unknown;
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
298
299
300
301
  /**
   * Add an exported symbol - it may have already been added without a
   * CRC, in this case just update the CRC
   **/
bd5cbcedf   Ram Pai   kbuild: export-ty...
302
303
  static struct symbol *sym_add_exported(const char *name, struct module *mod,
  				       enum export export)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
304
305
306
307
  {
  	struct symbol *s = find_symbol(name);
  
  	if (!s) {
bd5cbcedf   Ram Pai   kbuild: export-ty...
308
  		s = new_symbol(name, mod, export);
8e70c4588   Sam Ravnborg   kbuild: warn abou...
309
310
  	} else {
  		if (!s->preloaded) {
7b75b13cd   Sam Ravnborg   kbuild: when warn...
311
  			warn("%s: '%s' exported twice. Previous export "
8e70c4588   Sam Ravnborg   kbuild: warn abou...
312
313
314
315
  			     "was in %s%s
  ", mod->name, name,
  			     s->module->name,
  			     is_vmlinux(s->module->name) ?"":".ko");
4b21960f9   Trent Piepho   kbuild: modpost p...
316
  		} else {
baec30e41   Paul Bolle   modpost: Fix comm...
317
  			/* In case Module.symvers was out of date */
4b21960f9   Trent Piepho   kbuild: modpost p...
318
  			s->module = mod;
8e70c4588   Sam Ravnborg   kbuild: warn abou...
319
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
320
  	}
8e70c4588   Sam Ravnborg   kbuild: warn abou...
321
  	s->preloaded = 0;
040fcc819   Sam Ravnborg   kbuild: improved ...
322
323
  	s->vmlinux   = is_vmlinux(mod->name);
  	s->kernel    = 0;
bd5cbcedf   Ram Pai   kbuild: export-ty...
324
  	s->export    = export;
040fcc819   Sam Ravnborg   kbuild: improved ...
325
326
327
328
  	return s;
  }
  
  static void sym_update_crc(const char *name, struct module *mod,
bd5cbcedf   Ram Pai   kbuild: export-ty...
329
  			   unsigned int crc, enum export export)
040fcc819   Sam Ravnborg   kbuild: improved ...
330
331
  {
  	struct symbol *s = find_symbol(name);
b6568b1a1   Rusty Russell   modpost: fix bogu...
332
  	if (!s) {
bd5cbcedf   Ram Pai   kbuild: export-ty...
333
  		s = new_symbol(name, mod, export);
b6568b1a1   Rusty Russell   modpost: fix bogu...
334
335
336
  		/* Don't complain when we find it later. */
  		s->preloaded = 1;
  	}
040fcc819   Sam Ravnborg   kbuild: improved ...
337
338
  	s->crc = crc;
  	s->crc_valid = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
339
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
340
  void *grab_file(const char *filename, unsigned long *size)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
341
342
  {
  	struct stat st;
eb3d5cc67   Jesper Juhl   modpost: Stop gra...
343
  	void *map = MAP_FAILED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
344
345
346
  	int fd;
  
  	fd = open(filename, O_RDONLY);
eb3d5cc67   Jesper Juhl   modpost: Stop gra...
347
  	if (fd < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
348
  		return NULL;
eb3d5cc67   Jesper Juhl   modpost: Stop gra...
349
350
  	if (fstat(fd, &st))
  		goto failed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
351
352
353
  
  	*size = st.st_size;
  	map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
354

eb3d5cc67   Jesper Juhl   modpost: Stop gra...
355
356
  failed:
  	close(fd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
357
358
359
360
  	if (map == MAP_FAILED)
  		return NULL;
  	return map;
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
361
362
363
364
365
  /**
    * Return a copy of the next line in a mmap'ed file.
    * spaces in the beginning of the line is trimmed away.
    * Return a pointer to a static buffer.
    **/
df578e7d8   Sam Ravnborg   kbuild: clean up ...
366
  char *get_next_line(unsigned long *pos, void *file, unsigned long size)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
367
368
369
370
371
372
  {
  	static char line[4096];
  	int skip = 1;
  	size_t len = 0;
  	signed char *p = (signed char *)file + *pos;
  	char *s = line;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
373
  	for (; *pos < size ; (*pos)++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
  		if (skip && isspace(*p)) {
  			p++;
  			continue;
  		}
  		skip = 0;
  		if (*p != '
  ' && (*pos < size)) {
  			len++;
  			*s++ = *p++;
  			if (len > 4095)
  				break; /* Too long, stop */
  		} else {
  			/* End of string */
  			*s = '\0';
  			return line;
  		}
  	}
  	/* End of buffer */
  	return NULL;
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
394
  void release_file(void *file, unsigned long size)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
395
396
397
  {
  	munmap(file, size);
  }
85bd2fddd   Sam Ravnborg   kbuild: fix secti...
398
  static int parse_elf(struct elf_info *info, const char *filename)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
399
400
  {
  	unsigned int i;
85bd2fddd   Sam Ravnborg   kbuild: fix secti...
401
  	Elf_Ehdr *hdr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
402
403
  	Elf_Shdr *sechdrs;
  	Elf_Sym  *sym;
1ce53adf1   Denys Vlasenko   modpost: support ...
404
405
  	const char *secstrings;
  	unsigned int symtab_idx = ~0U, symtab_shndx_idx = ~0U;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
406
407
408
  
  	hdr = grab_file(filename, &info->size);
  	if (!hdr) {
eed380f3f   Guenter Roeck   modpost: Optional...
409
410
411
412
413
414
  		if (ignore_missing_files) {
  			fprintf(stderr, "%s: %s (ignored)
  ", filename,
  				strerror(errno));
  			return 0;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
415
  		perror(filename);
6803dc0ea   Sam Ravnborg   kbuild: replace a...
416
  		exit(1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
417
418
  	}
  	info->hdr = hdr;
85bd2fddd   Sam Ravnborg   kbuild: fix secti...
419
420
421
422
423
424
425
426
427
428
429
430
  	if (info->size < sizeof(*hdr)) {
  		/* file too small, assume this is an empty .o file */
  		return 0;
  	}
  	/* Is this a valid ELF file? */
  	if ((hdr->e_ident[EI_MAG0] != ELFMAG0) ||
  	    (hdr->e_ident[EI_MAG1] != ELFMAG1) ||
  	    (hdr->e_ident[EI_MAG2] != ELFMAG2) ||
  	    (hdr->e_ident[EI_MAG3] != ELFMAG3)) {
  		/* Not an ELF file - silently ignore it */
  		return 0;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
431
  	/* Fix endianness in ELF header */
7d875a028   Anders Kaseorg   kbuild, modpost: ...
432
433
434
435
436
437
438
439
440
441
442
443
444
  	hdr->e_type      = TO_NATIVE(hdr->e_type);
  	hdr->e_machine   = TO_NATIVE(hdr->e_machine);
  	hdr->e_version   = TO_NATIVE(hdr->e_version);
  	hdr->e_entry     = TO_NATIVE(hdr->e_entry);
  	hdr->e_phoff     = TO_NATIVE(hdr->e_phoff);
  	hdr->e_shoff     = TO_NATIVE(hdr->e_shoff);
  	hdr->e_flags     = TO_NATIVE(hdr->e_flags);
  	hdr->e_ehsize    = TO_NATIVE(hdr->e_ehsize);
  	hdr->e_phentsize = TO_NATIVE(hdr->e_phentsize);
  	hdr->e_phnum     = TO_NATIVE(hdr->e_phnum);
  	hdr->e_shentsize = TO_NATIVE(hdr->e_shentsize);
  	hdr->e_shnum     = TO_NATIVE(hdr->e_shnum);
  	hdr->e_shstrndx  = TO_NATIVE(hdr->e_shstrndx);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
445
446
  	sechdrs = (void *)hdr + hdr->e_shoff;
  	info->sechdrs = sechdrs;
a83710e58   Petr Stetiar   kbuild: fix segfa...
447
448
  	/* Check if file offset is correct */
  	if (hdr->e_shoff > info->size) {
df578e7d8   Sam Ravnborg   kbuild: clean up ...
449
450
451
452
  		fatal("section header offset=%lu in file '%s' is bigger than "
  		      "filesize=%lu
  ", (unsigned long)hdr->e_shoff,
  		      filename, info->size);
a83710e58   Petr Stetiar   kbuild: fix segfa...
453
454
  		return 0;
  	}
6845756b2   Anders Kaseorg   modpost: Update 6...
455
  	if (hdr->e_shnum == SHN_UNDEF) {
1ce53adf1   Denys Vlasenko   modpost: support ...
456
457
458
  		/*
  		 * There are more than 64k sections,
  		 * read count from .sh_size.
1ce53adf1   Denys Vlasenko   modpost: support ...
459
460
461
462
463
464
465
  		 */
  		info->num_sections = TO_NATIVE(sechdrs[0].sh_size);
  	}
  	else {
  		info->num_sections = hdr->e_shnum;
  	}
  	if (hdr->e_shstrndx == SHN_XINDEX) {
6845756b2   Anders Kaseorg   modpost: Update 6...
466
  		info->secindex_strings = TO_NATIVE(sechdrs[0].sh_link);
1ce53adf1   Denys Vlasenko   modpost: support ...
467
468
469
470
  	}
  	else {
  		info->secindex_strings = hdr->e_shstrndx;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
471
  	/* Fix endianness in section headers */
1ce53adf1   Denys Vlasenko   modpost: support ...
472
  	for (i = 0; i < info->num_sections; i++) {
7d875a028   Anders Kaseorg   kbuild, modpost: ...
473
474
475
476
477
478
479
480
481
482
  		sechdrs[i].sh_name      = TO_NATIVE(sechdrs[i].sh_name);
  		sechdrs[i].sh_type      = TO_NATIVE(sechdrs[i].sh_type);
  		sechdrs[i].sh_flags     = TO_NATIVE(sechdrs[i].sh_flags);
  		sechdrs[i].sh_addr      = TO_NATIVE(sechdrs[i].sh_addr);
  		sechdrs[i].sh_offset    = TO_NATIVE(sechdrs[i].sh_offset);
  		sechdrs[i].sh_size      = TO_NATIVE(sechdrs[i].sh_size);
  		sechdrs[i].sh_link      = TO_NATIVE(sechdrs[i].sh_link);
  		sechdrs[i].sh_info      = TO_NATIVE(sechdrs[i].sh_info);
  		sechdrs[i].sh_addralign = TO_NATIVE(sechdrs[i].sh_addralign);
  		sechdrs[i].sh_entsize   = TO_NATIVE(sechdrs[i].sh_entsize);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
483
484
  	}
  	/* Find symbol table. */
1ce53adf1   Denys Vlasenko   modpost: support ...
485
486
  	secstrings = (void *)hdr + sechdrs[info->secindex_strings].sh_offset;
  	for (i = 1; i < info->num_sections; i++) {
bd5cbcedf   Ram Pai   kbuild: export-ty...
487
  		const char *secname;
56fc82c53   Tejun Heo   modpost: NOBITS s...
488
  		int nobits = sechdrs[i].sh_type == SHT_NOBITS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
489

56fc82c53   Tejun Heo   modpost: NOBITS s...
490
  		if (!nobits && sechdrs[i].sh_offset > info->size) {
df578e7d8   Sam Ravnborg   kbuild: clean up ...
491
492
493
494
495
  			fatal("%s is truncated. sechdrs[i].sh_offset=%lu > "
  			      "sizeof(*hrd)=%zu
  ", filename,
  			      (unsigned long)sechdrs[i].sh_offset,
  			      sizeof(*hdr));
85bd2fddd   Sam Ravnborg   kbuild: fix secti...
496
497
  			return 0;
  		}
bd5cbcedf   Ram Pai   kbuild: export-ty...
498
499
  		secname = secstrings + sechdrs[i].sh_name;
  		if (strcmp(secname, ".modinfo") == 0) {
56fc82c53   Tejun Heo   modpost: NOBITS s...
500
501
502
  			if (nobits)
  				fatal("%s has NOBITS .modinfo
  ", filename);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
503
504
  			info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
  			info->modinfo_len = sechdrs[i].sh_size;
bd5cbcedf   Ram Pai   kbuild: export-ty...
505
506
  		} else if (strcmp(secname, "__ksymtab") == 0)
  			info->export_sec = i;
c96fca213   Sam Ravnborg   kbuild: warn when...
507
508
  		else if (strcmp(secname, "__ksymtab_unused") == 0)
  			info->export_unused_sec = i;
bd5cbcedf   Ram Pai   kbuild: export-ty...
509
510
  		else if (strcmp(secname, "__ksymtab_gpl") == 0)
  			info->export_gpl_sec = i;
c96fca213   Sam Ravnborg   kbuild: warn when...
511
512
  		else if (strcmp(secname, "__ksymtab_unused_gpl") == 0)
  			info->export_unused_gpl_sec = i;
bd5cbcedf   Ram Pai   kbuild: export-ty...
513
514
  		else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
  			info->export_gpl_future_sec = i;
1ce53adf1   Denys Vlasenko   modpost: support ...
515
516
517
518
519
520
521
  		if (sechdrs[i].sh_type == SHT_SYMTAB) {
  			unsigned int sh_link_idx;
  			symtab_idx = i;
  			info->symtab_start = (void *)hdr +
  			    sechdrs[i].sh_offset;
  			info->symtab_stop  = (void *)hdr +
  			    sechdrs[i].sh_offset + sechdrs[i].sh_size;
6845756b2   Anders Kaseorg   modpost: Update 6...
522
  			sh_link_idx = sechdrs[i].sh_link;
1ce53adf1   Denys Vlasenko   modpost: support ...
523
524
525
  			info->strtab       = (void *)hdr +
  			    sechdrs[sh_link_idx].sh_offset;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
526

1ce53adf1   Denys Vlasenko   modpost: support ...
527
528
529
530
531
532
533
534
  		/* 32bit section no. table? ("more than 64k sections") */
  		if (sechdrs[i].sh_type == SHT_SYMTAB_SHNDX) {
  			symtab_shndx_idx = i;
  			info->symtab_shndx_start = (void *)hdr +
  			    sechdrs[i].sh_offset;
  			info->symtab_shndx_stop  = (void *)hdr +
  			    sechdrs[i].sh_offset + sechdrs[i].sh_size;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
535
  	}
df578e7d8   Sam Ravnborg   kbuild: clean up ...
536
  	if (!info->symtab_start)
cb80514d9   Sam Ravnborg   kbuild: use warn(...
537
538
  		fatal("%s has no symtab?
  ", filename);
df578e7d8   Sam Ravnborg   kbuild: clean up ...
539

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
540
541
542
543
544
545
546
  	/* Fix endianness in symbols */
  	for (sym = info->symtab_start; sym < info->symtab_stop; sym++) {
  		sym->st_shndx = TO_NATIVE(sym->st_shndx);
  		sym->st_name  = TO_NATIVE(sym->st_name);
  		sym->st_value = TO_NATIVE(sym->st_value);
  		sym->st_size  = TO_NATIVE(sym->st_size);
  	}
1ce53adf1   Denys Vlasenko   modpost: support ...
547
548
549
  
  	if (symtab_shndx_idx != ~0U) {
  		Elf32_Word *p;
6845756b2   Anders Kaseorg   modpost: Update 6...
550
  		if (symtab_idx != sechdrs[symtab_shndx_idx].sh_link)
1ce53adf1   Denys Vlasenko   modpost: support ...
551
552
  			fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u
  ",
6845756b2   Anders Kaseorg   modpost: Update 6...
553
  			      filename, sechdrs[symtab_shndx_idx].sh_link,
1ce53adf1   Denys Vlasenko   modpost: support ...
554
555
556
557
558
559
  			      symtab_idx);
  		/* Fix endianness */
  		for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop;
  		     p++)
  			*p = TO_NATIVE(*p);
  	}
85bd2fddd   Sam Ravnborg   kbuild: fix secti...
560
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
561
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
562
  static void parse_elf_finish(struct elf_info *info)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
563
564
565
  {
  	release_file(info->hdr, info->size);
  }
4d7365d66   Sam Ravnborg   kbuild: ignore po...
566
567
568
  static int ignore_undef_symbol(struct elf_info *info, const char *symname)
  {
  	/* ignore __this_module, it will be resolved shortly */
b2c5cdcfd   Masahiro Yamada   modpost: remove s...
569
  	if (strcmp(symname, "__this_module") == 0)
4d7365d66   Sam Ravnborg   kbuild: ignore po...
570
571
572
573
574
575
  		return 1;
  	/* ignore global offset table */
  	if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0)
  		return 1;
  	if (info->hdr->e_machine == EM_PPC)
  		/* Special register function linked on all modules during final link of .ko */
d62c47652   Masahiro Yamada   modpost: use strs...
576
577
578
579
580
581
  		if (strstarts(symname, "_restgpr_") ||
  		    strstarts(symname, "_savegpr_") ||
  		    strstarts(symname, "_rest32gpr_") ||
  		    strstarts(symname, "_save32gpr_") ||
  		    strstarts(symname, "_restvr_") ||
  		    strstarts(symname, "_savevr_"))
4d7365d66   Sam Ravnborg   kbuild: ignore po...
582
  			return 1;
7fca5dc8a   Stephen Rothwell   powerpc: Fix modu...
583
584
  	if (info->hdr->e_machine == EM_PPC64)
  		/* Special register function linked on all modules during final link of .ko */
d62c47652   Masahiro Yamada   modpost: use strs...
585
586
587
588
  		if (strstarts(symname, "_restgpr0_") ||
  		    strstarts(symname, "_savegpr0_") ||
  		    strstarts(symname, "_restvr_") ||
  		    strstarts(symname, "_savevr_") ||
c153693d7   Alan Modra   powerpc: Simplify...
589
  		    strcmp(symname, ".TOC.") == 0)
7fca5dc8a   Stephen Rothwell   powerpc: Fix modu...
590
  			return 1;
4d7365d66   Sam Ravnborg   kbuild: ignore po...
591
592
593
  	/* Do not ignore this symbol */
  	return 0;
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
594
595
  static void handle_modversions(struct module *mod, struct elf_info *info,
  			       Elf_Sym *sym, const char *symname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
596
597
  {
  	unsigned int crc;
62a263561   Alessio Igor Bogani   modpost: Fix modp...
598
  	enum export export;
d8c1eb86e   Nicholas Piggin   kbuild: modpost w...
599
  	bool is_crc = false;
62a263561   Alessio Igor Bogani   modpost: Fix modp...
600

258f74263   Frank Rowand   modpost: Fix modp...
601
  	if ((!is_vmlinux(mod->name) || mod->is_dot_o) &&
d62c47652   Masahiro Yamada   modpost: use strs...
602
  	    strstarts(symname, "__ksymtab"))
62a263561   Alessio Igor Bogani   modpost: Fix modp...
603
604
605
  		export = export_from_secname(info, get_secindex(info, sym));
  	else
  		export = export_from_sec(info, get_secindex(info, sym));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
606

b5064654c   Andi Kleen   scripts/mod/modpo...
607
  	/* CRC'd symbol */
d62c47652   Masahiro Yamada   modpost: use strs...
608
  	if (strstarts(symname, "__crc_")) {
d8c1eb86e   Nicholas Piggin   kbuild: modpost w...
609
  		is_crc = true;
b5064654c   Andi Kleen   scripts/mod/modpo...
610
  		crc = (unsigned int) sym->st_value;
56067812d   Ard Biesheuvel   kbuild: modversio...
611
612
613
614
615
616
617
618
  		if (sym->st_shndx != SHN_UNDEF && sym->st_shndx != SHN_ABS) {
  			unsigned int *crcp;
  
  			/* symbol points to the CRC in the ELF object */
  			crcp = (void *)info->hdr + sym->st_value +
  			       info->sechdrs[sym->st_shndx].sh_offset -
  			       (info->hdr->e_type != ET_REL ?
  				info->sechdrs[sym->st_shndx].sh_addr : 0);
aa7f29f87   Fredrik Noring   kbuild: modversio...
619
  			crc = TO_NATIVE(*crcp);
56067812d   Ard Biesheuvel   kbuild: modversio...
620
  		}
b2c5cdcfd   Masahiro Yamada   modpost: remove s...
621
  		sym_update_crc(symname + strlen("__crc_"), mod, crc,
b5064654c   Andi Kleen   scripts/mod/modpo...
622
623
  				export);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
624
625
  	switch (sym->st_shndx) {
  	case SHN_COMMON:
d62c47652   Masahiro Yamada   modpost: use strs...
626
  		if (strstarts(symname, "__gnu_lto_")) {
ef178f923   Andi Kleen   Kbuild, lto: Hand...
627
628
629
630
  			/* Should warn here, but modpost runs before the linker */
  		} else
  			warn("\"%s\" [%s] is COMMON symbol
  ", symname, mod->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
631
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
632
633
634
635
636
  	case SHN_UNDEF:
  		/* undefined symbol */
  		if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL &&
  		    ELF_ST_BIND(sym->st_info) != STB_WEAK)
  			break;
4d7365d66   Sam Ravnborg   kbuild: ignore po...
637
  		if (ignore_undef_symbol(info, symname))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
638
  			break;
8d5290149   Ben Colline   [SPARC]: Deal wit...
639
640
641
642
643
644
  /* cope with newer glibc (2.3.4 or higher) STT_ definition in elf.h */
  #if defined(STT_REGISTER) || defined(STT_SPARC_REGISTER)
  /* add compatibility with older glibc */
  #ifndef STT_SPARC_REGISTER
  #define STT_SPARC_REGISTER STT_REGISTER
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
645
646
647
  		if (info->hdr->e_machine == EM_SPARC ||
  		    info->hdr->e_machine == EM_SPARCV9) {
  			/* Ignore register directives. */
8d5290149   Ben Colline   [SPARC]: Deal wit...
648
  			if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
649
  				break;
62070fa42   Sam Ravnborg   kbuild: kill trai...
650
  			if (symname[0] == '.') {
1f3aa9002   Randy Dunlap   scripts: modpost:...
651
  				char *munged = NOFAIL(strdup(symname));
62070fa42   Sam Ravnborg   kbuild: kill trai...
652
653
654
655
  				munged[0] = '_';
  				munged[1] = toupper(munged[1]);
  				symname = munged;
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
656
657
  		}
  #endif
62070fa42   Sam Ravnborg   kbuild: kill trai...
658

d8c1eb86e   Nicholas Piggin   kbuild: modpost w...
659
660
  		if (is_crc) {
  			const char *e = is_vmlinux(mod->name) ?"":".ko";
b2c5cdcfd   Masahiro Yamada   modpost: remove s...
661
662
663
  			warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.
  ",
  			     symname + strlen("__crc_"), mod->name, e);
d8c1eb86e   Nicholas Piggin   kbuild: modpost w...
664
  		}
b92021b09   Rusty Russell   CONFIG_SYMBOL_PRE...
665
666
667
  		mod->unres = alloc_symbol(symname,
  					  ELF_ST_BIND(sym->st_info) == STB_WEAK,
  					  mod->unres);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
668
669
670
  		break;
  	default:
  		/* All exported symbols */
d62c47652   Masahiro Yamada   modpost: use strs...
671
  		if (strstarts(symname, "__ksymtab_")) {
b2c5cdcfd   Masahiro Yamada   modpost: remove s...
672
  			sym_add_exported(symname + strlen("__ksymtab_"), mod,
bd5cbcedf   Ram Pai   kbuild: export-ty...
673
  					export);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
674
  		}
b2c5cdcfd   Masahiro Yamada   modpost: remove s...
675
  		if (strcmp(symname, "init_module") == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
676
  			mod->has_init = 1;
b2c5cdcfd   Masahiro Yamada   modpost: remove s...
677
  		if (strcmp(symname, "cleanup_module") == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
678
679
680
681
  			mod->has_cleanup = 1;
  		break;
  	}
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
682
683
684
  /**
   * Parse tag=value strings from .modinfo section
   **/
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
  static char *next_string(char *string, unsigned long *secsize)
  {
  	/* Skip non-zero chars */
  	while (string[0]) {
  		string++;
  		if ((*secsize)-- <= 1)
  			return NULL;
  	}
  
  	/* Skip any zero padding. */
  	while (!string[0]) {
  		string++;
  		if ((*secsize)-- <= 1)
  			return NULL;
  	}
  	return string;
  }
bca2ccee4   Masahiro Yamada   modpost: pass str...
702
703
  static char *get_next_modinfo(struct elf_info *info, const char *tag,
  			      char *prev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
704
705
706
  {
  	char *p;
  	unsigned int taglen = strlen(tag);
bca2ccee4   Masahiro Yamada   modpost: pass str...
707
708
  	char *modinfo = info->modinfo;
  	unsigned long size = info->modinfo_len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
709

bca2ccee4   Masahiro Yamada   modpost: pass str...
710
711
712
  	if (prev) {
  		size -= prev - modinfo;
  		modinfo = next_string(prev, &size);
b817f6fef   Sam Ravnborg   kbuild: check lic...
713
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
714
715
716
717
718
719
  	for (p = modinfo; p; p = next_string(p, &size)) {
  		if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
  			return p + taglen + 1;
  	}
  	return NULL;
  }
bca2ccee4   Masahiro Yamada   modpost: pass str...
720
  static char *get_modinfo(struct elf_info *info, const char *tag)
b817f6fef   Sam Ravnborg   kbuild: check lic...
721
722
  
  {
bca2ccee4   Masahiro Yamada   modpost: pass str...
723
  	return get_next_modinfo(info, tag, NULL);
b817f6fef   Sam Ravnborg   kbuild: check lic...
724
  }
93684d3b8   Sam Ravnborg   kbuild: include s...
725
  /**
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
726
727
728
729
730
   * Test if string s ends in string sub
   * return 0 if match
   **/
  static int strrcmp(const char *s, const char *sub)
  {
df578e7d8   Sam Ravnborg   kbuild: clean up ...
731
  	int slen, sublen;
62070fa42   Sam Ravnborg   kbuild: kill trai...
732

4c8fbca58   Sam Ravnborg   kbuild: whitelist...
733
734
  	if (!s || !sub)
  		return 1;
62070fa42   Sam Ravnborg   kbuild: kill trai...
735

4c8fbca58   Sam Ravnborg   kbuild: whitelist...
736
  	slen = strlen(s);
df578e7d8   Sam Ravnborg   kbuild: clean up ...
737
  	sublen = strlen(sub);
62070fa42   Sam Ravnborg   kbuild: kill trai...
738

4c8fbca58   Sam Ravnborg   kbuild: whitelist...
739
740
  	if ((slen == 0) || (sublen == 0))
  		return 1;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
741
742
  	if (sublen > slen)
  		return 1;
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
743

df578e7d8   Sam Ravnborg   kbuild: clean up ...
744
  	return memcmp(s + slen - sublen, sub, sublen);
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
745
  }
ff13f9269   Sam Ravnborg   kbuild: introduce...
746
747
  static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
  {
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
748
749
750
  	if (sym)
  		return elf->strtab + sym->st_name;
  	else
f666751a0   Sam Ravnborg   kbuild/modpost: i...
751
  		return "(unknown)";
ff13f9269   Sam Ravnborg   kbuild: introduce...
752
  }
10668220a   Sam Ravnborg   kbuild: introduce...
753
754
  /* The pattern is an array of simple patterns.
   * "foo" will match an exact string equal to "foo"
6c5bd235b   Sam Ravnborg   kbuild: check sec...
755
   * "*foo" will match a string that ends with "foo"
10668220a   Sam Ravnborg   kbuild: introduce...
756
   * "foo*" will match a string that begins with "foo"
09c20c032   Paul Gortmaker   modpost: expand p...
757
   * "*foo*" will match a string that contains "foo"
10668220a   Sam Ravnborg   kbuild: introduce...
758
   */
5c7251384   Trevor Keith   Fix all -Wmissing...
759
  static int match(const char *sym, const char * const pat[])
10668220a   Sam Ravnborg   kbuild: introduce...
760
761
762
763
764
  {
  	const char *p;
  	while (*pat) {
  		p = *pat++;
  		const char *endp = p + strlen(p) - 1;
09c20c032   Paul Gortmaker   modpost: expand p...
765
766
767
768
769
770
771
772
773
  		/* "*foo*" */
  		if (*p == '*' && *endp == '*') {
  			char *here, *bare = strndup(p + 1, strlen(p) - 2);
  
  			here = strstr(sym, bare);
  			free(bare);
  			if (here != NULL)
  				return 1;
  		}
6c5bd235b   Sam Ravnborg   kbuild: check sec...
774
  		/* "*foo" */
09c20c032   Paul Gortmaker   modpost: expand p...
775
  		else if (*p == '*') {
6c5bd235b   Sam Ravnborg   kbuild: check sec...
776
777
778
  			if (strrcmp(sym, p + 1) == 0)
  				return 1;
  		}
10668220a   Sam Ravnborg   kbuild: introduce...
779
  		/* "foo*" */
6c5bd235b   Sam Ravnborg   kbuild: check sec...
780
  		else if (*endp == '*') {
10668220a   Sam Ravnborg   kbuild: introduce...
781
782
783
  			if (strncmp(sym, p, strlen(p) - 1) == 0)
  				return 1;
  		}
10668220a   Sam Ravnborg   kbuild: introduce...
784
785
786
787
788
789
790
791
792
  		/* no wildcards */
  		else {
  			if (strcmp(p, sym) == 0)
  				return 1;
  		}
  	}
  	/* no match */
  	return 0;
  }
10668220a   Sam Ravnborg   kbuild: introduce...
793
  /* sections that we do not want to do full section mismatch check on */
7a3ee7538   Mathias Krause   modpost: reduce v...
794
  static const char *const section_white_list[] =
4391ed6aa   Sam Ravnborg   kbuild, modpost: ...
795
796
797
  {
  	".comment*",
  	".debug*",
4d10c223b   Chen Gang   scripts/mod/modpo...
798
  	".cranges",		/* sh64 */
1121584f5   H.J. Lu   modpost: Put .zde...
799
  	".zdebug*",		/* Compressed debug sections. */
739d875dd   David Howells   mn10300: Remove t...
800
  	".GCC.command.line",	/* record-gcc-switches */
4391ed6aa   Sam Ravnborg   kbuild, modpost: ...
801
802
803
804
805
806
  	".mdebug*",        /* alpha, score, mips etc. */
  	".pdr",            /* alpha, score, mips etc. */
  	".stab*",
  	".note*",
  	".got*",
  	".toc*",
af42e970b   Max Filippov   modpost: fix modp...
807
808
  	".xt.prop",				 /* xtensa */
  	".xt.lit",         /* xtensa */
f2e207f32   Vineet Gupta   modpost: Ignore A...
809
810
  	".arcextmap*",			/* arc */
  	".gnu.linkonce.arcext*",	/* arc : modules */
d1189c63e   Noam Camus   scripts: [modpost...
811
812
  	".cmem*",			/* EZchip */
  	".fmt_slot*",			/* EZchip */
ef178f923   Andi Kleen   Kbuild, lto: Hand...
813
  	".gnu.lto*",
e390f9a96   Josh Poimboeuf   objtool, modules:...
814
  	".discard.*",
4391ed6aa   Sam Ravnborg   kbuild, modpost: ...
815
816
  	NULL
  };
10668220a   Sam Ravnborg   kbuild: introduce...
817

e241a6303   Sam Ravnborg   kbuild: warn abou...
818
  /*
b614a697d   Anders Kaseorg   kbuild, modpost: ...
819
   * This is used to find sections missing the SHF_ALLOC flag.
e241a6303   Sam Ravnborg   kbuild: warn abou...
820
   * The cause of this is often a section specified in assembler
b614a697d   Anders Kaseorg   kbuild, modpost: ...
821
   * without "ax" / "aw".
e241a6303   Sam Ravnborg   kbuild: warn abou...
822
   */
b614a697d   Anders Kaseorg   kbuild, modpost: ...
823
  static void check_section(const char *modname, struct elf_info *elf,
bb66fc671   Masahiro Yamada   kbuild: trivial -...
824
  			  Elf_Shdr *sechdr)
e241a6303   Sam Ravnborg   kbuild: warn abou...
825
  {
b614a697d   Anders Kaseorg   kbuild, modpost: ...
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
  	const char *sec = sech_name(elf, sechdr);
  
  	if (sechdr->sh_type == SHT_PROGBITS &&
  	    !(sechdr->sh_flags & SHF_ALLOC) &&
  	    !match(sec, section_white_list)) {
  		warn("%s (%s): unexpected non-allocatable section.
  "
  		     "Did you forget to use \"ax\"/\"aw\" in a .S file?
  "
  		     "Note that for example <linux/init.h> contains
  "
  		     "section definitions for use in .S files.
  
  ",
  		     modname, sec);
e241a6303   Sam Ravnborg   kbuild: warn abou...
841
  	}
e241a6303   Sam Ravnborg   kbuild: warn abou...
842
  }
eb8f68904   Sam Ravnborg   Use separate sect...
843
  #define ALL_INIT_DATA_SECTIONS \
a0d8f8037   Rasmus Villemoes   scripts: modpost:...
844
845
  	".init.setup", ".init.rodata", ".meminit.rodata", \
  	".init.data", ".meminit.data"
eb8f68904   Sam Ravnborg   Use separate sect...
846
  #define ALL_EXIT_DATA_SECTIONS \
a0d8f8037   Rasmus Villemoes   scripts: modpost:...
847
  	".exit.data", ".memexit.data"
10668220a   Sam Ravnborg   kbuild: introduce...
848

eb8f68904   Sam Ravnborg   Use separate sect...
849
  #define ALL_INIT_TEXT_SECTIONS \
a0d8f8037   Rasmus Villemoes   scripts: modpost:...
850
  	".init.text", ".meminit.text"
eb8f68904   Sam Ravnborg   Use separate sect...
851
  #define ALL_EXIT_TEXT_SECTIONS \
a0d8f8037   Rasmus Villemoes   scripts: modpost:...
852
  	".exit.text", ".memexit.text"
10668220a   Sam Ravnborg   kbuild: introduce...
853

bb15d8db7   Sebastian Andrzej Siewior   scripts/modpost: ...
854
  #define ALL_PCI_INIT_SECTIONS	\
a0d8f8037   Rasmus Villemoes   scripts: modpost:...
855
856
857
  	".pci_fixup_early", ".pci_fixup_header", ".pci_fixup_final", \
  	".pci_fixup_enable", ".pci_fixup_resume", \
  	".pci_fixup_resume_early", ".pci_fixup_suspend"
bb15d8db7   Sebastian Andrzej Siewior   scripts/modpost: ...
858

e24f66288   Paul Gortmaker   modpost: remove a...
859
860
  #define ALL_XXXINIT_SECTIONS MEM_INIT_SECTIONS
  #define ALL_XXXEXIT_SECTIONS MEM_EXIT_SECTIONS
4a31a229f   Uwe Kleine-König   modpost: define A...
861
862
863
  
  #define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS
  #define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS
10668220a   Sam Ravnborg   kbuild: introduce...
864

a0d8f8037   Rasmus Villemoes   scripts: modpost:...
865
  #define DATA_SECTIONS ".data", ".data.rel"
157d1972d   Quentin Casasnovas   modpost: add .sch...
866
  #define TEXT_SECTIONS ".text", ".text.unlikely", ".sched.text", \
6727ad9e2   Chris Metcalf   nmi_backtrace: ge...
867
  		".kprobes.text", ".cpuidle.text"
52dc0595d   Quentin Casasnovas   modpost: handle r...
868
  #define OTHER_TEXT_SECTIONS ".ref.text", ".head.text", ".spinlock.text", \
673c2c34f   Chris Metcalf   modpost: work cor...
869
870
  		".fixup", ".entry.text", ".exception.text", ".text.*", \
  		".coldtext"
10668220a   Sam Ravnborg   kbuild: introduce...
871

fd6c3a8dc   Jan Beulich   initconst adjustm...
872
  #define INIT_SECTIONS      ".init.*"
fd6c3a8dc   Jan Beulich   initconst adjustm...
873
  #define MEM_INIT_SECTIONS  ".meminit.*"
eb8f68904   Sam Ravnborg   Use separate sect...
874

fd6c3a8dc   Jan Beulich   initconst adjustm...
875
  #define EXIT_SECTIONS      ".exit.*"
fd6c3a8dc   Jan Beulich   initconst adjustm...
876
  #define MEM_EXIT_SECTIONS  ".memexit.*"
eb8f68904   Sam Ravnborg   Use separate sect...
877

52dc0595d   Quentin Casasnovas   modpost: handle r...
878
879
  #define ALL_TEXT_SECTIONS  ALL_INIT_TEXT_SECTIONS, ALL_EXIT_TEXT_SECTIONS, \
  		TEXT_SECTIONS, OTHER_TEXT_SECTIONS
6c5bd235b   Sam Ravnborg   kbuild: check sec...
880
  /* init data sections */
7a3ee7538   Mathias Krause   modpost: reduce v...
881
882
  static const char *const init_data_sections[] =
  	{ ALL_INIT_DATA_SECTIONS, NULL };
6c5bd235b   Sam Ravnborg   kbuild: check sec...
883
884
  
  /* all init sections */
7a3ee7538   Mathias Krause   modpost: reduce v...
885
  static const char *const init_sections[] = { ALL_INIT_SECTIONS, NULL };
6c5bd235b   Sam Ravnborg   kbuild: check sec...
886
887
  
  /* All init and exit sections (code + data) */
7a3ee7538   Mathias Krause   modpost: reduce v...
888
  static const char *const init_exit_sections[] =
eb8f68904   Sam Ravnborg   Use separate sect...
889
  	{ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL };
6c5bd235b   Sam Ravnborg   kbuild: check sec...
890

4a3893d06   Paul Gortmaker   modpost: don't em...
891
892
  /* all text sections */
  static const char *const text_sections[] = { ALL_TEXT_SECTIONS, NULL };
6c5bd235b   Sam Ravnborg   kbuild: check sec...
893
  /* data section */
7a3ee7538   Mathias Krause   modpost: reduce v...
894
  static const char *const data_sections[] = { DATA_SECTIONS, NULL };
6c5bd235b   Sam Ravnborg   kbuild: check sec...
895

6c5bd235b   Sam Ravnborg   kbuild: check sec...
896
897
  
  /* symbols in .data that may refer to init/exit sections */
af92a82d0   Uwe Kleine-König   modpost: make sym...
898
899
900
901
902
903
904
905
906
  #define DEFAULT_SYMBOL_WHITE_LIST					\
  	"*driver",							\
  	"*_template", /* scsi uses *_template a lot */			\
  	"*_timer",    /* arm uses ops structures named _timer a lot */	\
  	"*_sht",      /* scsi also used *_sht to some extent */		\
  	"*_ops",							\
  	"*_probe",							\
  	"*_probe_one",							\
  	"*_console"
6c5bd235b   Sam Ravnborg   kbuild: check sec...
907

7a3ee7538   Mathias Krause   modpost: reduce v...
908
909
  static const char *const head_sections[] = { ".head.text*", NULL };
  static const char *const linker_symbols[] =
6c5bd235b   Sam Ravnborg   kbuild: check sec...
910
  	{ "__init_begin", "_sinittext", "_einittext", NULL };
4a3893d06   Paul Gortmaker   modpost: don't em...
911
  static const char *const optim_symbols[] = { "*.constprop.*", NULL };
6c5bd235b   Sam Ravnborg   kbuild: check sec...
912

588ccd732   Sam Ravnborg   kbuild: add verbo...
913
  enum mismatch {
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
914
915
916
917
918
919
920
921
  	TEXT_TO_ANY_INIT,
  	DATA_TO_ANY_INIT,
  	TEXT_TO_ANY_EXIT,
  	DATA_TO_ANY_EXIT,
  	XXXINIT_TO_SOME_INIT,
  	XXXEXIT_TO_SOME_EXIT,
  	ANY_INIT_TO_ANY_EXIT,
  	ANY_EXIT_TO_ANY_INIT,
588ccd732   Sam Ravnborg   kbuild: add verbo...
922
  	EXPORT_TO_INIT_EXIT,
52dc0595d   Quentin Casasnovas   modpost: handle r...
923
  	EXTABLE_TO_NON_TEXT,
588ccd732   Sam Ravnborg   kbuild: add verbo...
924
  };
e5d8f59a5   Quentin Casasnovas   modpost: document...
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
  /**
   * Describe how to match sections on different criterias:
   *
   * @fromsec: Array of sections to be matched.
   *
   * @bad_tosec: Relocations applied to a section in @fromsec to a section in
   * this array is forbidden (black-list).  Can be empty.
   *
   * @good_tosec: Relocations applied to a section in @fromsec must be
   * targetting sections in this array (white-list).  Can be empty.
   *
   * @mismatch: Type of mismatch.
   *
   * @symbol_white_list: Do not match a relocation to a symbol in this list
   * even if it is targetting a section in @bad_to_sec.
   *
   * @handler: Specific handler to call when a match is found.  If NULL,
   * default_mismatch_handler() will be called.
   *
   */
10668220a   Sam Ravnborg   kbuild: introduce...
945
946
  struct sectioncheck {
  	const char *fromsec[20];
050e57fd5   Quentin Casasnovas   modpost: add stri...
947
948
  	const char *bad_tosec[20];
  	const char *good_tosec[20];
588ccd732   Sam Ravnborg   kbuild: add verbo...
949
  	enum mismatch mismatch;
af92a82d0   Uwe Kleine-König   modpost: make sym...
950
  	const char *symbol_white_list[20];
644e8f14c   Quentin Casasnovas   modpost: add hand...
951
952
953
  	void (*handler)(const char *modname, struct elf_info *elf,
  			const struct sectioncheck* const mismatch,
  			Elf_Rela *r, Elf_Sym *sym, const char *fromsec);
10668220a   Sam Ravnborg   kbuild: introduce...
954
  };
52dc0595d   Quentin Casasnovas   modpost: handle r...
955
956
957
958
  static void extable_mismatch_handler(const char *modname, struct elf_info *elf,
  				     const struct sectioncheck* const mismatch,
  				     Elf_Rela *r, Elf_Sym *sym,
  				     const char *fromsec);
7a3ee7538   Mathias Krause   modpost: reduce v...
959
  static const struct sectioncheck sectioncheck[] = {
10668220a   Sam Ravnborg   kbuild: introduce...
960
961
962
963
  /* Do not reference init/exit code/data from
   * normal code and data
   */
  {
588ccd732   Sam Ravnborg   kbuild: add verbo...
964
  	.fromsec = { TEXT_SECTIONS, NULL },
050e57fd5   Quentin Casasnovas   modpost: add stri...
965
  	.bad_tosec = { ALL_INIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
966
  	.mismatch = TEXT_TO_ANY_INIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
967
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
588ccd732   Sam Ravnborg   kbuild: add verbo...
968
969
970
  },
  {
  	.fromsec = { DATA_SECTIONS, NULL },
050e57fd5   Quentin Casasnovas   modpost: add stri...
971
  	.bad_tosec = { ALL_XXXINIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
972
  	.mismatch = DATA_TO_ANY_INIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
973
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
588ccd732   Sam Ravnborg   kbuild: add verbo...
974
975
  },
  {
0db252452   Uwe Kleine-König   modpost: don't al...
976
  	.fromsec = { DATA_SECTIONS, NULL },
050e57fd5   Quentin Casasnovas   modpost: add stri...
977
  	.bad_tosec = { INIT_SECTIONS, NULL },
0db252452   Uwe Kleine-König   modpost: don't al...
978
979
980
981
982
983
984
  	.mismatch = DATA_TO_ANY_INIT,
  	.symbol_white_list = {
  		"*_template", "*_timer", "*_sht", "*_ops",
  		"*_probe", "*_probe_one", "*_console", NULL
  	},
  },
  {
588ccd732   Sam Ravnborg   kbuild: add verbo...
985
  	.fromsec = { TEXT_SECTIONS, NULL },
050e57fd5   Quentin Casasnovas   modpost: add stri...
986
  	.bad_tosec = { ALL_EXIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
987
  	.mismatch = TEXT_TO_ANY_EXIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
988
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
588ccd732   Sam Ravnborg   kbuild: add verbo...
989
990
991
  },
  {
  	.fromsec = { DATA_SECTIONS, NULL },
050e57fd5   Quentin Casasnovas   modpost: add stri...
992
  	.bad_tosec = { ALL_EXIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
993
  	.mismatch = DATA_TO_ANY_EXIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
994
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
eb8f68904   Sam Ravnborg   Use separate sect...
995
  },
e24f66288   Paul Gortmaker   modpost: remove a...
996
  /* Do not reference init code/data from meminit code/data */
eb8f68904   Sam Ravnborg   Use separate sect...
997
  {
4a31a229f   Uwe Kleine-König   modpost: define A...
998
  	.fromsec = { ALL_XXXINIT_SECTIONS, NULL },
050e57fd5   Quentin Casasnovas   modpost: add stri...
999
  	.bad_tosec = { INIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1000
  	.mismatch = XXXINIT_TO_SOME_INIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
1001
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
eb8f68904   Sam Ravnborg   Use separate sect...
1002
  },
e24f66288   Paul Gortmaker   modpost: remove a...
1003
  /* Do not reference exit code/data from memexit code/data */
eb8f68904   Sam Ravnborg   Use separate sect...
1004
  {
4a31a229f   Uwe Kleine-König   modpost: define A...
1005
  	.fromsec = { ALL_XXXEXIT_SECTIONS, NULL },
050e57fd5   Quentin Casasnovas   modpost: add stri...
1006
  	.bad_tosec = { EXIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1007
  	.mismatch = XXXEXIT_TO_SOME_EXIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
1008
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
10668220a   Sam Ravnborg   kbuild: introduce...
1009
1010
1011
  },
  /* Do not use exit code/data from init code */
  {
eb8f68904   Sam Ravnborg   Use separate sect...
1012
  	.fromsec = { ALL_INIT_SECTIONS, NULL },
050e57fd5   Quentin Casasnovas   modpost: add stri...
1013
  	.bad_tosec = { ALL_EXIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1014
  	.mismatch = ANY_INIT_TO_ANY_EXIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
1015
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
10668220a   Sam Ravnborg   kbuild: introduce...
1016
1017
1018
  },
  /* Do not use init code/data from exit code */
  {
eb8f68904   Sam Ravnborg   Use separate sect...
1019
  	.fromsec = { ALL_EXIT_SECTIONS, NULL },
050e57fd5   Quentin Casasnovas   modpost: add stri...
1020
  	.bad_tosec = { ALL_INIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1021
  	.mismatch = ANY_EXIT_TO_ANY_INIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
1022
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
10668220a   Sam Ravnborg   kbuild: introduce...
1023
  },
bb15d8db7   Sebastian Andrzej Siewior   scripts/modpost: ...
1024
1025
  {
  	.fromsec = { ALL_PCI_INIT_SECTIONS, NULL },
050e57fd5   Quentin Casasnovas   modpost: add stri...
1026
  	.bad_tosec = { INIT_SECTIONS, NULL },
bb15d8db7   Sebastian Andrzej Siewior   scripts/modpost: ...
1027
1028
1029
  	.mismatch = ANY_INIT_TO_ANY_EXIT,
  	.symbol_white_list = { NULL },
  },
10668220a   Sam Ravnborg   kbuild: introduce...
1030
1031
1032
  /* Do not export init/exit functions or data */
  {
  	.fromsec = { "__ksymtab*", NULL },
050e57fd5   Quentin Casasnovas   modpost: add stri...
1033
  	.bad_tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
af92a82d0   Uwe Kleine-König   modpost: make sym...
1034
1035
  	.mismatch = EXPORT_TO_INIT_EXIT,
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
52dc0595d   Quentin Casasnovas   modpost: handle r...
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
  },
  {
  	.fromsec = { "__ex_table", NULL },
  	/* If you're adding any new black-listed sections in here, consider
  	 * adding a special 'printer' for them in scripts/check_extable.
  	 */
  	.bad_tosec = { ".altinstr_replacement", NULL },
  	.good_tosec = {ALL_TEXT_SECTIONS , NULL},
  	.mismatch = EXTABLE_TO_NON_TEXT,
  	.handler = extable_mismatch_handler,
10668220a   Sam Ravnborg   kbuild: introduce...
1046
1047
  }
  };
0d2a636ee   Uwe Kleine-König   modpost: pass aro...
1048
1049
  static const struct sectioncheck *section_mismatch(
  		const char *fromsec, const char *tosec)
10668220a   Sam Ravnborg   kbuild: introduce...
1050
1051
1052
1053
  {
  	int i;
  	int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck);
  	const struct sectioncheck *check = &sectioncheck[0];
c5c3439af   Quentin Casasnovas   modpost: do not t...
1054
1055
1056
  	/*
  	 * The target section could be the SHT_NUL section when we're
  	 * handling relocations to un-resolved symbols, trying to match it
739d875dd   David Howells   mn10300: Remove t...
1057
1058
  	 * doesn't make much sense and causes build failures on parisc
  	 * architectures.
c5c3439af   Quentin Casasnovas   modpost: do not t...
1059
1060
1061
  	 */
  	if (*tosec == '\0')
  		return NULL;
10668220a   Sam Ravnborg   kbuild: introduce...
1062
  	for (i = 0; i < elems; i++) {
050e57fd5   Quentin Casasnovas   modpost: add stri...
1063
1064
1065
1066
1067
1068
  		if (match(fromsec, check->fromsec)) {
  			if (check->bad_tosec[0] && match(tosec, check->bad_tosec))
  				return check;
  			if (check->good_tosec[0] && !match(tosec, check->good_tosec))
  				return check;
  		}
10668220a   Sam Ravnborg   kbuild: introduce...
1069
1070
  		check++;
  	}
0d2a636ee   Uwe Kleine-König   modpost: pass aro...
1071
  	return NULL;
10668220a   Sam Ravnborg   kbuild: introduce...
1072
  }
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1073
1074
  /**
   * Whitelist to allow certain references to pass with no warning.
0e0d314e6   Sam Ravnborg   kbuild: introduce...
1075
   *
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1076
1077
1078
1079
1080
1081
1082
   * Pattern 1:
   *   If a module parameter is declared __initdata and permissions=0
   *   then this is legal despite the warning generated.
   *   We cannot see value of permissions here, so just ignore
   *   this pattern.
   *   The pattern is identified by:
   *   tosec   = .init.data
9209aed07   Sam Ravnborg   kbuild: kill fals...
1083
   *   fromsec = .data*
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1084
   *   atsym   =__param*
62070fa42   Sam Ravnborg   kbuild: kill trai...
1085
   *
6a841528d   Rusty Russell   param: silence .i...
1086
1087
1088
1089
1090
1091
1092
   * Pattern 1a:
   *   module_param_call() ops can refer to __init set function if permissions=0
   *   The pattern is identified by:
   *   tosec   = .init.text
   *   fromsec = .data*
   *   atsym   = __param_ops_*
   *
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1093
   * Pattern 2:
72ee59b57   Randy Dunlap   kbuild modpost - ...
1094
   *   Many drivers utilise a *driver container with references to
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1095
   *   add, remove, probe functions etc.
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1096
   *   the pattern is identified by:
83cda2bb3   Sam Ravnborg   kbuild: be more f...
1097
1098
   *   tosec   = init or exit section
   *   fromsec = data section
df578e7d8   Sam Ravnborg   kbuild: clean up ...
1099
1100
   *   atsym = *driver, *_template, *_sht, *_ops, *_probe,
   *           *probe_one, *_console, *_timer
ee6a8545a   Vivek Goyal   [PATCH] x86-64: M...
1101
1102
   *
   * Pattern 3:
c993971f4   Sam Ravnborg   kbuild: fix comme...
1103
   *   Whitelist all references from .head.text to any init section
9bf8cb9b7   Sam Ravnborg   kbuild: fix warni...
1104
   *
1d8af559f   Sam Ravnborg   kbuild: consolida...
1105
   * Pattern 4:
ee6a8545a   Vivek Goyal   [PATCH] x86-64: M...
1106
1107
1108
1109
1110
1111
1112
   *   Some symbols belong to init section but still it is ok to reference
   *   these from non-init sections as these symbols don't have any memory
   *   allocated for them and symbol address and value are same. So even
   *   if init section is freed, its ok to reference those symbols.
   *   For ex. symbols marking the init section boundaries.
   *   This pattern is identified by
   *   refsymname = __init_begin, _sinittext, _einittext
9bf8cb9b7   Sam Ravnborg   kbuild: fix warni...
1113
   *
4a3893d06   Paul Gortmaker   modpost: don't em...
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
   * Pattern 5:
   *   GCC may optimize static inlines when fed constant arg(s) resulting
   *   in functions like cpumask_empty() -- generating an associated symbol
   *   cpumask_empty.constprop.3 that appears in the audit.  If the const that
   *   is passed in comes from __init, like say nmi_ipi_mask, we get a
   *   meaningless section warning.  May need to add isra symbols too...
   *   This pattern is identified by
   *   tosec   = init section
   *   fromsec = text section
   *   refsymname = *.constprop.*
   *
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1125
   **/
af92a82d0   Uwe Kleine-König   modpost: make sym...
1126
1127
  static int secref_whitelist(const struct sectioncheck *mismatch,
  			    const char *fromsec, const char *fromsym,
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1128
  			    const char *tosec, const char *tosym)
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1129
  {
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1130
  	/* Check for pattern 1 */
6c5bd235b   Sam Ravnborg   kbuild: check sec...
1131
1132
  	if (match(tosec, init_data_sections) &&
  	    match(fromsec, data_sections) &&
d62c47652   Masahiro Yamada   modpost: use strs...
1133
  	    strstarts(fromsym, "__param"))
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1134
  		return 0;
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1135

6a841528d   Rusty Russell   param: silence .i...
1136
1137
1138
  	/* Check for pattern 1a */
  	if (strcmp(tosec, ".init.text") == 0 &&
  	    match(fromsec, data_sections) &&
d62c47652   Masahiro Yamada   modpost: use strs...
1139
  	    strstarts(fromsym, "__param_ops_"))
6a841528d   Rusty Russell   param: silence .i...
1140
  		return 0;
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1141
  	/* Check for pattern 2 */
6c5bd235b   Sam Ravnborg   kbuild: check sec...
1142
1143
  	if (match(tosec, init_exit_sections) &&
  	    match(fromsec, data_sections) &&
af92a82d0   Uwe Kleine-König   modpost: make sym...
1144
  	    match(fromsym, mismatch->symbol_white_list))
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1145
  		return 0;
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1146

9bf8cb9b7   Sam Ravnborg   kbuild: fix warni...
1147
  	/* Check for pattern 3 */
6c5bd235b   Sam Ravnborg   kbuild: check sec...
1148
1149
  	if (match(fromsec, head_sections) &&
  	    match(tosec, init_sections))
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1150
  		return 0;
9bf8cb9b7   Sam Ravnborg   kbuild: fix warni...
1151

1d8af559f   Sam Ravnborg   kbuild: consolida...
1152
  	/* Check for pattern 4 */
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1153
1154
  	if (match(tosym, linker_symbols))
  		return 0;
9bf8cb9b7   Sam Ravnborg   kbuild: fix warni...
1155

4a3893d06   Paul Gortmaker   modpost: don't em...
1156
1157
1158
1159
1160
  	/* Check for pattern 5 */
  	if (match(fromsec, text_sections) &&
  	    match(tosec, init_sections) &&
  	    match(fromsym, optim_symbols))
  		return 0;
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1161
  	return 1;
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1162
  }
b6293e6c9   Sami Tolvanen   modpost: validate...
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
  static inline int is_arm_mapping_symbol(const char *str)
  {
  	return str[0] == '$' && strchr("axtd", str[1])
  	       && (str[2] == '\0' || str[2] == '.');
  }
  
  /*
   * If there's no name there, ignore it; likewise, ignore it if it's
   * one of the magic symbols emitted used by current ARM tools.
   *
   * Otherwise if find_symbols_between() returns those symbols, they'll
   * fail the whitelist tests and cause lots of false alarms ... fixable
   * only by merging __exit and __init sections into __text, bloating
   * the kernel (which is especially evil on embedded platforms).
   */
  static inline int is_valid_name(struct elf_info *elf, Elf_Sym *sym)
  {
  	const char *name = elf->strtab + sym->st_name;
  
  	if (!name || !strlen(name))
  		return 0;
  	return !is_arm_mapping_symbol(name);
  }
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1186
  /**
93684d3b8   Sam Ravnborg   kbuild: include s...
1187
1188
1189
1190
1191
1192
   * Find symbol based on relocation record info.
   * In some cases the symbol supplied is a valid symbol so
   * return refsym. If st_name != 0 we assume this is a valid symbol.
   * In other cases the symbol needs to be looked up in the symbol table
   * based on section and address.
   *  **/
9ad21c3f3   Sam Ravnborg   kbuild: try harde...
1193
  static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,
93684d3b8   Sam Ravnborg   kbuild: include s...
1194
1195
1196
  				Elf_Sym *relsym)
  {
  	Elf_Sym *sym;
9ad21c3f3   Sam Ravnborg   kbuild: try harde...
1197
1198
1199
  	Elf_Sym *near = NULL;
  	Elf64_Sword distance = 20;
  	Elf64_Sword d;
1ce53adf1   Denys Vlasenko   modpost: support ...
1200
  	unsigned int relsym_secindex;
93684d3b8   Sam Ravnborg   kbuild: include s...
1201
1202
1203
  
  	if (relsym->st_name != 0)
  		return relsym;
1ce53adf1   Denys Vlasenko   modpost: support ...
1204
1205
  
  	relsym_secindex = get_secindex(elf, relsym);
93684d3b8   Sam Ravnborg   kbuild: include s...
1206
  	for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
1ce53adf1   Denys Vlasenko   modpost: support ...
1207
  		if (get_secindex(elf, sym) != relsym_secindex)
93684d3b8   Sam Ravnborg   kbuild: include s...
1208
  			continue;
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1209
1210
  		if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
  			continue;
b6293e6c9   Sami Tolvanen   modpost: validate...
1211
1212
  		if (!is_valid_name(elf, sym))
  			continue;
93684d3b8   Sam Ravnborg   kbuild: include s...
1213
1214
  		if (sym->st_value == addr)
  			return sym;
9ad21c3f3   Sam Ravnborg   kbuild: try harde...
1215
1216
1217
1218
1219
1220
1221
1222
  		/* Find a symbol nearby - addr are maybe negative */
  		d = sym->st_value - addr;
  		if (d < 0)
  			d = addr - sym->st_value;
  		if (d < distance) {
  			distance = d;
  			near = sym;
  		}
93684d3b8   Sam Ravnborg   kbuild: include s...
1223
  	}
9ad21c3f3   Sam Ravnborg   kbuild: try harde...
1224
1225
1226
1227
1228
  	/* We need a close match */
  	if (distance < 20)
  		return near;
  	else
  		return NULL;
93684d3b8   Sam Ravnborg   kbuild: include s...
1229
  }
b39927cf4   Sam Ravnborg   kbuild: check for...
1230
  /*
43c74d179   Sam Ravnborg   kbuild: in the se...
1231
1232
1233
1234
   * Find symbols before or equal addr and after addr - in the section sec.
   * If we find two symbols with equal offset prefer one with a valid name.
   * The ELF format may have a better way to detect what type of symbol
   * it is, but this works for now.
b39927cf4   Sam Ravnborg   kbuild: check for...
1235
   **/
157c23c80   Sam Ravnborg   kbuild: use simpl...
1236
1237
  static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
  				 const char *sec)
b39927cf4   Sam Ravnborg   kbuild: check for...
1238
1239
  {
  	Elf_Sym *sym;
157c23c80   Sam Ravnborg   kbuild: use simpl...
1240
  	Elf_Sym *near = NULL;
157c23c80   Sam Ravnborg   kbuild: use simpl...
1241
  	Elf_Addr distance = ~0;
62070fa42   Sam Ravnborg   kbuild: kill trai...
1242

b39927cf4   Sam Ravnborg   kbuild: check for...
1243
1244
  	for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
  		const char *symsec;
1ce53adf1   Denys Vlasenko   modpost: support ...
1245
  		if (is_shndx_special(sym->st_shndx))
b39927cf4   Sam Ravnborg   kbuild: check for...
1246
  			continue;
1ce53adf1   Denys Vlasenko   modpost: support ...
1247
  		symsec = sec_name(elf, get_secindex(elf, sym));
b39927cf4   Sam Ravnborg   kbuild: check for...
1248
1249
  		if (strcmp(symsec, sec) != 0)
  			continue;
da68d61f8   David Brownell   [PATCH] remove mo...
1250
1251
  		if (!is_valid_name(elf, sym))
  			continue;
b39927cf4   Sam Ravnborg   kbuild: check for...
1252
  		if (sym->st_value <= addr) {
157c23c80   Sam Ravnborg   kbuild: use simpl...
1253
1254
1255
1256
1257
  			if ((addr - sym->st_value) < distance) {
  				distance = addr - sym->st_value;
  				near = sym;
  			} else if ((addr - sym->st_value) == distance) {
  				near = sym;
43c74d179   Sam Ravnborg   kbuild: in the se...
1258
  			}
b39927cf4   Sam Ravnborg   kbuild: check for...
1259
1260
  		}
  	}
157c23c80   Sam Ravnborg   kbuild: use simpl...
1261
  	return near;
b39927cf4   Sam Ravnborg   kbuild: check for...
1262
  }
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1263
  /*
588ccd732   Sam Ravnborg   kbuild: add verbo...
1264
1265
   * Convert a section name to the function/data attribute
   * .init.text => __init
588ccd732   Sam Ravnborg   kbuild: add verbo...
1266
1267
   * .memexitconst => __memconst
   * etc.
cbcf14a94   Andy Shevchenko   scripts/mod/modpo...
1268
1269
1270
   *
   * The memory of returned value has been allocated on a heap. The user of this
   * method should free it after usage.
588ccd732   Sam Ravnborg   kbuild: add verbo...
1271
1272
1273
1274
  */
  static char *sec2annotation(const char *s)
  {
  	if (match(s, init_exit_sections)) {
1f3aa9002   Randy Dunlap   scripts: modpost:...
1275
  		char *p = NOFAIL(malloc(20));
588ccd732   Sam Ravnborg   kbuild: add verbo...
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
  		char *r = p;
  
  		*p++ = '_';
  		*p++ = '_';
  		if (*s == '.')
  			s++;
  		while (*s && *s != '.')
  			*p++ = *s++;
  		*p = '\0';
  		if (*s == '.')
  			s++;
  		if (strstr(s, "rodata") != NULL)
  			strcat(p, "const ");
  		else if (strstr(s, "data") != NULL)
  			strcat(p, "data ");
  		else
  			strcat(p, " ");
cbcf14a94   Andy Shevchenko   scripts/mod/modpo...
1293
  		return r;
588ccd732   Sam Ravnborg   kbuild: add verbo...
1294
  	} else {
1f3aa9002   Randy Dunlap   scripts: modpost:...
1295
  		return NOFAIL(strdup(""));
588ccd732   Sam Ravnborg   kbuild: add verbo...
1296
1297
1298
1299
1300
1301
1302
1303
  	}
  }
  
  static int is_function(Elf_Sym *sym)
  {
  	if (sym)
  		return ELF_ST_TYPE(sym->st_info) == STT_FUNC;
  	else
f666751a0   Sam Ravnborg   kbuild/modpost: i...
1304
  		return -1;
588ccd732   Sam Ravnborg   kbuild: add verbo...
1305
  }
00759c0ea   Randy Dunlap   modpost: fix trai...
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
  static void print_section_list(const char * const list[20])
  {
  	const char *const *s = list;
  
  	while (*s) {
  		fprintf(stderr, "%s", *s);
  		s++;
  		if (*s)
  			fprintf(stderr, ", ");
  	}
  	fprintf(stderr, "
  ");
  }
356ad5381   Quentin Casasnovas   modpost: factoriz...
1319
1320
1321
1322
1323
1324
1325
1326
  static inline void get_pretty_name(int is_func, const char** name, const char** name_p)
  {
  	switch (is_func) {
  	case 0:	*name = "variable"; *name_p = ""; break;
  	case 1:	*name = "function"; *name_p = "()"; break;
  	default: *name = "(unknown reference)"; *name_p = ""; break;
  	}
  }
588ccd732   Sam Ravnborg   kbuild: add verbo...
1327
  /*
b39927cf4   Sam Ravnborg   kbuild: check for...
1328
1329
   * Print a warning about a section mismatch.
   * Try to find symbols near it so user can find it.
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1330
   * Check whitelist before warning - it may be a false positive.
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1331
   */
0d2a636ee   Uwe Kleine-König   modpost: pass aro...
1332
1333
  static void report_sec_mismatch(const char *modname,
  				const struct sectioncheck *mismatch,
bb66fc671   Masahiro Yamada   kbuild: trivial -...
1334
1335
1336
1337
1338
1339
  				const char *fromsec,
  				unsigned long long fromaddr,
  				const char *fromsym,
  				int from_is_func,
  				const char *tosec, const char *tosym,
  				int to_is_func)
588ccd732   Sam Ravnborg   kbuild: add verbo...
1340
1341
1342
  {
  	const char *from, *from_p;
  	const char *to, *to_p;
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1343
1344
  	char *prl_from;
  	char *prl_to;
f666751a0   Sam Ravnborg   kbuild/modpost: i...
1345

e5f95c8b7   Sam Ravnborg   kbuild: print onl...
1346
1347
1348
  	sec_mismatch_count++;
  	if (!sec_mismatch_verbose)
  		return;
356ad5381   Quentin Casasnovas   modpost: factoriz...
1349
1350
  	get_pretty_name(from_is_func, &from, &from_p);
  	get_pretty_name(to_is_func, &to, &to_p);
7c0ac495e   Geert Uytterhoeven   kbuild/modpost: U...
1351
1352
1353
1354
1355
  	warn("%s(%s+0x%llx): Section mismatch in reference from the %s %s%s "
  	     "to the %s %s:%s%s
  ",
  	     modname, fromsec, fromaddr, from, fromsym, from_p, to, tosec,
  	     tosym, to_p);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1356

0d2a636ee   Uwe Kleine-König   modpost: pass aro...
1357
  	switch (mismatch->mismatch) {
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1358
  	case TEXT_TO_ANY_INIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1359
1360
  		prl_from = sec2annotation(fromsec);
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1361
  		fprintf(stderr,
f666751a0   Sam Ravnborg   kbuild/modpost: i...
1362
1363
  		"The function %s%s() references
  "
588ccd732   Sam Ravnborg   kbuild: add verbo...
1364
1365
1366
1367
1368
1369
  		"the %s %s%s%s.
  "
  		"This is often because %s lacks a %s
  "
  		"annotation or the annotation of %s is wrong.
  ",
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1370
1371
1372
1373
1374
  		prl_from, fromsym,
  		to, prl_to, tosym, to_p,
  		fromsym, prl_to, tosym);
  		free(prl_from);
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1375
  		break;
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1376
  	case DATA_TO_ANY_INIT: {
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1377
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1378
1379
1380
1381
1382
1383
1384
  		fprintf(stderr,
  		"The variable %s references
  "
  		"the %s %s%s%s
  "
  		"If the reference is valid then annotate the
  "
8b8b76c04   Sam Ravnborg   kbuild: add hint ...
1385
  		"variable with __init* or __refdata (see linux/init.h) "
588ccd732   Sam Ravnborg   kbuild: add verbo...
1386
1387
  		"or name the variable:
  ",
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1388
  		fromsym, to, prl_to, tosym, to_p);
00759c0ea   Randy Dunlap   modpost: fix trai...
1389
  		print_section_list(mismatch->symbol_white_list);
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1390
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1391
  		break;
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1392
  	}
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1393
  	case TEXT_TO_ANY_EXIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1394
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1395
1396
1397
1398
1399
1400
1401
  		fprintf(stderr,
  		"The function %s() references a %s in an exit section.
  "
  		"Often the %s %s%s has valid usage outside the exit section
  "
  		"and the fix is to remove the %sannotation of %s.
  ",
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1402
1403
  		fromsym, to, to, tosym, to_p, prl_to, tosym);
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1404
  		break;
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1405
  	case DATA_TO_ANY_EXIT: {
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1406
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
  		fprintf(stderr,
  		"The variable %s references
  "
  		"the %s %s%s%s
  "
  		"If the reference is valid then annotate the
  "
  		"variable with __exit* (see linux/init.h) or "
  		"name the variable:
  ",
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1417
  		fromsym, to, prl_to, tosym, to_p);
00759c0ea   Randy Dunlap   modpost: fix trai...
1418
  		print_section_list(mismatch->symbol_white_list);
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1419
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1420
1421
  		break;
  	}
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1422
1423
  	case XXXINIT_TO_SOME_INIT:
  	case XXXEXIT_TO_SOME_EXIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1424
1425
  		prl_from = sec2annotation(fromsec);
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1426
1427
1428
1429
1430
1431
1432
1433
1434
  		fprintf(stderr,
  		"The %s %s%s%s references
  "
  		"a %s %s%s%s.
  "
  		"If %s is only used by %s then
  "
  		"annotate %s with a matching annotation.
  ",
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1435
1436
  		from, prl_from, fromsym, from_p,
  		to, prl_to, tosym, to_p,
b1d2675a6   Geert Uytterhoeven   kbuild: fix rever...
1437
  		tosym, fromsym, tosym);
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1438
1439
  		free(prl_from);
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1440
  		break;
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1441
  	case ANY_INIT_TO_ANY_EXIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1442
1443
  		prl_from = sec2annotation(fromsec);
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
  		fprintf(stderr,
  		"The %s %s%s%s references
  "
  		"a %s %s%s%s.
  "
  		"This is often seen when error handling "
  		"in the init function
  "
  		"uses functionality in the exit path.
  "
  		"The fix is often to remove the %sannotation of
  "
  		"%s%s so it may be used outside an exit section.
  ",
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1458
1459
  		from, prl_from, fromsym, from_p,
  		to, prl_to, tosym, to_p,
5003bab82   Andrew Morton   fix "scripts/mod/...
1460
  		prl_to, tosym, to_p);
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1461
1462
  		free(prl_from);
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1463
  		break;
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1464
  	case ANY_EXIT_TO_ANY_INIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1465
1466
  		prl_from = sec2annotation(fromsec);
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
  		fprintf(stderr,
  		"The %s %s%s%s references
  "
  		"a %s %s%s%s.
  "
  		"This is often seen when error handling "
  		"in the exit function
  "
  		"uses functionality in the init path.
  "
  		"The fix is often to remove the %sannotation of
  "
  		"%s%s so it may be used outside an init section.
  ",
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1481
1482
1483
1484
1485
  		from, prl_from, fromsym, from_p,
  		to, prl_to, tosym, to_p,
  		prl_to, tosym, to_p);
  		free(prl_from);
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1486
1487
  		break;
  	case EXPORT_TO_INIT_EXIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1488
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1489
1490
1491
1492
1493
1494
  		fprintf(stderr,
  		"The symbol %s is exported and annotated %s
  "
  		"Fix this by removing the %sannotation of %s "
  		"or drop the export.
  ",
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1495
1496
  		tosym, prl_to, prl_to, tosym);
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1497
  		break;
52dc0595d   Quentin Casasnovas   modpost: handle r...
1498
1499
1500
1501
  	case EXTABLE_TO_NON_TEXT:
  		fatal("There's a special handler for this mismatch type, "
  		      "we should never get here.");
  		break;
588ccd732   Sam Ravnborg   kbuild: add verbo...
1502
1503
1504
  	}
  	fprintf(stderr, "
  ");
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1505
  }
644e8f14c   Quentin Casasnovas   modpost: add hand...
1506
1507
1508
  static void default_mismatch_handler(const char *modname, struct elf_info *elf,
  				     const struct sectioncheck* const mismatch,
  				     Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1509
1510
  {
  	const char *tosec;
644e8f14c   Quentin Casasnovas   modpost: add hand...
1511
1512
1513
1514
  	Elf_Sym *to;
  	Elf_Sym *from;
  	const char *tosym;
  	const char *fromsym;
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1515

644e8f14c   Quentin Casasnovas   modpost: add hand...
1516
1517
  	from = find_elf_symbol2(elf, r->r_offset, fromsec);
  	fromsym = sym_name(elf, from);
644e8f14c   Quentin Casasnovas   modpost: add hand...
1518

d62c47652   Masahiro Yamada   modpost: use strs...
1519
  	if (strstarts(fromsym, "reference___initcall"))
644e8f14c   Quentin Casasnovas   modpost: add hand...
1520
  		return;
c7a65e064   Quentin Casasnovas   modpost: mismatch...
1521
1522
1523
  	tosec = sec_name(elf, get_secindex(elf, sym));
  	to = find_elf_symbol(elf, r->r_addend, sym);
  	tosym = sym_name(elf, to);
644e8f14c   Quentin Casasnovas   modpost: add hand...
1524
1525
1526
1527
1528
1529
1530
1531
1532
  	/* check whitelist - we may ignore it */
  	if (secref_whitelist(mismatch,
  			     fromsec, fromsym, tosec, tosym)) {
  		report_sec_mismatch(modname, mismatch,
  				    fromsec, r->r_offset, fromsym,
  				    is_function(from), tosec, tosym,
  				    is_function(to));
  	}
  }
52dc0595d   Quentin Casasnovas   modpost: handle r...
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
  static int is_executable_section(struct elf_info* elf, unsigned int section_index)
  {
  	if (section_index > elf->num_sections)
  		fatal("section_index is outside elf->num_sections!
  ");
  
  	return ((elf->sechdrs[section_index].sh_flags & SHF_EXECINSTR) == SHF_EXECINSTR);
  }
  
  /*
   * We rely on a gross hack in section_rel[a]() calling find_extable_entry_size()
   * to know the sizeof(struct exception_table_entry) for the target architecture.
   */
  static unsigned int extable_entry_size = 0;
e84048aa1   Quentin Casasnovas   modpost: fix exta...
1547
  static void find_extable_entry_size(const char* const sec, const Elf_Rela* r)
52dc0595d   Quentin Casasnovas   modpost: handle r...
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
  {
  	/*
  	 * If we're currently checking the second relocation within __ex_table,
  	 * that relocation offset tells us the offsetof(struct
  	 * exception_table_entry, fixup) which is equal to sizeof(struct
  	 * exception_table_entry) divided by two.  We use that to our advantage
  	 * since there's no portable way to get that size as every architecture
  	 * seems to go with different sized types.  Not pretty but better than
  	 * hard-coding the size for every architecture..
  	 */
e84048aa1   Quentin Casasnovas   modpost: fix exta...
1558
  	if (!extable_entry_size)
52dc0595d   Quentin Casasnovas   modpost: handle r...
1559
1560
  		extable_entry_size = r->r_offset * 2;
  }
e84048aa1   Quentin Casasnovas   modpost: fix exta...
1561

52dc0595d   Quentin Casasnovas   modpost: handle r...
1562
1563
  static inline bool is_extable_fault_address(Elf_Rela *r)
  {
d3df4de7e   Quentin Casasnovas   modpost: fix inve...
1564
1565
1566
1567
1568
1569
  	/*
  	 * extable_entry_size is only discovered after we've handled the
  	 * _second_ relocation in __ex_table, so only abort when we're not
  	 * handling the first reloc and extable_entry_size is zero.
  	 */
  	if (r->r_offset && extable_entry_size == 0)
52dc0595d   Quentin Casasnovas   modpost: handle r...
1570
1571
1572
1573
1574
1575
  		fatal("extable_entry size hasn't been discovered!
  ");
  
  	return ((r->r_offset == 0) ||
  		(r->r_offset % extable_entry_size == 0));
  }
e84048aa1   Quentin Casasnovas   modpost: fix exta...
1576
1577
  #define is_second_extable_reloc(Start, Cur, Sec)			\
  	(((Cur) == (Start) + 1) && (strcmp("__ex_table", (Sec)) == 0))
52dc0595d   Quentin Casasnovas   modpost: handle r...
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
  static void report_extable_warnings(const char* modname, struct elf_info* elf,
  				    const struct sectioncheck* const mismatch,
  				    Elf_Rela* r, Elf_Sym* sym,
  				    const char* fromsec, const char* tosec)
  {
  	Elf_Sym* fromsym = find_elf_symbol2(elf, r->r_offset, fromsec);
  	const char* fromsym_name = sym_name(elf, fromsym);
  	Elf_Sym* tosym = find_elf_symbol(elf, r->r_addend, sym);
  	const char* tosym_name = sym_name(elf, tosym);
  	const char* from_pretty_name;
  	const char* from_pretty_name_p;
  	const char* to_pretty_name;
  	const char* to_pretty_name_p;
  
  	get_pretty_name(is_function(fromsym),
  			&from_pretty_name, &from_pretty_name_p);
  	get_pretty_name(is_function(tosym),
  			&to_pretty_name, &to_pretty_name_p);
  
  	warn("%s(%s+0x%lx): Section mismatch in reference"
  	     " from the %s %s%s to the %s %s:%s%s
  ",
  	     modname, fromsec, (long)r->r_offset, from_pretty_name,
  	     fromsym_name, from_pretty_name_p,
  	     to_pretty_name, tosec, tosym_name, to_pretty_name_p);
  
  	if (!match(tosec, mismatch->bad_tosec) &&
  	    is_executable_section(elf, get_secindex(elf, sym)))
  		fprintf(stderr,
  			"The relocation at %s+0x%lx references
  "
  			"section \"%s\" which is not in the list of
  "
  			"authorized sections.  If you're adding a new section
  "
  			"and/or if this reference is valid, add \"%s\" to the
  "
  			"list of authorized sections to jump to on fault.
  "
  			"This can be achieved by adding \"%s\" to 
  "
  			"OTHER_TEXT_SECTIONS in scripts/mod/modpost.c.
  ",
  			fromsec, (long)r->r_offset, tosec, tosec, tosec);
  }
  
  static void extable_mismatch_handler(const char* modname, struct elf_info *elf,
  				     const struct sectioncheck* const mismatch,
  				     Elf_Rela* r, Elf_Sym* sym,
  				     const char *fromsec)
  {
  	const char* tosec = sec_name(elf, get_secindex(elf, sym));
  
  	sec_mismatch_count++;
  
  	if (sec_mismatch_verbose)
  		report_extable_warnings(modname, elf, mismatch, r, sym,
  					fromsec, tosec);
  
  	if (match(tosec, mismatch->bad_tosec))
  		fatal("The relocation at %s+0x%lx references
  "
  		      "section \"%s\" which is black-listed.
  "
  		      "Something is seriously wrong and should be fixed.
  "
  		      "You might get more information about where this is
  "
  		      "coming from by using scripts/check_extable.sh %s
  ",
  		      fromsec, (long)r->r_offset, tosec, modname);
  	else if (!is_executable_section(elf, get_secindex(elf, sym))) {
  		if (is_extable_fault_address(r))
  			fatal("The relocation at %s+0x%lx references
  "
  			      "section \"%s\" which is not executable, IOW
  "
  			      "it is not possible for the kernel to fault
  "
  			      "at that address.  Something is seriously wrong
  "
  			      "and should be fixed.
  ",
  			      fromsec, (long)r->r_offset, tosec);
  		else
  			fatal("The relocation at %s+0x%lx references
  "
  			      "section \"%s\" which is not executable, IOW
  "
  			      "the kernel will fault if it ever tries to
  "
  			      "jump to it.  Something is seriously wrong
  "
  			      "and should be fixed.
  ",
  			      fromsec, (long)r->r_offset, tosec);
  	}
  }
644e8f14c   Quentin Casasnovas   modpost: add hand...
1676
1677
1678
  static void check_section_mismatch(const char *modname, struct elf_info *elf,
  				   Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
  {
0cad61d7a   Luis de Bethencourt   modpost: Remove t...
1679
  	const char *tosec = sec_name(elf, get_secindex(elf, sym));
644e8f14c   Quentin Casasnovas   modpost: add hand...
1680
  	const struct sectioncheck *mismatch = section_mismatch(fromsec, tosec);
0d2a636ee   Uwe Kleine-König   modpost: pass aro...
1681
  	if (mismatch) {
644e8f14c   Quentin Casasnovas   modpost: add hand...
1682
1683
1684
1685
1686
1687
  		if (mismatch->handler)
  			mismatch->handler(modname, elf,  mismatch,
  					  r, sym, fromsec);
  		else
  			default_mismatch_handler(modname, elf, mismatch,
  						 r, sym, fromsec);
b39927cf4   Sam Ravnborg   kbuild: check for...
1688
1689
  	}
  }
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1690
  static unsigned int *reloc_location(struct elf_info *elf,
5b24c0715   Sam Ravnborg   kbuild: code refa...
1691
  				    Elf_Shdr *sechdr, Elf_Rela *r)
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1692
1693
  {
  	Elf_Shdr *sechdrs = elf->sechdrs;
6845756b2   Anders Kaseorg   modpost: Update 6...
1694
  	int section = sechdr->sh_info;
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1695
1696
  
  	return (void *)elf->hdr + sechdrs[section].sh_offset +
731ece41f   Olof Johansson   modpost: Fix addr...
1697
  		r->r_offset;
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1698
  }
5b24c0715   Sam Ravnborg   kbuild: code refa...
1699
  static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1700
1701
  {
  	unsigned int r_typ = ELF_R_TYPE(r->r_info);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1702
  	unsigned int *location = reloc_location(elf, sechdr, r);
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
  
  	switch (r_typ) {
  	case R_386_32:
  		r->r_addend = TO_NATIVE(*location);
  		break;
  	case R_386_PC32:
  		r->r_addend = TO_NATIVE(*location) + 4;
  		/* For CONFIG_RELOCATABLE=y */
  		if (elf->hdr->e_type == ET_EXEC)
  			r->r_addend += r->r_offset;
  		break;
  	}
  	return 0;
  }
6e2e340b5   Tony Lindgren   ARM: 7324/1: modp...
1717
1718
1719
1720
1721
1722
  #ifndef R_ARM_CALL
  #define R_ARM_CALL	28
  #endif
  #ifndef R_ARM_JUMP24
  #define R_ARM_JUMP24	29
  #endif
c9698e5cd   David A. Long   ARM: 7964/1: Dete...
1723
1724
1725
1726
1727
1728
1729
1730
1731
  #ifndef	R_ARM_THM_CALL
  #define	R_ARM_THM_CALL		10
  #endif
  #ifndef	R_ARM_THM_JUMP24
  #define	R_ARM_THM_JUMP24	30
  #endif
  #ifndef	R_ARM_THM_JUMP19
  #define	R_ARM_THM_JUMP19	51
  #endif
5b24c0715   Sam Ravnborg   kbuild: code refa...
1732
  static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
56a974fa2   Sam Ravnborg   kbuild: make bett...
1733
1734
1735
1736
1737
1738
  {
  	unsigned int r_typ = ELF_R_TYPE(r->r_info);
  
  	switch (r_typ) {
  	case R_ARM_ABS32:
  		/* From ARM ABI: (S + A) | T */
df578e7d8   Sam Ravnborg   kbuild: clean up ...
1739
  		r->r_addend = (int)(long)
bb66fc671   Masahiro Yamada   kbuild: trivial -...
1740
  			      (elf->symtab_start + ELF_R_SYM(r->r_info));
56a974fa2   Sam Ravnborg   kbuild: make bett...
1741
1742
  		break;
  	case R_ARM_PC24:
6e2e340b5   Tony Lindgren   ARM: 7324/1: modp...
1743
1744
  	case R_ARM_CALL:
  	case R_ARM_JUMP24:
c9698e5cd   David A. Long   ARM: 7964/1: Dete...
1745
1746
1747
  	case R_ARM_THM_CALL:
  	case R_ARM_THM_JUMP24:
  	case R_ARM_THM_JUMP19:
56a974fa2   Sam Ravnborg   kbuild: make bett...
1748
  		/* From ARM ABI: ((S + A) | T) - P */
df578e7d8   Sam Ravnborg   kbuild: clean up ...
1749
  		r->r_addend = (int)(long)(elf->hdr +
bb66fc671   Masahiro Yamada   kbuild: trivial -...
1750
1751
  			      sechdr->sh_offset +
  			      (r->r_offset - sechdr->sh_addr));
56a974fa2   Sam Ravnborg   kbuild: make bett...
1752
1753
1754
1755
1756
1757
  		break;
  	default:
  		return 1;
  	}
  	return 0;
  }
5b24c0715   Sam Ravnborg   kbuild: code refa...
1758
  static int addend_mips_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1759
1760
  {
  	unsigned int r_typ = ELF_R_TYPE(r->r_info);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1761
  	unsigned int *location = reloc_location(elf, sechdr, r);
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
  	unsigned int inst;
  
  	if (r_typ == R_MIPS_HI16)
  		return 1;	/* skip this */
  	inst = TO_NATIVE(*location);
  	switch (r_typ) {
  	case R_MIPS_LO16:
  		r->r_addend = inst & 0xffff;
  		break;
  	case R_MIPS_26:
  		r->r_addend = (inst & 0x03ffffff) << 2;
  		break;
  	case R_MIPS_32:
  		r->r_addend = inst;
  		break;
  	}
  	return 0;
  }
5b24c0715   Sam Ravnborg   kbuild: code refa...
1780
  static void section_rela(const char *modname, struct elf_info *elf,
bb66fc671   Masahiro Yamada   kbuild: trivial -...
1781
  			 Elf_Shdr *sechdr)
5b24c0715   Sam Ravnborg   kbuild: code refa...
1782
1783
1784
1785
1786
1787
  {
  	Elf_Sym  *sym;
  	Elf_Rela *rela;
  	Elf_Rela r;
  	unsigned int r_sym;
  	const char *fromsec;
5b24c0715   Sam Ravnborg   kbuild: code refa...
1788

ff13f9269   Sam Ravnborg   kbuild: introduce...
1789
  	Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset;
5b24c0715   Sam Ravnborg   kbuild: code refa...
1790
  	Elf_Rela *stop  = (void *)start + sechdr->sh_size;
ff13f9269   Sam Ravnborg   kbuild: introduce...
1791
  	fromsec = sech_name(elf, sechdr);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1792
1793
  	fromsec += strlen(".rela");
  	/* if from section (name) is know good then skip it */
b614a697d   Anders Kaseorg   kbuild, modpost: ...
1794
  	if (match(fromsec, section_white_list))
5b24c0715   Sam Ravnborg   kbuild: code refa...
1795
  		return;
e241a6303   Sam Ravnborg   kbuild: warn abou...
1796

5b24c0715   Sam Ravnborg   kbuild: code refa...
1797
1798
1799
  	for (rela = start; rela < stop; rela++) {
  		r.r_offset = TO_NATIVE(rela->r_offset);
  #if KERNEL_ELFCLASS == ELFCLASS64
ff13f9269   Sam Ravnborg   kbuild: introduce...
1800
  		if (elf->hdr->e_machine == EM_MIPS) {
5b24c0715   Sam Ravnborg   kbuild: code refa...
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
  			unsigned int r_typ;
  			r_sym = ELF64_MIPS_R_SYM(rela->r_info);
  			r_sym = TO_NATIVE(r_sym);
  			r_typ = ELF64_MIPS_R_TYPE(rela->r_info);
  			r.r_info = ELF64_R_INFO(r_sym, r_typ);
  		} else {
  			r.r_info = TO_NATIVE(rela->r_info);
  			r_sym = ELF_R_SYM(r.r_info);
  		}
  #else
  		r.r_info = TO_NATIVE(rela->r_info);
  		r_sym = ELF_R_SYM(r.r_info);
  #endif
  		r.r_addend = TO_NATIVE(rela->r_addend);
  		sym = elf->symtab_start + r_sym;
  		/* Skip special sections */
1ce53adf1   Denys Vlasenko   modpost: support ...
1817
  		if (is_shndx_special(sym->st_shndx))
5b24c0715   Sam Ravnborg   kbuild: code refa...
1818
  			continue;
e84048aa1   Quentin Casasnovas   modpost: fix exta...
1819
1820
  		if (is_second_extable_reloc(start, rela, fromsec))
  			find_extable_entry_size(fromsec, &r);
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1821
  		check_section_mismatch(modname, elf, &r, sym, fromsec);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1822
1823
1824
1825
  	}
  }
  
  static void section_rel(const char *modname, struct elf_info *elf,
bb66fc671   Masahiro Yamada   kbuild: trivial -...
1826
  			Elf_Shdr *sechdr)
5b24c0715   Sam Ravnborg   kbuild: code refa...
1827
1828
1829
1830
1831
1832
  {
  	Elf_Sym *sym;
  	Elf_Rel *rel;
  	Elf_Rela r;
  	unsigned int r_sym;
  	const char *fromsec;
5b24c0715   Sam Ravnborg   kbuild: code refa...
1833

ff13f9269   Sam Ravnborg   kbuild: introduce...
1834
  	Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset;
5b24c0715   Sam Ravnborg   kbuild: code refa...
1835
  	Elf_Rel *stop  = (void *)start + sechdr->sh_size;
ff13f9269   Sam Ravnborg   kbuild: introduce...
1836
  	fromsec = sech_name(elf, sechdr);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1837
1838
  	fromsec += strlen(".rel");
  	/* if from section (name) is know good then skip it */
b614a697d   Anders Kaseorg   kbuild, modpost: ...
1839
  	if (match(fromsec, section_white_list))
5b24c0715   Sam Ravnborg   kbuild: code refa...
1840
1841
1842
1843
1844
  		return;
  
  	for (rel = start; rel < stop; rel++) {
  		r.r_offset = TO_NATIVE(rel->r_offset);
  #if KERNEL_ELFCLASS == ELFCLASS64
ff13f9269   Sam Ravnborg   kbuild: introduce...
1845
  		if (elf->hdr->e_machine == EM_MIPS) {
5b24c0715   Sam Ravnborg   kbuild: code refa...
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
  			unsigned int r_typ;
  			r_sym = ELF64_MIPS_R_SYM(rel->r_info);
  			r_sym = TO_NATIVE(r_sym);
  			r_typ = ELF64_MIPS_R_TYPE(rel->r_info);
  			r.r_info = ELF64_R_INFO(r_sym, r_typ);
  		} else {
  			r.r_info = TO_NATIVE(rel->r_info);
  			r_sym = ELF_R_SYM(r.r_info);
  		}
  #else
  		r.r_info = TO_NATIVE(rel->r_info);
  		r_sym = ELF_R_SYM(r.r_info);
  #endif
  		r.r_addend = 0;
ff13f9269   Sam Ravnborg   kbuild: introduce...
1860
  		switch (elf->hdr->e_machine) {
5b24c0715   Sam Ravnborg   kbuild: code refa...
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
  		case EM_386:
  			if (addend_386_rel(elf, sechdr, &r))
  				continue;
  			break;
  		case EM_ARM:
  			if (addend_arm_rel(elf, sechdr, &r))
  				continue;
  			break;
  		case EM_MIPS:
  			if (addend_mips_rel(elf, sechdr, &r))
  				continue;
  			break;
  		}
  		sym = elf->symtab_start + r_sym;
  		/* Skip special sections */
1ce53adf1   Denys Vlasenko   modpost: support ...
1876
  		if (is_shndx_special(sym->st_shndx))
5b24c0715   Sam Ravnborg   kbuild: code refa...
1877
  			continue;
e84048aa1   Quentin Casasnovas   modpost: fix exta...
1878
1879
  		if (is_second_extable_reloc(start, rel, fromsec))
  			find_extable_entry_size(fromsec, &r);
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1880
  		check_section_mismatch(modname, elf, &r, sym, fromsec);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1881
1882
  	}
  }
b39927cf4   Sam Ravnborg   kbuild: check for...
1883
1884
1885
1886
  /**
   * A module includes a number of sections that are discarded
   * either when loaded or when used as built-in.
   * For loaded modules all functions marked __init and all data
b595076a1   Uwe Kleine-König   tree-wide: fix co...
1887
   * marked __initdata will be discarded when the module has been initialized.
b39927cf4   Sam Ravnborg   kbuild: check for...
1888
1889
   * Likewise for modules used built-in the sections marked __exit
   * are discarded because __exit marked function are supposed to be called
32be1d223   Ben Dooks   scripts/mod/modpo...
1890
   * only when a module is unloaded which never happens for built-in modules.
b39927cf4   Sam Ravnborg   kbuild: check for...
1891
1892
1893
1894
1895
   * The check_sec_ref() function traverses all relocation records
   * to find all references to a section that reference a section that will
   * be discarded and warns about it.
   **/
  static void check_sec_ref(struct module *mod, const char *modname,
bb66fc671   Masahiro Yamada   kbuild: trivial -...
1896
  			  struct elf_info *elf)
b39927cf4   Sam Ravnborg   kbuild: check for...
1897
1898
  {
  	int i;
b39927cf4   Sam Ravnborg   kbuild: check for...
1899
  	Elf_Shdr *sechdrs = elf->sechdrs;
62070fa42   Sam Ravnborg   kbuild: kill trai...
1900

b39927cf4   Sam Ravnborg   kbuild: check for...
1901
  	/* Walk through all sections */
1ce53adf1   Denys Vlasenko   modpost: support ...
1902
  	for (i = 0; i < elf->num_sections; i++) {
b614a697d   Anders Kaseorg   kbuild, modpost: ...
1903
  		check_section(modname, elf, &elf->sechdrs[i]);
b39927cf4   Sam Ravnborg   kbuild: check for...
1904
  		/* We want to process only relocation sections and not .init */
5b24c0715   Sam Ravnborg   kbuild: code refa...
1905
  		if (sechdrs[i].sh_type == SHT_RELA)
10668220a   Sam Ravnborg   kbuild: introduce...
1906
  			section_rela(modname, elf, &elf->sechdrs[i]);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1907
  		else if (sechdrs[i].sh_type == SHT_REL)
10668220a   Sam Ravnborg   kbuild: introduce...
1908
  			section_rel(modname, elf, &elf->sechdrs[i]);
b39927cf4   Sam Ravnborg   kbuild: check for...
1909
1910
  	}
  }
7d02b490e   Andi Kleen   Kbuild, lto: Drop...
1911
1912
  static char *remove_dot(char *s)
  {
fcd38ed0f   Michal Nazarewicz   scripts: modpost:...
1913
  	size_t n = strcspn(s, ".");
7d02b490e   Andi Kleen   Kbuild, lto: Drop...
1914

fcd38ed0f   Michal Nazarewicz   scripts: modpost:...
1915
1916
1917
  	if (n && s[n]) {
  		size_t m = strspn(s + n + 1, "0123456789");
  		if (m && (s[n + m] == '.' || s[n + m] == 0))
7d02b490e   Andi Kleen   Kbuild, lto: Drop...
1918
1919
1920
1921
  			s[n] = 0;
  	}
  	return s;
  }
8b1857436   Masahiro Yamada   modpost: constify...
1922
  static void read_symbols(const char *modname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1923
1924
1925
  {
  	const char *symname;
  	char *version;
b817f6fef   Sam Ravnborg   kbuild: check lic...
1926
  	char *license;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1927
1928
1929
  	struct module *mod;
  	struct elf_info info = { };
  	Elf_Sym *sym;
85bd2fddd   Sam Ravnborg   kbuild: fix secti...
1930
1931
  	if (!parse_elf(&info, modname))
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1932
1933
1934
1935
1936
1937
  
  	mod = new_module(modname);
  
  	/* When there's no vmlinux, don't print warnings about
  	 * unresolved symbols (since there'll be too many ;) */
  	if (is_vmlinux(modname)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1938
  		have_vmlinux = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1939
1940
  		mod->skip = 1;
  	}
bca2ccee4   Masahiro Yamada   modpost: pass str...
1941
  	license = get_modinfo(&info, "license");
ba1029c9c   Randy Dunlap   modpost: detect m...
1942
  	if (!license && !is_vmlinux(modname))
2fa365682   Sam Ravnborg   kbuild: soften MO...
1943
1944
1945
1946
1947
  		warn("modpost: missing MODULE_LICENSE() in %s
  "
  		     "see include/linux/module.h for "
  		     "more information
  ", modname);
b817f6fef   Sam Ravnborg   kbuild: check lic...
1948
1949
1950
1951
1952
1953
1954
  	while (license) {
  		if (license_is_gpl_compatible(license))
  			mod->gpl_compatible = 1;
  		else {
  			mod->gpl_compatible = 0;
  			break;
  		}
bca2ccee4   Masahiro Yamada   modpost: pass str...
1955
  		license = get_next_modinfo(&info, "license", license);
b817f6fef   Sam Ravnborg   kbuild: check lic...
1956
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1957
  	for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
7d02b490e   Andi Kleen   Kbuild, lto: Drop...
1958
  		symname = remove_dot(info.strtab + sym->st_name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1959
1960
1961
1962
  
  		handle_modversions(mod, &info, sym, symname);
  		handle_moddevtable(mod, &info, sym, symname);
  	}
074a04f57   Masahiro Yamada   modpost: remove r...
1963
  	if (!is_vmlinux(modname) || vmlinux_section_warnings)
10668220a   Sam Ravnborg   kbuild: introduce...
1964
  		check_sec_ref(mod, modname, &info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1965

bca2ccee4   Masahiro Yamada   modpost: pass str...
1966
  	version = get_modinfo(&info, "version");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1967
1968
1969
1970
1971
1972
1973
1974
  	if (version)
  		maybe_frob_rcs_version(modname, version, info.modinfo,
  				       version - (char *)info.hdr);
  	if (version || (all_versions && !is_vmlinux(modname)))
  		get_src_version(modname, mod->srcversion,
  				sizeof(mod->srcversion)-1);
  
  	parse_elf_finish(&info);
8c8ef42ae   Rusty Russell   module: include o...
1975
  	/* Our trick to get versioning for module struct etc. - it's
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1976
1977
1978
1979
  	 * never passed as an argument to an exported function, so
  	 * the automatic versioning doesn't pick it up, but it's really
  	 * important anyhow */
  	if (modversions)
8c8ef42ae   Rusty Russell   module: include o...
1980
  		mod->unres = alloc_symbol("module_layout", 0, mod->unres);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1981
  }
712f9b468   Rusty Russell   modpost: add -T o...
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
  static void read_symbols_from_files(const char *filename)
  {
  	FILE *in = stdin;
  	char fname[PATH_MAX];
  
  	if (strcmp(filename, "-") != 0) {
  		in = fopen(filename, "r");
  		if (!in)
  			fatal("Can't open filenames file %s: %m", filename);
  	}
  
  	while (fgets(fname, PATH_MAX, in) != NULL) {
  		if (strends(fname, "
  "))
  			fname[strlen(fname)-1] = '\0';
  		read_symbols(fname);
  	}
  
  	if (in != stdin)
  		fclose(in);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2003
2004
2005
2006
2007
  #define SZ 500
  
  /* We first write the generated file into memory using the
   * following helper, then compare to the file on disk and
   * only update the later if anything changed */
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
2008
2009
  void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf,
  						      const char *fmt, ...)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2010
2011
2012
2013
  {
  	char tmp[SZ];
  	int len;
  	va_list ap;
62070fa42   Sam Ravnborg   kbuild: kill trai...
2014

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2015
2016
  	va_start(ap, fmt);
  	len = vsnprintf(tmp, SZ, fmt, ap);
7670f023a   Sam Ravnborg   [PATCH] kbuild: f...
2017
  	buf_write(buf, tmp, len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2018
2019
  	va_end(ap);
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
2020
  void buf_write(struct buffer *buf, const char *s, int len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2021
2022
  {
  	if (buf->size - buf->pos < len) {
7670f023a   Sam Ravnborg   [PATCH] kbuild: f...
2023
  		buf->size += len + SZ;
1f3aa9002   Randy Dunlap   scripts: modpost:...
2024
  		buf->p = NOFAIL(realloc(buf->p, buf->size));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2025
2026
2027
2028
  	}
  	strncpy(buf->p + buf->pos, s, len);
  	buf->pos += len;
  }
c96fca213   Sam Ravnborg   kbuild: warn when...
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
  static void check_for_gpl_usage(enum export exp, const char *m, const char *s)
  {
  	const char *e = is_vmlinux(m) ?"":".ko";
  
  	switch (exp) {
  	case export_gpl:
  		fatal("modpost: GPL-incompatible module %s%s "
  		      "uses GPL-only symbol '%s'
  ", m, e, s);
  		break;
  	case export_unused_gpl:
  		fatal("modpost: GPL-incompatible module %s%s "
  		      "uses GPL-only symbol marked UNUSED '%s'
  ", m, e, s);
  		break;
  	case export_gpl_future:
  		warn("modpost: GPL-incompatible module %s%s "
  		      "uses future GPL-only symbol '%s'
  ", m, e, s);
  		break;
  	case export_plain:
  	case export_unused:
  	case export_unknown:
  		/* ignore */
  		break;
  	}
  }
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2056
  static void check_for_unused(enum export exp, const char *m, const char *s)
c96fca213   Sam Ravnborg   kbuild: warn when...
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
  {
  	const char *e = is_vmlinux(m) ?"":".ko";
  
  	switch (exp) {
  	case export_unused:
  	case export_unused_gpl:
  		warn("modpost: module %s%s "
  		      "uses symbol '%s' marked UNUSED
  ", m, e, s);
  		break;
  	default:
  		/* ignore */
  		break;
  	}
  }
  
  static void check_exports(struct module *mod)
b817f6fef   Sam Ravnborg   kbuild: check lic...
2074
2075
2076
2077
  {
  	struct symbol *s, *exp;
  
  	for (s = mod->unres; s; s = s->next) {
6449bd621   Andrew Morton   kbuild: modpost b...
2078
  		const char *basename;
b817f6fef   Sam Ravnborg   kbuild: check lic...
2079
2080
2081
  		exp = find_symbol(s->name);
  		if (!exp || exp->module == mod)
  			continue;
6449bd621   Andrew Morton   kbuild: modpost b...
2082
  		basename = strrchr(mod->name, '/');
b817f6fef   Sam Ravnborg   kbuild: check lic...
2083
2084
  		if (basename)
  			basename++;
c96fca213   Sam Ravnborg   kbuild: warn when...
2085
2086
2087
2088
2089
  		else
  			basename = mod->name;
  		if (!mod->gpl_compatible)
  			check_for_gpl_usage(exp->export, basename, exp->name);
  		check_for_unused(exp->export, basename, exp->name);
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2090
  	}
b817f6fef   Sam Ravnborg   kbuild: check lic...
2091
  }
4fd3e4ef1   Wanlong Gao   modpost: abort if...
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
  static int check_modname_len(struct module *mod)
  {
  	const char *mod_name;
  
  	mod_name = strrchr(mod->name, '/');
  	if (mod_name == NULL)
  		mod_name = mod->name;
  	else
  		mod_name++;
  	if (strlen(mod_name) >= MODULE_NAME_LEN) {
  		merror("module name is too long [%s.ko]
  ", mod->name);
  		return 1;
  	}
  
  	return 0;
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
2109
2110
2111
2112
  /**
   * Header for the generated file
   **/
  static void add_header(struct buffer *b, struct module *mod)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2113
  {
9afb719e7   Laura Abbott   kbuild: Add build...
2114
2115
  	buf_printf(b, "#include <linux/build-salt.h>
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2116
2117
2118
2119
2120
2121
2122
2123
  	buf_printf(b, "#include <linux/module.h>
  ");
  	buf_printf(b, "#include <linux/vermagic.h>
  ");
  	buf_printf(b, "#include <linux/compiler.h>
  ");
  	buf_printf(b, "
  ");
9afb719e7   Laura Abbott   kbuild: Add build...
2124
2125
2126
2127
  	buf_printf(b, "BUILD_SALT;
  ");
  	buf_printf(b, "
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2128
2129
  	buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);
  ");
3e2e857f9   Kees Cook   module: Add modul...
2130
2131
  	buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2132
2133
  	buf_printf(b, "
  ");
e0f244c63   Andi Kleen   asmlinkage, modul...
2134
2135
  	buf_printf(b, "__visible struct module __this_module
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2136
2137
  	buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {
  ");
3c7ec94d2   Greg Kroah-Hartman   modpost: use prop...
2138
2139
  	buf_printf(b, "\t.name = KBUILD_MODNAME,
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2140
  	if (mod->has_init)
3c7ec94d2   Greg Kroah-Hartman   modpost: use prop...
2141
2142
  		buf_printf(b, "\t.init = init_module,
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2143
2144
2145
  	if (mod->has_cleanup)
  		buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD
  "
3c7ec94d2   Greg Kroah-Hartman   modpost: use prop...
2146
2147
  			      "\t.exit = cleanup_module,
  "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2148
2149
  			      "#endif
  ");
3c7ec94d2   Greg Kroah-Hartman   modpost: use prop...
2150
2151
  	buf_printf(b, "\t.arch = MODULE_ARCH_INIT,
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2152
2153
2154
  	buf_printf(b, "};
  ");
  }
2449b8ba0   Ben Hutchings   module,bug: Add T...
2155
2156
2157
2158
2159
2160
2161
  static void add_intree_flag(struct buffer *b, int is_intree)
  {
  	if (is_intree)
  		buf_printf(b, "
  MODULE_INFO(intree, \"Y\");
  ");
  }
caf7501a1   Andi Kleen   module/retpoline:...
2162
2163
2164
  /* Cannot check for assembler */
  static void add_retpoline(struct buffer *b)
  {
4bef2bacb   WANG Chao   x86, modpost: Rep...
2165
2166
2167
  	buf_printf(b, "
  #ifdef CONFIG_RETPOLINE
  ");
caf7501a1   Andi Kleen   module/retpoline:...
2168
2169
2170
2171
2172
  	buf_printf(b, "MODULE_INFO(retpoline, \"Y\");
  ");
  	buf_printf(b, "#endif
  ");
  }
5c7251384   Trevor Keith   Fix all -Wmissing...
2173
  static void add_staging_flag(struct buffer *b, const char *name)
a9860bf05   Greg Kroah-Hartman   Staging: add TAIN...
2174
  {
d62c47652   Masahiro Yamada   modpost: use strs...
2175
  	if (strstarts(name, "drivers/staging"))
a9860bf05   Greg Kroah-Hartman   Staging: add TAIN...
2176
2177
2178
2179
  		buf_printf(b, "
  MODULE_INFO(staging, \"Y\");
  ");
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
2180
2181
2182
  /**
   * Record CRCs for unresolved symbols
   **/
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
2183
  static int add_versions(struct buffer *b, struct module *mod)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2184
2185
  {
  	struct symbol *s, *exp;
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
2186
  	int err = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2187
2188
2189
2190
  
  	for (s = mod->unres; s; s = s->next) {
  		exp = find_symbol(s->name);
  		if (!exp || exp->module == mod) {
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
2191
  			if (have_vmlinux && !s->weak) {
2a1166594   Matthew Wilcox   kbuild: distingui...
2192
2193
2194
2195
2196
2197
2198
  				if (warn_unresolved) {
  					warn("\"%s\" [%s.ko] undefined!
  ",
  					     s->name, mod->name);
  				} else {
  					merror("\"%s\" [%s.ko] undefined!
  ",
bb66fc671   Masahiro Yamada   kbuild: trivial -...
2199
  					       s->name, mod->name);
2a1166594   Matthew Wilcox   kbuild: distingui...
2200
2201
  					err = 1;
  				}
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
2202
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2203
2204
2205
2206
2207
2208
2209
2210
  			continue;
  		}
  		s->module = exp->module;
  		s->crc_valid = exp->crc_valid;
  		s->crc = exp->crc;
  	}
  
  	if (!modversions)
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
2211
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2212
2213
2214
2215
2216
  
  	buf_printf(b, "
  ");
  	buf_printf(b, "static const struct modversion_info ____versions[]
  ");
3ff6eecca   Adrian Bunk   remove __attribut...
2217
2218
  	buf_printf(b, "__used
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2219
2220
2221
2222
  	buf_printf(b, "__attribute__((section(\"__versions\"))) = {
  ");
  
  	for (s = mod->unres; s; s = s->next) {
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2223
  		if (!s->module)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2224
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2225
  		if (!s->crc_valid) {
cb80514d9   Sam Ravnborg   kbuild: use warn(...
2226
2227
  			warn("\"%s\" [%s.ko] has no CRC!
  ",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2228
2229
2230
  				s->name, mod->name);
  			continue;
  		}
5cfb203a3   Takashi Iwai   modpost: abort if...
2231
2232
2233
2234
2235
2236
2237
  		if (strlen(s->name) >= MODULE_NAME_LEN) {
  			merror("too long symbol \"%s\" [%s.ko]
  ",
  			       s->name, mod->name);
  			err = 1;
  			break;
  		}
b2c5cdcfd   Masahiro Yamada   modpost: remove s...
2238
2239
  		buf_printf(b, "\t{ %#8x, \"%s\" },
  ",
a4b6a77b7   James Hogan   module: fix symbo...
2240
  			   s->crc, s->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2241
2242
2243
2244
  	}
  
  	buf_printf(b, "};
  ");
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
2245
2246
  
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2247
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
2248
2249
  static void add_depends(struct buffer *b, struct module *mod,
  			struct module *modules)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2250
2251
2252
2253
  {
  	struct symbol *s;
  	struct module *m;
  	int first = 1;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2254
  	for (m = modules; m; m = m->next)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2255
  		m->seen = is_vmlinux(m->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2256
2257
2258
2259
2260
  
  	buf_printf(b, "
  ");
  	buf_printf(b, "static const char __module_depends[]
  ");
3ff6eecca   Adrian Bunk   remove __attribut...
2261
2262
  	buf_printf(b, "__used
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2263
2264
2265
2266
  	buf_printf(b, "__attribute__((section(\".modinfo\"))) =
  ");
  	buf_printf(b, "\"depends=");
  	for (s = mod->unres; s; s = s->next) {
a61b2dfd1   Sam Ravnborg   kbuild: fix segme...
2267
  		const char *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2268
2269
2270
2271
2272
2273
2274
  		if (!s->module)
  			continue;
  
  		if (s->module->seen)
  			continue;
  
  		s->module->seen = 1;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2275
2276
  		p = strrchr(s->module->name, '/');
  		if (p)
a61b2dfd1   Sam Ravnborg   kbuild: fix segme...
2277
2278
2279
2280
  			p++;
  		else
  			p = s->module->name;
  		buf_printf(b, "%s%s", first ? "" : ",", p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2281
2282
2283
2284
2285
  		first = 0;
  	}
  	buf_printf(b, "\";
  ");
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
2286
  static void add_srcversion(struct buffer *b, struct module *mod)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2287
2288
2289
2290
2291
2292
2293
2294
2295
  {
  	if (mod->srcversion[0]) {
  		buf_printf(b, "
  ");
  		buf_printf(b, "MODULE_INFO(srcversion, \"%s\");
  ",
  			   mod->srcversion);
  	}
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
2296
  static void write_if_changed(struct buffer *b, const char *fname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
  {
  	char *tmp;
  	FILE *file;
  	struct stat st;
  
  	file = fopen(fname, "r");
  	if (!file)
  		goto write;
  
  	if (fstat(fileno(file), &st) < 0)
  		goto close_write;
  
  	if (st.st_size != b->pos)
  		goto close_write;
  
  	tmp = NOFAIL(malloc(b->pos));
  	if (fread(tmp, 1, b->pos, file) != b->pos)
  		goto free_write;
  
  	if (memcmp(tmp, b->p, b->pos) != 0)
  		goto free_write;
  
  	free(tmp);
  	fclose(file);
  	return;
  
   free_write:
  	free(tmp);
   close_write:
  	fclose(file);
   write:
  	file = fopen(fname, "w");
  	if (!file) {
  		perror(fname);
  		exit(1);
  	}
  	if (fwrite(b->p, 1, b->pos, file) != b->pos) {
  		perror(fname);
  		exit(1);
  	}
  	fclose(file);
  }
bd5cbcedf   Ram Pai   kbuild: export-ty...
2339
  /* parse Module.symvers file. line format:
534b89a9f   Sam Ravnborg   kbuild: fix segv ...
2340
   * 0x12345678<tab>symbol<tab>module[[<tab>export]<tab>something]
bd5cbcedf   Ram Pai   kbuild: export-ty...
2341
   **/
040fcc819   Sam Ravnborg   kbuild: improved ...
2342
  static void read_dump(const char *fname, unsigned int kernel)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2343
2344
2345
2346
  {
  	unsigned long size, pos = 0;
  	void *file = grab_file(fname, &size);
  	char *line;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2347
  	if (!file)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2348
2349
2350
2351
  		/* No symbol versions, silently ignore */
  		return;
  
  	while ((line = get_next_line(&pos, file, size))) {
534b89a9f   Sam Ravnborg   kbuild: fix segv ...
2352
  		char *symname, *modname, *d, *export, *end;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2353
2354
  		unsigned int crc;
  		struct module *mod;
040fcc819   Sam Ravnborg   kbuild: improved ...
2355
  		struct symbol *s;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2356
2357
2358
2359
2360
2361
2362
  
  		if (!(symname = strchr(line, '\t')))
  			goto fail;
  		*symname++ = '\0';
  		if (!(modname = strchr(symname, '\t')))
  			goto fail;
  		*modname++ = '\0';
9ac545b0f   Laurent Riffard   kbuild: fix modul...
2363
  		if ((export = strchr(modname, '\t')) != NULL)
bd5cbcedf   Ram Pai   kbuild: export-ty...
2364
  			*export++ = '\0';
534b89a9f   Sam Ravnborg   kbuild: fix segv ...
2365
2366
  		if (export && ((end = strchr(export, '\t')) != NULL))
  			*end = '\0';
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2367
2368
2369
  		crc = strtoul(line, &d, 16);
  		if (*symname == '\0' || *modname == '\0' || *d != '\0')
  			goto fail;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2370
2371
2372
  		mod = find_module(modname);
  		if (!mod) {
  			if (is_vmlinux(modname))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2373
  				have_vmlinux = 1;
0fa3a88cf   Jan Beulich   kbuild: remove po...
2374
  			mod = new_module(modname);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2375
2376
  			mod->skip = 1;
  		}
bd5cbcedf   Ram Pai   kbuild: export-ty...
2377
  		s = sym_add_exported(symname, mod, export_no(export));
8e70c4588   Sam Ravnborg   kbuild: warn abou...
2378
2379
  		s->kernel    = kernel;
  		s->preloaded = 1;
bd5cbcedf   Ram Pai   kbuild: export-ty...
2380
  		sym_update_crc(symname, mod, crc, export_no(export));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2381
  	}
2ee41e62b   Christian Engelmayer   modpost: Fix reso...
2382
  	release_file(file, size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2383
2384
  	return;
  fail:
2ee41e62b   Christian Engelmayer   modpost: Fix reso...
2385
  	release_file(file, size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2386
2387
2388
  	fatal("parse error in symbol dump file
  ");
  }
040fcc819   Sam Ravnborg   kbuild: improved ...
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
  /* For normal builds always dump all symbols.
   * For external modules only dump symbols
   * that are not read from kernel Module.symvers.
   **/
  static int dump_sym(struct symbol *sym)
  {
  	if (!external_module)
  		return 1;
  	if (sym->vmlinux || sym->kernel)
  		return 0;
  	return 1;
  }
62070fa42   Sam Ravnborg   kbuild: kill trai...
2401

5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
2402
  static void write_dump(const char *fname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2403
2404
2405
2406
2407
2408
2409
2410
  {
  	struct buffer buf = { };
  	struct symbol *symbol;
  	int n;
  
  	for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
  		symbol = symbolhash[n];
  		while (symbol) {
040fcc819   Sam Ravnborg   kbuild: improved ...
2411
  			if (dump_sym(symbol))
bd5cbcedf   Ram Pai   kbuild: export-ty...
2412
2413
  				buf_printf(&buf, "0x%08x\t%s\t%s\t%s
  ",
62070fa42   Sam Ravnborg   kbuild: kill trai...
2414
  					symbol->crc, symbol->name,
bd5cbcedf   Ram Pai   kbuild: export-ty...
2415
2416
  					symbol->module->name,
  					export_str(symbol->export));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2417
2418
2419
2420
  			symbol = symbol->next;
  		}
  	}
  	write_if_changed(&buf, fname);
c7d47f26d   Heinrich Schuchardt   modpost: free all...
2421
  	free(buf.p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2422
  }
2d04b5ae1   Richard Hacker   kbuild: support l...
2423
2424
2425
2426
  struct ext_sym_list {
  	struct ext_sym_list *next;
  	const char *file;
  };
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
2427
  int main(int argc, char **argv)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2428
2429
2430
  {
  	struct module *mod;
  	struct buffer buf = { };
040fcc819   Sam Ravnborg   kbuild: improved ...
2431
  	char *kernel_read = NULL, *module_read = NULL;
712f9b468   Rusty Russell   modpost: add -T o...
2432
  	char *dump_write = NULL, *files_source = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2433
  	int opt;
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
2434
  	int err;
2d04b5ae1   Richard Hacker   kbuild: support l...
2435
2436
  	struct ext_sym_list *extsym_iter;
  	struct ext_sym_list *extsym_start = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2437

47490ec14   Nicolas Boichat   modpost: Add flag...
2438
  	while ((opt = getopt(argc, argv, "i:I:e:mnsST:o:awM:K:E")) != -1) {
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2439
2440
2441
2442
2443
2444
2445
2446
  		switch (opt) {
  		case 'i':
  			kernel_read = optarg;
  			break;
  		case 'I':
  			module_read = optarg;
  			external_module = 1;
  			break;
2d04b5ae1   Richard Hacker   kbuild: support l...
2447
2448
2449
2450
2451
2452
2453
2454
  		case 'e':
  			external_module = 1;
  			extsym_iter =
  			   NOFAIL(malloc(sizeof(*extsym_iter)));
  			extsym_iter->next = extsym_start;
  			extsym_iter->file = optarg;
  			extsym_start = extsym_iter;
  			break;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2455
2456
2457
  		case 'm':
  			modversions = 1;
  			break;
eed380f3f   Guenter Roeck   modpost: Optional...
2458
2459
2460
  		case 'n':
  			ignore_missing_files = 1;
  			break;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2461
2462
2463
2464
2465
2466
2467
2468
2469
  		case 'o':
  			dump_write = optarg;
  			break;
  		case 'a':
  			all_versions = 1;
  			break;
  		case 's':
  			vmlinux_section_warnings = 0;
  			break;
588ccd732   Sam Ravnborg   kbuild: add verbo...
2470
2471
2472
  		case 'S':
  			sec_mismatch_verbose = 0;
  			break;
712f9b468   Rusty Russell   modpost: add -T o...
2473
2474
2475
  		case 'T':
  			files_source = optarg;
  			break;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2476
2477
2478
  		case 'w':
  			warn_unresolved = 1;
  			break;
47490ec14   Nicolas Boichat   modpost: Add flag...
2479
2480
2481
  		case 'E':
  			sec_mismatch_fatal = 1;
  			break;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2482
2483
  		default:
  			exit(1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2484
2485
  		}
  	}
040fcc819   Sam Ravnborg   kbuild: improved ...
2486
2487
2488
2489
  	if (kernel_read)
  		read_dump(kernel_read, 1);
  	if (module_read)
  		read_dump(module_read, 0);
2d04b5ae1   Richard Hacker   kbuild: support l...
2490
2491
2492
2493
2494
2495
  	while (extsym_start) {
  		read_dump(extsym_start->file, 0);
  		extsym_iter = extsym_start->next;
  		free(extsym_start);
  		extsym_start = extsym_iter;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2496

df578e7d8   Sam Ravnborg   kbuild: clean up ...
2497
  	while (optind < argc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2498
  		read_symbols(argv[optind++]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2499

712f9b468   Rusty Russell   modpost: add -T o...
2500
2501
  	if (files_source)
  		read_symbols_from_files(files_source);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2502
2503
2504
  	for (mod = modules; mod; mod = mod->next) {
  		if (mod->skip)
  			continue;
c96fca213   Sam Ravnborg   kbuild: warn when...
2505
  		check_exports(mod);
b817f6fef   Sam Ravnborg   kbuild: check lic...
2506
  	}
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
2507
  	err = 0;
b817f6fef   Sam Ravnborg   kbuild: check lic...
2508
  	for (mod = modules; mod; mod = mod->next) {
d93e1719a   Mathias Krause   modpost: simplify...
2509
  		char fname[PATH_MAX];
666ab414f   Andi Kleen   kbuild: fix a buf...
2510

b817f6fef   Sam Ravnborg   kbuild: check lic...
2511
2512
  		if (mod->skip)
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2513
2514
  
  		buf.pos = 0;
4fd3e4ef1   Wanlong Gao   modpost: abort if...
2515
  		err |= check_modname_len(mod);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2516
  		add_header(&buf, mod);
2449b8ba0   Ben Hutchings   module,bug: Add T...
2517
  		add_intree_flag(&buf, !external_module);
caf7501a1   Andi Kleen   module/retpoline:...
2518
  		add_retpoline(&buf);
a9860bf05   Greg Kroah-Hartman   Staging: add TAIN...
2519
  		add_staging_flag(&buf, mod->name);
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
2520
  		err |= add_versions(&buf, mod);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2521
2522
2523
2524
2525
2526
2527
  		add_depends(&buf, mod, modules);
  		add_moddevtable(&buf, mod);
  		add_srcversion(&buf, mod);
  
  		sprintf(fname, "%s.mod.c", mod->name);
  		write_if_changed(&buf, fname);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2528
2529
  	if (dump_write)
  		write_dump(dump_write);
47490ec14   Nicolas Boichat   modpost: Add flag...
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
  	if (sec_mismatch_count) {
  		if (!sec_mismatch_verbose) {
  			warn("modpost: Found %d section mismatch(es).
  "
  			     "To see full details build your kernel with:
  "
  			     "'make CONFIG_DEBUG_SECTION_MISMATCH=y'
  ",
  			     sec_mismatch_count);
  		}
  		if (sec_mismatch_fatal) {
  			fatal("modpost: Section mismatches detected.
  "
  			      "Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.
  ");
  		}
  	}
c7d47f26d   Heinrich Schuchardt   modpost: free all...
2547
  	free(buf.p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2548

c53ddacdc   Kirill Korotaev   kbuild: fail kern...
2549
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2550
  }