Blame view

scripts/mod/modpost.c 65.3 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"
5a865c060   Linus Torvalds   Merge branch 'for...
21
  #include "../../include/generated/autoconf.h"
b817f6fef   Sam Ravnborg   kbuild: check lic...
22
  #include "../../include/linux/license.h"
b92021b09   Rusty Russell   CONFIG_SYMBOL_PRE...
23
  #include "../../include/linux/export.h"
9e1b9b807   Alan Jenkins   module: make MODU...
24

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

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

6d9a89ea4   Andi Kleen   kbuild: declare t...
49
50
51
  #define PRINTF __attribute__ ((format (printf, 1, 2)))
  
  PRINTF void fatal(const char *fmt, ...)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
52
53
54
55
56
57
58
59
60
61
62
  {
  	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...
63
  PRINTF void warn(const char *fmt, ...)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64
65
66
67
68
69
70
71
72
  {
  	va_list arglist;
  
  	fprintf(stderr, "WARNING: ");
  
  	va_start(arglist, fmt);
  	vfprintf(stderr, fmt, arglist);
  	va_end(arglist);
  }
6d9a89ea4   Andi Kleen   kbuild: declare t...
73
  PRINTF void merror(const char *fmt, ...)
2a1166594   Matthew Wilcox   kbuild: distingui...
74
75
76
77
78
79
80
81
82
  {
  	va_list arglist;
  
  	fprintf(stderr, "ERROR: ");
  
  	va_start(arglist, fmt);
  	vfprintf(stderr, fmt, arglist);
  	va_end(arglist);
  }
d4ef1c30e   Rusty Russell   modpost: minor cl...
83
84
85
86
87
88
89
  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 ...
90
91
92
  static int is_vmlinux(const char *modname)
  {
  	const char *myname;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
93
94
  	myname = strrchr(modname, '/');
  	if (myname)
040fcc819   Sam Ravnborg   kbuild: improved ...
95
96
97
  		myname++;
  	else
  		myname = modname;
741f98fe2   Sam Ravnborg   kbuild: do sectio...
98
99
  	return (strcmp(myname, "vmlinux") == 0) ||
  	       (strcmp(myname, "vmlinux.o") == 0);
040fcc819   Sam Ravnborg   kbuild: improved ...
100
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
102
  void *do_nofail(void *ptr, const char *expr)
  {
df578e7d8   Sam Ravnborg   kbuild: clean up ...
103
  	if (!ptr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
104
105
  		fatal("modpost: Memory allocation failure: %s.
  ", expr);
df578e7d8   Sam Ravnborg   kbuild: clean up ...
106

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
107
108
109
110
  	return ptr;
  }
  
  /* A list of all modules we processed */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
111
  static struct module *modules;
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
112
  static struct module *find_module(char *modname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
114
115
116
117
118
119
120
  {
  	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...
121
  static struct module *new_module(const char *modname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
122
123
  {
  	struct module *mod;
d4ef1c30e   Rusty Russell   modpost: minor cl...
124
  	char *p;
62070fa42   Sam Ravnborg   kbuild: kill trai...
125

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
126
127
128
129
130
  	mod = NOFAIL(malloc(sizeof(*mod)));
  	memset(mod, 0, sizeof(*mod));
  	p = NOFAIL(strdup(modname));
  
  	/* strip trailing .o */
d4ef1c30e   Rusty Russell   modpost: minor cl...
131
132
133
134
  	if (strends(p, ".o")) {
  		p[strlen(p) - 2] = '\0';
  		mod->is_dot_o = 1;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135
136
137
  
  	/* add to list */
  	mod->name = p;
b817f6fef   Sam Ravnborg   kbuild: check lic...
138
  	mod->gpl_compatible = -1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
  	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 ...
156
157
158
  	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...
159
  	unsigned int preloaded:1;  /* 1 if symbol from Module.symvers, or crc */
bd5cbcedf   Ram Pai   kbuild: export-ty...
160
  	enum export  export;       /* Type of export */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
162
163
164
165
166
167
168
169
170
171
172
  	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 ...
173
  	for (value = 0x238F13AF * strlen(name), i = 0; name[i]; i++)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
174
175
176
177
  		value = (value + (((unsigned char *)name)[i] << (i*5 % 24)));
  
  	return (1103515243 * value + 12345);
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
178
179
180
181
182
183
  /**
   * 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
184
185
186
187
188
189
190
191
192
193
194
  {
  	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...
195
196
  static struct symbol *new_symbol(const char *name, struct module *module,
  				 enum export export)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
197
198
199
200
201
202
203
  {
  	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...
204
  	new->export = export;
040fcc819   Sam Ravnborg   kbuild: improved ...
205
  	return new;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
206
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
207
  static struct symbol *find_symbol(const char *name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208
209
210
211
212
213
  {
  	struct symbol *s;
  
  	/* For our purposes, .foo matches foo.  PPC64 needs this. */
  	if (name[0] == '.')
  		name++;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
214
  	for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s = s->next) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
215
216
217
218
219
  		if (strcmp(s->name, name) == 0)
  			return s;
  	}
  	return NULL;
  }
7a3ee7538   Mathias Krause   modpost: reduce v...
220
  static const struct {
bd5cbcedf   Ram Pai   kbuild: export-ty...
221
222
223
224
  	const char *str;
  	enum export export;
  } export_list[] = {
  	{ .str = "EXPORT_SYMBOL",            .export = export_plain },
c96fca213   Sam Ravnborg   kbuild: warn when...
225
  	{ .str = "EXPORT_UNUSED_SYMBOL",     .export = export_unused },
bd5cbcedf   Ram Pai   kbuild: export-ty...
226
  	{ .str = "EXPORT_SYMBOL_GPL",        .export = export_gpl },
c96fca213   Sam Ravnborg   kbuild: warn when...
227
  	{ .str = "EXPORT_UNUSED_SYMBOL_GPL", .export = export_unused_gpl },
bd5cbcedf   Ram Pai   kbuild: export-ty...
228
229
230
231
232
233
234
235
236
  	{ .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 ...
237
  static enum export export_no(const char *s)
bd5cbcedf   Ram Pai   kbuild: export-ty...
238
239
  {
  	int i;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
240

534b89a9f   Sam Ravnborg   kbuild: fix segv ...
241
242
  	if (!s)
  		return export_unknown;
bd5cbcedf   Ram Pai   kbuild: export-ty...
243
244
245
246
247
248
  	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;
  }
62a263561   Alessio Igor Bogani   modpost: Fix modp...
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
  static const char *sec_name(struct elf_info *elf, int secindex);
  
  #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 ...
270
  static enum export export_from_sec(struct elf_info *elf, unsigned int sec)
bd5cbcedf   Ram Pai   kbuild: export-ty...
271
272
273
  {
  	if (sec == elf->export_sec)
  		return export_plain;
c96fca213   Sam Ravnborg   kbuild: warn when...
274
275
  	else if (sec == elf->export_unused_sec)
  		return export_unused;
bd5cbcedf   Ram Pai   kbuild: export-ty...
276
277
  	else if (sec == elf->export_gpl_sec)
  		return export_gpl;
c96fca213   Sam Ravnborg   kbuild: warn when...
278
279
  	else if (sec == elf->export_unused_gpl_sec)
  		return export_unused_gpl;
bd5cbcedf   Ram Pai   kbuild: export-ty...
280
281
282
283
284
  	else if (sec == elf->export_gpl_future_sec)
  		return export_gpl_future;
  	else
  		return export_unknown;
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
285
286
287
288
  /**
   * 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...
289
290
  static struct symbol *sym_add_exported(const char *name, struct module *mod,
  				       enum export export)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
291
292
293
294
  {
  	struct symbol *s = find_symbol(name);
  
  	if (!s) {
bd5cbcedf   Ram Pai   kbuild: export-ty...
295
  		s = new_symbol(name, mod, export);
8e70c4588   Sam Ravnborg   kbuild: warn abou...
296
297
  	} else {
  		if (!s->preloaded) {
7b75b13cd   Sam Ravnborg   kbuild: when warn...
298
  			warn("%s: '%s' exported twice. Previous export "
8e70c4588   Sam Ravnborg   kbuild: warn abou...
299
300
301
302
  			     "was in %s%s
  ", mod->name, name,
  			     s->module->name,
  			     is_vmlinux(s->module->name) ?"":".ko");
4b21960f9   Trent Piepho   kbuild: modpost p...
303
  		} else {
baec30e41   Paul Bolle   modpost: Fix comm...
304
  			/* In case Module.symvers was out of date */
4b21960f9   Trent Piepho   kbuild: modpost p...
305
  			s->module = mod;
8e70c4588   Sam Ravnborg   kbuild: warn abou...
306
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
307
  	}
8e70c4588   Sam Ravnborg   kbuild: warn abou...
308
  	s->preloaded = 0;
040fcc819   Sam Ravnborg   kbuild: improved ...
309
310
  	s->vmlinux   = is_vmlinux(mod->name);
  	s->kernel    = 0;
bd5cbcedf   Ram Pai   kbuild: export-ty...
311
  	s->export    = export;
040fcc819   Sam Ravnborg   kbuild: improved ...
312
313
314
315
  	return s;
  }
  
  static void sym_update_crc(const char *name, struct module *mod,
bd5cbcedf   Ram Pai   kbuild: export-ty...
316
  			   unsigned int crc, enum export export)
040fcc819   Sam Ravnborg   kbuild: improved ...
317
318
  {
  	struct symbol *s = find_symbol(name);
b6568b1a1   Rusty Russell   modpost: fix bogu...
319
  	if (!s) {
bd5cbcedf   Ram Pai   kbuild: export-ty...
320
  		s = new_symbol(name, mod, export);
b6568b1a1   Rusty Russell   modpost: fix bogu...
321
322
323
  		/* Don't complain when we find it later. */
  		s->preloaded = 1;
  	}
040fcc819   Sam Ravnborg   kbuild: improved ...
324
325
  	s->crc = crc;
  	s->crc_valid = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
326
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
327
  void *grab_file(const char *filename, unsigned long *size)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
328
329
  {
  	struct stat st;
eb3d5cc67   Jesper Juhl   modpost: Stop gra...
330
  	void *map = MAP_FAILED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
331
332
333
  	int fd;
  
  	fd = open(filename, O_RDONLY);
eb3d5cc67   Jesper Juhl   modpost: Stop gra...
334
  	if (fd < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
335
  		return NULL;
eb3d5cc67   Jesper Juhl   modpost: Stop gra...
336
337
  	if (fstat(fd, &st))
  		goto failed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
338
339
340
  
  	*size = st.st_size;
  	map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
341

eb3d5cc67   Jesper Juhl   modpost: Stop gra...
342
343
  failed:
  	close(fd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
344
345
346
347
  	if (map == MAP_FAILED)
  		return NULL;
  	return map;
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
348
349
350
351
352
  /**
    * 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 ...
353
  char *get_next_line(unsigned long *pos, void *file, unsigned long size)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
354
355
356
357
358
359
  {
  	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 ...
360
  	for (; *pos < size ; (*pos)++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
  		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...
381
  void release_file(void *file, unsigned long size)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
382
383
384
  {
  	munmap(file, size);
  }
85bd2fddd   Sam Ravnborg   kbuild: fix secti...
385
  static int parse_elf(struct elf_info *info, const char *filename)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
386
387
  {
  	unsigned int i;
85bd2fddd   Sam Ravnborg   kbuild: fix secti...
388
  	Elf_Ehdr *hdr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
389
390
  	Elf_Shdr *sechdrs;
  	Elf_Sym  *sym;
1ce53adf1   Denys Vlasenko   modpost: support ...
391
392
  	const char *secstrings;
  	unsigned int symtab_idx = ~0U, symtab_shndx_idx = ~0U;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
393
394
395
  
  	hdr = grab_file(filename, &info->size);
  	if (!hdr) {
eed380f3f   Guenter Roeck   modpost: Optional...
396
397
398
399
400
401
  		if (ignore_missing_files) {
  			fprintf(stderr, "%s: %s (ignored)
  ", filename,
  				strerror(errno));
  			return 0;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
402
  		perror(filename);
6803dc0ea   Sam Ravnborg   kbuild: replace a...
403
  		exit(1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
404
405
  	}
  	info->hdr = hdr;
85bd2fddd   Sam Ravnborg   kbuild: fix secti...
406
407
408
409
410
411
412
413
414
415
416
417
  	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
418
  	/* Fix endianness in ELF header */
7d875a028   Anders Kaseorg   kbuild, modpost: ...
419
420
421
422
423
424
425
426
427
428
429
430
431
  	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
432
433
  	sechdrs = (void *)hdr + hdr->e_shoff;
  	info->sechdrs = sechdrs;
a83710e58   Petr Stetiar   kbuild: fix segfa...
434
435
  	/* Check if file offset is correct */
  	if (hdr->e_shoff > info->size) {
df578e7d8   Sam Ravnborg   kbuild: clean up ...
436
437
438
439
  		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...
440
441
  		return 0;
  	}
6845756b2   Anders Kaseorg   modpost: Update 6...
442
  	if (hdr->e_shnum == SHN_UNDEF) {
1ce53adf1   Denys Vlasenko   modpost: support ...
443
444
445
  		/*
  		 * There are more than 64k sections,
  		 * read count from .sh_size.
1ce53adf1   Denys Vlasenko   modpost: support ...
446
447
448
449
450
451
452
  		 */
  		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...
453
  		info->secindex_strings = TO_NATIVE(sechdrs[0].sh_link);
1ce53adf1   Denys Vlasenko   modpost: support ...
454
455
456
457
  	}
  	else {
  		info->secindex_strings = hdr->e_shstrndx;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
458
  	/* Fix endianness in section headers */
1ce53adf1   Denys Vlasenko   modpost: support ...
459
  	for (i = 0; i < info->num_sections; i++) {
7d875a028   Anders Kaseorg   kbuild, modpost: ...
460
461
462
463
464
465
466
467
468
469
  		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
470
471
  	}
  	/* Find symbol table. */
1ce53adf1   Denys Vlasenko   modpost: support ...
472
473
  	secstrings = (void *)hdr + sechdrs[info->secindex_strings].sh_offset;
  	for (i = 1; i < info->num_sections; i++) {
bd5cbcedf   Ram Pai   kbuild: export-ty...
474
  		const char *secname;
56fc82c53   Tejun Heo   modpost: NOBITS s...
475
  		int nobits = sechdrs[i].sh_type == SHT_NOBITS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
476

56fc82c53   Tejun Heo   modpost: NOBITS s...
477
  		if (!nobits && sechdrs[i].sh_offset > info->size) {
df578e7d8   Sam Ravnborg   kbuild: clean up ...
478
479
480
481
482
  			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...
483
484
  			return 0;
  		}
bd5cbcedf   Ram Pai   kbuild: export-ty...
485
486
  		secname = secstrings + sechdrs[i].sh_name;
  		if (strcmp(secname, ".modinfo") == 0) {
56fc82c53   Tejun Heo   modpost: NOBITS s...
487
488
489
  			if (nobits)
  				fatal("%s has NOBITS .modinfo
  ", filename);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
490
491
  			info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
  			info->modinfo_len = sechdrs[i].sh_size;
bd5cbcedf   Ram Pai   kbuild: export-ty...
492
493
  		} else if (strcmp(secname, "__ksymtab") == 0)
  			info->export_sec = i;
c96fca213   Sam Ravnborg   kbuild: warn when...
494
495
  		else if (strcmp(secname, "__ksymtab_unused") == 0)
  			info->export_unused_sec = i;
bd5cbcedf   Ram Pai   kbuild: export-ty...
496
497
  		else if (strcmp(secname, "__ksymtab_gpl") == 0)
  			info->export_gpl_sec = i;
c96fca213   Sam Ravnborg   kbuild: warn when...
498
499
  		else if (strcmp(secname, "__ksymtab_unused_gpl") == 0)
  			info->export_unused_gpl_sec = i;
bd5cbcedf   Ram Pai   kbuild: export-ty...
500
501
  		else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
  			info->export_gpl_future_sec = i;
1ce53adf1   Denys Vlasenko   modpost: support ...
502
503
504
505
506
507
508
  		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...
509
  			sh_link_idx = sechdrs[i].sh_link;
1ce53adf1   Denys Vlasenko   modpost: support ...
510
511
512
  			info->strtab       = (void *)hdr +
  			    sechdrs[sh_link_idx].sh_offset;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
513

1ce53adf1   Denys Vlasenko   modpost: support ...
514
515
516
517
518
519
520
521
  		/* 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
522
  	}
df578e7d8   Sam Ravnborg   kbuild: clean up ...
523
  	if (!info->symtab_start)
cb80514d9   Sam Ravnborg   kbuild: use warn(...
524
525
  		fatal("%s has no symtab?
  ", filename);
df578e7d8   Sam Ravnborg   kbuild: clean up ...
526

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
527
528
529
530
531
532
533
  	/* 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 ...
534
535
536
  
  	if (symtab_shndx_idx != ~0U) {
  		Elf32_Word *p;
6845756b2   Anders Kaseorg   modpost: Update 6...
537
  		if (symtab_idx != sechdrs[symtab_shndx_idx].sh_link)
1ce53adf1   Denys Vlasenko   modpost: support ...
538
539
  			fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u
  ",
6845756b2   Anders Kaseorg   modpost: Update 6...
540
  			      filename, sechdrs[symtab_shndx_idx].sh_link,
1ce53adf1   Denys Vlasenko   modpost: support ...
541
542
543
544
545
546
  			      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...
547
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
548
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
549
  static void parse_elf_finish(struct elf_info *info)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
550
551
552
  {
  	release_file(info->hdr, info->size);
  }
4d7365d66   Sam Ravnborg   kbuild: ignore po...
553
554
555
  static int ignore_undef_symbol(struct elf_info *info, const char *symname)
  {
  	/* ignore __this_module, it will be resolved shortly */
b92021b09   Rusty Russell   CONFIG_SYMBOL_PRE...
556
  	if (strcmp(symname, VMLINUX_SYMBOL_STR(__this_module)) == 0)
4d7365d66   Sam Ravnborg   kbuild: ignore po...
557
558
559
560
561
562
563
564
565
  		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 */
  		if (strncmp(symname, "_restgpr_", sizeof("_restgpr_") - 1) == 0 ||
  		    strncmp(symname, "_savegpr_", sizeof("_savegpr_") - 1) == 0 ||
  		    strncmp(symname, "_rest32gpr_", sizeof("_rest32gpr_") - 1) == 0 ||
8fe9c93e7   Andreas Schwab   powerpc: Add vr s...
566
567
568
  		    strncmp(symname, "_save32gpr_", sizeof("_save32gpr_") - 1) == 0 ||
  		    strncmp(symname, "_restvr_", sizeof("_restvr_") - 1) == 0 ||
  		    strncmp(symname, "_savevr_", sizeof("_savevr_") - 1) == 0)
4d7365d66   Sam Ravnborg   kbuild: ignore po...
569
  			return 1;
7fca5dc8a   Stephen Rothwell   powerpc: Fix modu...
570
571
572
  	if (info->hdr->e_machine == EM_PPC64)
  		/* Special register function linked on all modules during final link of .ko */
  		if (strncmp(symname, "_restgpr0_", sizeof("_restgpr0_") - 1) == 0 ||
8fe9c93e7   Andreas Schwab   powerpc: Add vr s...
573
574
  		    strncmp(symname, "_savegpr0_", sizeof("_savegpr0_") - 1) == 0 ||
  		    strncmp(symname, "_restvr_", sizeof("_restvr_") - 1) == 0 ||
c153693d7   Alan Modra   powerpc: Simplify...
575
576
  		    strncmp(symname, "_savevr_", sizeof("_savevr_") - 1) == 0 ||
  		    strcmp(symname, ".TOC.") == 0)
7fca5dc8a   Stephen Rothwell   powerpc: Fix modu...
577
  			return 1;
4d7365d66   Sam Ravnborg   kbuild: ignore po...
578
579
580
  	/* Do not ignore this symbol */
  	return 0;
  }
b92021b09   Rusty Russell   CONFIG_SYMBOL_PRE...
581
582
  #define CRC_PFX     VMLINUX_SYMBOL_STR(__crc_)
  #define KSYMTAB_PFX VMLINUX_SYMBOL_STR(__ksymtab_)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
583

5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
584
585
  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
586
587
  {
  	unsigned int crc;
62a263561   Alessio Igor Bogani   modpost: Fix modp...
588
  	enum export export;
258f74263   Frank Rowand   modpost: Fix modp...
589
590
  	if ((!is_vmlinux(mod->name) || mod->is_dot_o) &&
  	    strncmp(symname, "__ksymtab", 9) == 0)
62a263561   Alessio Igor Bogani   modpost: Fix modp...
591
592
593
  		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
594

b5064654c   Andi Kleen   scripts/mod/modpo...
595
596
597
598
599
600
  	/* CRC'd symbol */
  	if (strncmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
  		crc = (unsigned int) sym->st_value;
  		sym_update_crc(symname + strlen(CRC_PFX), mod, crc,
  				export);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
601
602
  	switch (sym->st_shndx) {
  	case SHN_COMMON:
ef178f923   Andi Kleen   Kbuild, lto: Hand...
603
604
605
606
607
  		if (!strncmp(symname, "__gnu_lto_", sizeof("__gnu_lto_")-1)) {
  			/* 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
608
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
609
610
611
612
613
  	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...
614
  		if (ignore_undef_symbol(info, symname))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
615
  			break;
8d5290149   Ben Colline   [SPARC]: Deal wit...
616
617
618
619
620
621
  /* 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
622
623
624
  		if (info->hdr->e_machine == EM_SPARC ||
  		    info->hdr->e_machine == EM_SPARCV9) {
  			/* Ignore register directives. */
8d5290149   Ben Colline   [SPARC]: Deal wit...
625
  			if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
626
  				break;
62070fa42   Sam Ravnborg   kbuild: kill trai...
627
628
629
630
631
632
  			if (symname[0] == '.') {
  				char *munged = strdup(symname);
  				munged[0] = '_';
  				munged[1] = toupper(munged[1]);
  				symname = munged;
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
633
634
  		}
  #endif
62070fa42   Sam Ravnborg   kbuild: kill trai...
635

b92021b09   Rusty Russell   CONFIG_SYMBOL_PRE...
636
637
638
639
640
641
642
643
644
  #ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX
  		if (symname[0] != '_')
  			break;
  		else
  			symname++;
  #endif
  		mod->unres = alloc_symbol(symname,
  					  ELF_ST_BIND(sym->st_info) == STB_WEAK,
  					  mod->unres);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
645
646
647
  		break;
  	default:
  		/* All exported symbols */
8d99513c1   Michal Marek   modpost: fix segf...
648
  		if (strncmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
bd5cbcedf   Ram Pai   kbuild: export-ty...
649
650
  			sym_add_exported(symname + strlen(KSYMTAB_PFX), mod,
  					export);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
651
  		}
b92021b09   Rusty Russell   CONFIG_SYMBOL_PRE...
652
  		if (strcmp(symname, VMLINUX_SYMBOL_STR(init_module)) == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
653
  			mod->has_init = 1;
b92021b09   Rusty Russell   CONFIG_SYMBOL_PRE...
654
  		if (strcmp(symname, VMLINUX_SYMBOL_STR(cleanup_module)) == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
655
656
657
658
  			mod->has_cleanup = 1;
  		break;
  	}
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
659
660
661
  /**
   * Parse tag=value strings from .modinfo section
   **/
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
  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;
  }
b817f6fef   Sam Ravnborg   kbuild: check lic...
679
680
  static char *get_next_modinfo(void *modinfo, unsigned long modinfo_len,
  			      const char *tag, char *info)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
681
682
683
684
  {
  	char *p;
  	unsigned int taglen = strlen(tag);
  	unsigned long size = modinfo_len;
b817f6fef   Sam Ravnborg   kbuild: check lic...
685
686
687
688
  	if (info) {
  		size -= info - (char *)modinfo;
  		modinfo = next_string(info, &size);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
689
690
691
692
693
694
  	for (p = modinfo; p; p = next_string(p, &size)) {
  		if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
  			return p + taglen + 1;
  	}
  	return NULL;
  }
b817f6fef   Sam Ravnborg   kbuild: check lic...
695
696
697
698
699
700
  static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
  			 const char *tag)
  
  {
  	return get_next_modinfo(modinfo, modinfo_len, tag, NULL);
  }
93684d3b8   Sam Ravnborg   kbuild: include s...
701
  /**
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
702
703
704
705
706
   * 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 ...
707
  	int slen, sublen;
62070fa42   Sam Ravnborg   kbuild: kill trai...
708

4c8fbca58   Sam Ravnborg   kbuild: whitelist...
709
710
  	if (!s || !sub)
  		return 1;
62070fa42   Sam Ravnborg   kbuild: kill trai...
711

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

4c8fbca58   Sam Ravnborg   kbuild: whitelist...
715
716
  	if ((slen == 0) || (sublen == 0))
  		return 1;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
717
718
  	if (sublen > slen)
  		return 1;
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
719

df578e7d8   Sam Ravnborg   kbuild: clean up ...
720
  	return memcmp(s + slen - sublen, sub, sublen);
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
721
  }
ff13f9269   Sam Ravnborg   kbuild: introduce...
722
723
  static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
  {
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
724
725
726
  	if (sym)
  		return elf->strtab + sym->st_name;
  	else
f666751a0   Sam Ravnborg   kbuild/modpost: i...
727
  		return "(unknown)";
ff13f9269   Sam Ravnborg   kbuild: introduce...
728
  }
1ce53adf1   Denys Vlasenko   modpost: support ...
729
  static const char *sec_name(struct elf_info *elf, int secindex)
ff13f9269   Sam Ravnborg   kbuild: introduce...
730
731
732
  {
  	Elf_Shdr *sechdrs = elf->sechdrs;
  	return (void *)elf->hdr +
1ce53adf1   Denys Vlasenko   modpost: support ...
733
734
  		elf->sechdrs[elf->secindex_strings].sh_offset +
  		sechdrs[secindex].sh_name;
ff13f9269   Sam Ravnborg   kbuild: introduce...
735
736
737
738
739
  }
  
  static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr)
  {
  	return (void *)elf->hdr +
1ce53adf1   Denys Vlasenko   modpost: support ...
740
741
  		elf->sechdrs[elf->secindex_strings].sh_offset +
  		sechdr->sh_name;
ff13f9269   Sam Ravnborg   kbuild: introduce...
742
  }
10668220a   Sam Ravnborg   kbuild: introduce...
743
744
  /* The pattern is an array of simple patterns.
   * "foo" will match an exact string equal to "foo"
6c5bd235b   Sam Ravnborg   kbuild: check sec...
745
   * "*foo" will match a string that ends with "foo"
10668220a   Sam Ravnborg   kbuild: introduce...
746
   * "foo*" will match a string that begins with "foo"
09c20c032   Paul Gortmaker   modpost: expand p...
747
   * "*foo*" will match a string that contains "foo"
10668220a   Sam Ravnborg   kbuild: introduce...
748
   */
5c7251384   Trevor Keith   Fix all -Wmissing...
749
  static int match(const char *sym, const char * const pat[])
10668220a   Sam Ravnborg   kbuild: introduce...
750
751
752
753
754
  {
  	const char *p;
  	while (*pat) {
  		p = *pat++;
  		const char *endp = p + strlen(p) - 1;
09c20c032   Paul Gortmaker   modpost: expand p...
755
756
757
758
759
760
761
762
763
  		/* "*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...
764
  		/* "*foo" */
09c20c032   Paul Gortmaker   modpost: expand p...
765
  		else if (*p == '*') {
6c5bd235b   Sam Ravnborg   kbuild: check sec...
766
767
768
  			if (strrcmp(sym, p + 1) == 0)
  				return 1;
  		}
10668220a   Sam Ravnborg   kbuild: introduce...
769
  		/* "foo*" */
6c5bd235b   Sam Ravnborg   kbuild: check sec...
770
  		else if (*endp == '*') {
10668220a   Sam Ravnborg   kbuild: introduce...
771
772
773
  			if (strncmp(sym, p, strlen(p) - 1) == 0)
  				return 1;
  		}
10668220a   Sam Ravnborg   kbuild: introduce...
774
775
776
777
778
779
780
781
782
  		/* no wildcards */
  		else {
  			if (strcmp(p, sym) == 0)
  				return 1;
  		}
  	}
  	/* no match */
  	return 0;
  }
10668220a   Sam Ravnborg   kbuild: introduce...
783
  /* sections that we do not want to do full section mismatch check on */
7a3ee7538   Mathias Krause   modpost: reduce v...
784
  static const char *const section_white_list[] =
4391ed6aa   Sam Ravnborg   kbuild, modpost: ...
785
786
787
  {
  	".comment*",
  	".debug*",
4d10c223b   Chen Gang   scripts/mod/modpo...
788
  	".cranges",		/* sh64 */
1121584f5   H.J. Lu   modpost: Put .zde...
789
  	".zdebug*",		/* Compressed debug sections. */
019fca84e   David Howells   MN10300: Permit ....
790
  	".GCC-command-line",	/* mn10300 */
76b27645a   Jonathan Kliegman   modpost: Permit ....
791
  	".GCC.command.line",	/* record-gcc-switches, non mn10300 */
4391ed6aa   Sam Ravnborg   kbuild, modpost: ...
792
793
794
795
796
797
  	".mdebug*",        /* alpha, score, mips etc. */
  	".pdr",            /* alpha, score, mips etc. */
  	".stab*",
  	".note*",
  	".got*",
  	".toc*",
af42e970b   Max Filippov   modpost: fix modp...
798
799
  	".xt.prop",				 /* xtensa */
  	".xt.lit",         /* xtensa */
f2e207f32   Vineet Gupta   modpost: Ignore A...
800
801
  	".arcextmap*",			/* arc */
  	".gnu.linkonce.arcext*",	/* arc : modules */
d1189c63e   Noam Camus   scripts: [modpost...
802
803
  	".cmem*",			/* EZchip */
  	".fmt_slot*",			/* EZchip */
ef178f923   Andi Kleen   Kbuild, lto: Hand...
804
  	".gnu.lto*",
4391ed6aa   Sam Ravnborg   kbuild, modpost: ...
805
806
  	NULL
  };
10668220a   Sam Ravnborg   kbuild: introduce...
807

e241a6303   Sam Ravnborg   kbuild: warn abou...
808
  /*
b614a697d   Anders Kaseorg   kbuild, modpost: ...
809
   * This is used to find sections missing the SHF_ALLOC flag.
e241a6303   Sam Ravnborg   kbuild: warn abou...
810
   * The cause of this is often a section specified in assembler
b614a697d   Anders Kaseorg   kbuild, modpost: ...
811
   * without "ax" / "aw".
e241a6303   Sam Ravnborg   kbuild: warn abou...
812
   */
b614a697d   Anders Kaseorg   kbuild, modpost: ...
813
  static void check_section(const char *modname, struct elf_info *elf,
bb66fc671   Masahiro Yamada   kbuild: trivial -...
814
  			  Elf_Shdr *sechdr)
e241a6303   Sam Ravnborg   kbuild: warn abou...
815
  {
b614a697d   Anders Kaseorg   kbuild, modpost: ...
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
  	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...
831
  	}
e241a6303   Sam Ravnborg   kbuild: warn abou...
832
  }
eb8f68904   Sam Ravnborg   Use separate sect...
833
  #define ALL_INIT_DATA_SECTIONS \
a0d8f8037   Rasmus Villemoes   scripts: modpost:...
834
835
  	".init.setup", ".init.rodata", ".meminit.rodata", \
  	".init.data", ".meminit.data"
eb8f68904   Sam Ravnborg   Use separate sect...
836
  #define ALL_EXIT_DATA_SECTIONS \
a0d8f8037   Rasmus Villemoes   scripts: modpost:...
837
  	".exit.data", ".memexit.data"
10668220a   Sam Ravnborg   kbuild: introduce...
838

eb8f68904   Sam Ravnborg   Use separate sect...
839
  #define ALL_INIT_TEXT_SECTIONS \
a0d8f8037   Rasmus Villemoes   scripts: modpost:...
840
  	".init.text", ".meminit.text"
eb8f68904   Sam Ravnborg   Use separate sect...
841
  #define ALL_EXIT_TEXT_SECTIONS \
a0d8f8037   Rasmus Villemoes   scripts: modpost:...
842
  	".exit.text", ".memexit.text"
10668220a   Sam Ravnborg   kbuild: introduce...
843

bb15d8db7   Sebastian Andrzej Siewior   scripts/modpost: ...
844
  #define ALL_PCI_INIT_SECTIONS	\
a0d8f8037   Rasmus Villemoes   scripts: modpost:...
845
846
847
  	".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: ...
848

e24f66288   Paul Gortmaker   modpost: remove a...
849
850
  #define ALL_XXXINIT_SECTIONS MEM_INIT_SECTIONS
  #define ALL_XXXEXIT_SECTIONS MEM_EXIT_SECTIONS
4a31a229f   Uwe Kleine-König   modpost: define A...
851
852
853
  
  #define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS
  #define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS
10668220a   Sam Ravnborg   kbuild: introduce...
854

a0d8f8037   Rasmus Villemoes   scripts: modpost:...
855
  #define DATA_SECTIONS ".data", ".data.rel"
157d1972d   Quentin Casasnovas   modpost: add .sch...
856
857
  #define TEXT_SECTIONS ".text", ".text.unlikely", ".sched.text", \
  		".kprobes.text"
52dc0595d   Quentin Casasnovas   modpost: handle r...
858
  #define OTHER_TEXT_SECTIONS ".ref.text", ".head.text", ".spinlock.text", \
673c2c34f   Chris Metcalf   modpost: work cor...
859
860
  		".fixup", ".entry.text", ".exception.text", ".text.*", \
  		".coldtext"
10668220a   Sam Ravnborg   kbuild: introduce...
861

fd6c3a8dc   Jan Beulich   initconst adjustm...
862
  #define INIT_SECTIONS      ".init.*"
fd6c3a8dc   Jan Beulich   initconst adjustm...
863
  #define MEM_INIT_SECTIONS  ".meminit.*"
eb8f68904   Sam Ravnborg   Use separate sect...
864

fd6c3a8dc   Jan Beulich   initconst adjustm...
865
  #define EXIT_SECTIONS      ".exit.*"
fd6c3a8dc   Jan Beulich   initconst adjustm...
866
  #define MEM_EXIT_SECTIONS  ".memexit.*"
eb8f68904   Sam Ravnborg   Use separate sect...
867

52dc0595d   Quentin Casasnovas   modpost: handle r...
868
869
  #define ALL_TEXT_SECTIONS  ALL_INIT_TEXT_SECTIONS, ALL_EXIT_TEXT_SECTIONS, \
  		TEXT_SECTIONS, OTHER_TEXT_SECTIONS
6c5bd235b   Sam Ravnborg   kbuild: check sec...
870
  /* init data sections */
7a3ee7538   Mathias Krause   modpost: reduce v...
871
872
  static const char *const init_data_sections[] =
  	{ ALL_INIT_DATA_SECTIONS, NULL };
6c5bd235b   Sam Ravnborg   kbuild: check sec...
873
874
  
  /* all init sections */
7a3ee7538   Mathias Krause   modpost: reduce v...
875
  static const char *const init_sections[] = { ALL_INIT_SECTIONS, NULL };
6c5bd235b   Sam Ravnborg   kbuild: check sec...
876
877
  
  /* All init and exit sections (code + data) */
7a3ee7538   Mathias Krause   modpost: reduce v...
878
  static const char *const init_exit_sections[] =
eb8f68904   Sam Ravnborg   Use separate sect...
879
  	{ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL };
6c5bd235b   Sam Ravnborg   kbuild: check sec...
880

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

6c5bd235b   Sam Ravnborg   kbuild: check sec...
886
887
  
  /* symbols in .data that may refer to init/exit sections */
af92a82d0   Uwe Kleine-König   modpost: make sym...
888
889
890
891
892
893
894
895
896
  #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...
897

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

588ccd732   Sam Ravnborg   kbuild: add verbo...
903
  enum mismatch {
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
904
905
906
907
908
909
910
911
  	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...
912
  	EXPORT_TO_INIT_EXIT,
52dc0595d   Quentin Casasnovas   modpost: handle r...
913
  	EXTABLE_TO_NON_TEXT,
588ccd732   Sam Ravnborg   kbuild: add verbo...
914
  };
e5d8f59a5   Quentin Casasnovas   modpost: document...
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
  /**
   * 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...
935
936
  struct sectioncheck {
  	const char *fromsec[20];
050e57fd5   Quentin Casasnovas   modpost: add stri...
937
938
  	const char *bad_tosec[20];
  	const char *good_tosec[20];
588ccd732   Sam Ravnborg   kbuild: add verbo...
939
  	enum mismatch mismatch;
af92a82d0   Uwe Kleine-König   modpost: make sym...
940
  	const char *symbol_white_list[20];
644e8f14c   Quentin Casasnovas   modpost: add hand...
941
942
943
  	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...
944
  };
52dc0595d   Quentin Casasnovas   modpost: handle r...
945
946
947
948
  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...
949
  static const struct sectioncheck sectioncheck[] = {
10668220a   Sam Ravnborg   kbuild: introduce...
950
951
952
953
  /* Do not reference init/exit code/data from
   * normal code and data
   */
  {
588ccd732   Sam Ravnborg   kbuild: add verbo...
954
  	.fromsec = { TEXT_SECTIONS, NULL },
050e57fd5   Quentin Casasnovas   modpost: add stri...
955
  	.bad_tosec = { ALL_INIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
956
  	.mismatch = TEXT_TO_ANY_INIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
957
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
588ccd732   Sam Ravnborg   kbuild: add verbo...
958
959
960
  },
  {
  	.fromsec = { DATA_SECTIONS, NULL },
050e57fd5   Quentin Casasnovas   modpost: add stri...
961
  	.bad_tosec = { ALL_XXXINIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
962
  	.mismatch = DATA_TO_ANY_INIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
963
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
588ccd732   Sam Ravnborg   kbuild: add verbo...
964
965
  },
  {
0db252452   Uwe Kleine-König   modpost: don't al...
966
  	.fromsec = { DATA_SECTIONS, NULL },
050e57fd5   Quentin Casasnovas   modpost: add stri...
967
  	.bad_tosec = { INIT_SECTIONS, NULL },
0db252452   Uwe Kleine-König   modpost: don't al...
968
969
970
971
972
973
974
  	.mismatch = DATA_TO_ANY_INIT,
  	.symbol_white_list = {
  		"*_template", "*_timer", "*_sht", "*_ops",
  		"*_probe", "*_probe_one", "*_console", NULL
  	},
  },
  {
588ccd732   Sam Ravnborg   kbuild: add verbo...
975
  	.fromsec = { TEXT_SECTIONS, NULL },
050e57fd5   Quentin Casasnovas   modpost: add stri...
976
  	.bad_tosec = { ALL_EXIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
977
  	.mismatch = TEXT_TO_ANY_EXIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
978
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
588ccd732   Sam Ravnborg   kbuild: add verbo...
979
980
981
  },
  {
  	.fromsec = { DATA_SECTIONS, NULL },
050e57fd5   Quentin Casasnovas   modpost: add stri...
982
  	.bad_tosec = { ALL_EXIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
983
  	.mismatch = DATA_TO_ANY_EXIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
984
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
eb8f68904   Sam Ravnborg   Use separate sect...
985
  },
e24f66288   Paul Gortmaker   modpost: remove a...
986
  /* Do not reference init code/data from meminit code/data */
eb8f68904   Sam Ravnborg   Use separate sect...
987
  {
4a31a229f   Uwe Kleine-König   modpost: define A...
988
  	.fromsec = { ALL_XXXINIT_SECTIONS, NULL },
050e57fd5   Quentin Casasnovas   modpost: add stri...
989
  	.bad_tosec = { INIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
990
  	.mismatch = XXXINIT_TO_SOME_INIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
991
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
eb8f68904   Sam Ravnborg   Use separate sect...
992
  },
e24f66288   Paul Gortmaker   modpost: remove a...
993
  /* Do not reference exit code/data from memexit code/data */
eb8f68904   Sam Ravnborg   Use separate sect...
994
  {
4a31a229f   Uwe Kleine-König   modpost: define A...
995
  	.fromsec = { ALL_XXXEXIT_SECTIONS, NULL },
050e57fd5   Quentin Casasnovas   modpost: add stri...
996
  	.bad_tosec = { EXIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
997
  	.mismatch = XXXEXIT_TO_SOME_EXIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
998
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
10668220a   Sam Ravnborg   kbuild: introduce...
999
1000
1001
  },
  /* Do not use exit code/data from init code */
  {
eb8f68904   Sam Ravnborg   Use separate sect...
1002
  	.fromsec = { ALL_INIT_SECTIONS, NULL },
050e57fd5   Quentin Casasnovas   modpost: add stri...
1003
  	.bad_tosec = { ALL_EXIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1004
  	.mismatch = ANY_INIT_TO_ANY_EXIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
1005
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
10668220a   Sam Ravnborg   kbuild: introduce...
1006
1007
1008
  },
  /* Do not use init code/data from exit code */
  {
eb8f68904   Sam Ravnborg   Use separate sect...
1009
  	.fromsec = { ALL_EXIT_SECTIONS, NULL },
050e57fd5   Quentin Casasnovas   modpost: add stri...
1010
  	.bad_tosec = { ALL_INIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1011
  	.mismatch = ANY_EXIT_TO_ANY_INIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
1012
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
10668220a   Sam Ravnborg   kbuild: introduce...
1013
  },
bb15d8db7   Sebastian Andrzej Siewior   scripts/modpost: ...
1014
1015
  {
  	.fromsec = { ALL_PCI_INIT_SECTIONS, NULL },
050e57fd5   Quentin Casasnovas   modpost: add stri...
1016
  	.bad_tosec = { INIT_SECTIONS, NULL },
bb15d8db7   Sebastian Andrzej Siewior   scripts/modpost: ...
1017
1018
1019
  	.mismatch = ANY_INIT_TO_ANY_EXIT,
  	.symbol_white_list = { NULL },
  },
10668220a   Sam Ravnborg   kbuild: introduce...
1020
1021
1022
  /* Do not export init/exit functions or data */
  {
  	.fromsec = { "__ksymtab*", NULL },
050e57fd5   Quentin Casasnovas   modpost: add stri...
1023
  	.bad_tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
af92a82d0   Uwe Kleine-König   modpost: make sym...
1024
1025
  	.mismatch = EXPORT_TO_INIT_EXIT,
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
52dc0595d   Quentin Casasnovas   modpost: handle r...
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
  },
  {
  	.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...
1036
1037
  }
  };
0d2a636ee   Uwe Kleine-König   modpost: pass aro...
1038
1039
  static const struct sectioncheck *section_mismatch(
  		const char *fromsec, const char *tosec)
10668220a   Sam Ravnborg   kbuild: introduce...
1040
1041
1042
1043
  {
  	int i;
  	int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck);
  	const struct sectioncheck *check = &sectioncheck[0];
c5c3439af   Quentin Casasnovas   modpost: do not t...
1044
1045
1046
1047
1048
1049
1050
1051
  	/*
  	 * The target section could be the SHT_NUL section when we're
  	 * handling relocations to un-resolved symbols, trying to match it
  	 * doesn't make much sense and causes build failures on parisc and
  	 * mn10300 architectures.
  	 */
  	if (*tosec == '\0')
  		return NULL;
10668220a   Sam Ravnborg   kbuild: introduce...
1052
  	for (i = 0; i < elems; i++) {
050e57fd5   Quentin Casasnovas   modpost: add stri...
1053
1054
1055
1056
1057
1058
  		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...
1059
1060
  		check++;
  	}
0d2a636ee   Uwe Kleine-König   modpost: pass aro...
1061
  	return NULL;
10668220a   Sam Ravnborg   kbuild: introduce...
1062
  }
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1063
1064
  /**
   * Whitelist to allow certain references to pass with no warning.
0e0d314e6   Sam Ravnborg   kbuild: introduce...
1065
   *
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1066
1067
1068
1069
1070
1071
1072
   * 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...
1073
   *   fromsec = .data*
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1074
   *   atsym   =__param*
62070fa42   Sam Ravnborg   kbuild: kill trai...
1075
   *
6a841528d   Rusty Russell   param: silence .i...
1076
1077
1078
1079
1080
1081
1082
   * 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...
1083
   * Pattern 2:
72ee59b57   Randy Dunlap   kbuild modpost - ...
1084
   *   Many drivers utilise a *driver container with references to
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1085
   *   add, remove, probe functions etc.
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1086
   *   the pattern is identified by:
83cda2bb3   Sam Ravnborg   kbuild: be more f...
1087
1088
   *   tosec   = init or exit section
   *   fromsec = data section
df578e7d8   Sam Ravnborg   kbuild: clean up ...
1089
1090
   *   atsym = *driver, *_template, *_sht, *_ops, *_probe,
   *           *probe_one, *_console, *_timer
ee6a8545a   Vivek Goyal   [PATCH] x86-64: M...
1091
1092
   *
   * Pattern 3:
c993971f4   Sam Ravnborg   kbuild: fix comme...
1093
   *   Whitelist all references from .head.text to any init section
9bf8cb9b7   Sam Ravnborg   kbuild: fix warni...
1094
   *
1d8af559f   Sam Ravnborg   kbuild: consolida...
1095
   * Pattern 4:
ee6a8545a   Vivek Goyal   [PATCH] x86-64: M...
1096
1097
1098
1099
1100
1101
1102
   *   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...
1103
   *
4a3893d06   Paul Gortmaker   modpost: don't em...
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
   * 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...
1115
   **/
af92a82d0   Uwe Kleine-König   modpost: make sym...
1116
1117
  static int secref_whitelist(const struct sectioncheck *mismatch,
  			    const char *fromsec, const char *fromsym,
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1118
  			    const char *tosec, const char *tosym)
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1119
  {
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1120
  	/* Check for pattern 1 */
6c5bd235b   Sam Ravnborg   kbuild: check sec...
1121
1122
  	if (match(tosec, init_data_sections) &&
  	    match(fromsec, data_sections) &&
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1123
1124
  	    (strncmp(fromsym, "__param", strlen("__param")) == 0))
  		return 0;
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1125

6a841528d   Rusty Russell   param: silence .i...
1126
1127
1128
1129
1130
  	/* Check for pattern 1a */
  	if (strcmp(tosec, ".init.text") == 0 &&
  	    match(fromsec, data_sections) &&
  	    (strncmp(fromsym, "__param_ops_", strlen("__param_ops_")) == 0))
  		return 0;
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1131
  	/* Check for pattern 2 */
6c5bd235b   Sam Ravnborg   kbuild: check sec...
1132
1133
  	if (match(tosec, init_exit_sections) &&
  	    match(fromsec, data_sections) &&
af92a82d0   Uwe Kleine-König   modpost: make sym...
1134
  	    match(fromsym, mismatch->symbol_white_list))
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1135
  		return 0;
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1136

9bf8cb9b7   Sam Ravnborg   kbuild: fix warni...
1137
  	/* Check for pattern 3 */
6c5bd235b   Sam Ravnborg   kbuild: check sec...
1138
1139
  	if (match(fromsec, head_sections) &&
  	    match(tosec, init_sections))
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1140
  		return 0;
9bf8cb9b7   Sam Ravnborg   kbuild: fix warni...
1141

1d8af559f   Sam Ravnborg   kbuild: consolida...
1142
  	/* Check for pattern 4 */
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1143
1144
  	if (match(tosym, linker_symbols))
  		return 0;
9bf8cb9b7   Sam Ravnborg   kbuild: fix warni...
1145

4a3893d06   Paul Gortmaker   modpost: don't em...
1146
1147
1148
1149
1150
  	/* Check for pattern 5 */
  	if (match(fromsec, text_sections) &&
  	    match(tosec, init_sections) &&
  	    match(fromsym, optim_symbols))
  		return 0;
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1151
  	return 1;
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1152
1153
1154
  }
  
  /**
93684d3b8   Sam Ravnborg   kbuild: include s...
1155
1156
1157
1158
1159
1160
   * 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...
1161
  static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,
93684d3b8   Sam Ravnborg   kbuild: include s...
1162
1163
1164
  				Elf_Sym *relsym)
  {
  	Elf_Sym *sym;
9ad21c3f3   Sam Ravnborg   kbuild: try harde...
1165
1166
1167
  	Elf_Sym *near = NULL;
  	Elf64_Sword distance = 20;
  	Elf64_Sword d;
1ce53adf1   Denys Vlasenko   modpost: support ...
1168
  	unsigned int relsym_secindex;
93684d3b8   Sam Ravnborg   kbuild: include s...
1169
1170
1171
  
  	if (relsym->st_name != 0)
  		return relsym;
1ce53adf1   Denys Vlasenko   modpost: support ...
1172
1173
  
  	relsym_secindex = get_secindex(elf, relsym);
93684d3b8   Sam Ravnborg   kbuild: include s...
1174
  	for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
1ce53adf1   Denys Vlasenko   modpost: support ...
1175
  		if (get_secindex(elf, sym) != relsym_secindex)
93684d3b8   Sam Ravnborg   kbuild: include s...
1176
  			continue;
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1177
1178
  		if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
  			continue;
93684d3b8   Sam Ravnborg   kbuild: include s...
1179
1180
  		if (sym->st_value == addr)
  			return sym;
9ad21c3f3   Sam Ravnborg   kbuild: try harde...
1181
1182
1183
1184
1185
1186
1187
1188
  		/* 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...
1189
  	}
9ad21c3f3   Sam Ravnborg   kbuild: try harde...
1190
1191
1192
1193
1194
  	/* We need a close match */
  	if (distance < 20)
  		return near;
  	else
  		return NULL;
93684d3b8   Sam Ravnborg   kbuild: include s...
1195
  }
da68d61f8   David Brownell   [PATCH] remove mo...
1196
1197
  static inline int is_arm_mapping_symbol(const char *str)
  {
6c34f1f54   Kyle McMartin   aarch64: filter $...
1198
  	return str[0] == '$' && strchr("axtd", str[1])
da68d61f8   David Brownell   [PATCH] remove mo...
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
  	       && (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);
  }
b39927cf4   Sam Ravnborg   kbuild: check for...
1219
  /*
43c74d179   Sam Ravnborg   kbuild: in the se...
1220
1221
1222
1223
   * 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...
1224
   **/
157c23c80   Sam Ravnborg   kbuild: use simpl...
1225
1226
  static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
  				 const char *sec)
b39927cf4   Sam Ravnborg   kbuild: check for...
1227
1228
  {
  	Elf_Sym *sym;
157c23c80   Sam Ravnborg   kbuild: use simpl...
1229
  	Elf_Sym *near = NULL;
157c23c80   Sam Ravnborg   kbuild: use simpl...
1230
  	Elf_Addr distance = ~0;
62070fa42   Sam Ravnborg   kbuild: kill trai...
1231

b39927cf4   Sam Ravnborg   kbuild: check for...
1232
1233
  	for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
  		const char *symsec;
1ce53adf1   Denys Vlasenko   modpost: support ...
1234
  		if (is_shndx_special(sym->st_shndx))
b39927cf4   Sam Ravnborg   kbuild: check for...
1235
  			continue;
1ce53adf1   Denys Vlasenko   modpost: support ...
1236
  		symsec = sec_name(elf, get_secindex(elf, sym));
b39927cf4   Sam Ravnborg   kbuild: check for...
1237
1238
  		if (strcmp(symsec, sec) != 0)
  			continue;
da68d61f8   David Brownell   [PATCH] remove mo...
1239
1240
  		if (!is_valid_name(elf, sym))
  			continue;
b39927cf4   Sam Ravnborg   kbuild: check for...
1241
  		if (sym->st_value <= addr) {
157c23c80   Sam Ravnborg   kbuild: use simpl...
1242
1243
1244
1245
1246
  			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...
1247
  			}
b39927cf4   Sam Ravnborg   kbuild: check for...
1248
1249
  		}
  	}
157c23c80   Sam Ravnborg   kbuild: use simpl...
1250
  	return near;
b39927cf4   Sam Ravnborg   kbuild: check for...
1251
  }
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1252
  /*
588ccd732   Sam Ravnborg   kbuild: add verbo...
1253
1254
   * Convert a section name to the function/data attribute
   * .init.text => __init
588ccd732   Sam Ravnborg   kbuild: add verbo...
1255
1256
   * .memexitconst => __memconst
   * etc.
cbcf14a94   Andy Shevchenko   scripts/mod/modpo...
1257
1258
1259
   *
   * 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...
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
  */
  static char *sec2annotation(const char *s)
  {
  	if (match(s, init_exit_sections)) {
  		char *p = malloc(20);
  		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...
1282
  		return r;
588ccd732   Sam Ravnborg   kbuild: add verbo...
1283
  	} else {
5003bab82   Andrew Morton   fix "scripts/mod/...
1284
  		return strdup("");
588ccd732   Sam Ravnborg   kbuild: add verbo...
1285
1286
1287
1288
1289
1290
1291
1292
  	}
  }
  
  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...
1293
  		return -1;
588ccd732   Sam Ravnborg   kbuild: add verbo...
1294
  }
00759c0ea   Randy Dunlap   modpost: fix trai...
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
  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...
1308
1309
1310
1311
1312
1313
1314
1315
  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...
1316
  /*
b39927cf4   Sam Ravnborg   kbuild: check for...
1317
1318
   * Print a warning about a section mismatch.
   * Try to find symbols near it so user can find it.
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1319
   * Check whitelist before warning - it may be a false positive.
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1320
   */
0d2a636ee   Uwe Kleine-König   modpost: pass aro...
1321
1322
  static void report_sec_mismatch(const char *modname,
  				const struct sectioncheck *mismatch,
bb66fc671   Masahiro Yamada   kbuild: trivial -...
1323
1324
1325
1326
1327
1328
  				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...
1329
1330
1331
  {
  	const char *from, *from_p;
  	const char *to, *to_p;
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1332
1333
  	char *prl_from;
  	char *prl_to;
f666751a0   Sam Ravnborg   kbuild/modpost: i...
1334

e5f95c8b7   Sam Ravnborg   kbuild: print onl...
1335
1336
1337
  	sec_mismatch_count++;
  	if (!sec_mismatch_verbose)
  		return;
356ad5381   Quentin Casasnovas   modpost: factoriz...
1338
1339
  	get_pretty_name(from_is_func, &from, &from_p);
  	get_pretty_name(to_is_func, &to, &to_p);
7c0ac495e   Geert Uytterhoeven   kbuild/modpost: U...
1340
1341
1342
1343
1344
  	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...
1345

0d2a636ee   Uwe Kleine-König   modpost: pass aro...
1346
  	switch (mismatch->mismatch) {
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1347
  	case TEXT_TO_ANY_INIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1348
1349
  		prl_from = sec2annotation(fromsec);
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1350
  		fprintf(stderr,
f666751a0   Sam Ravnborg   kbuild/modpost: i...
1351
1352
  		"The function %s%s() references
  "
588ccd732   Sam Ravnborg   kbuild: add verbo...
1353
1354
1355
1356
1357
1358
  		"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...
1359
1360
1361
1362
1363
  		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...
1364
  		break;
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1365
  	case DATA_TO_ANY_INIT: {
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1366
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1367
1368
1369
1370
1371
1372
1373
  		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 ...
1374
  		"variable with __init* or __refdata (see linux/init.h) "
588ccd732   Sam Ravnborg   kbuild: add verbo...
1375
1376
  		"or name the variable:
  ",
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1377
  		fromsym, to, prl_to, tosym, to_p);
00759c0ea   Randy Dunlap   modpost: fix trai...
1378
  		print_section_list(mismatch->symbol_white_list);
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1379
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1380
  		break;
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1381
  	}
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1382
  	case TEXT_TO_ANY_EXIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1383
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1384
1385
1386
1387
1388
1389
1390
  		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...
1391
1392
  		fromsym, to, to, tosym, to_p, prl_to, tosym);
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1393
  		break;
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1394
  	case DATA_TO_ANY_EXIT: {
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1395
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
  		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...
1406
  		fromsym, to, prl_to, tosym, to_p);
00759c0ea   Randy Dunlap   modpost: fix trai...
1407
  		print_section_list(mismatch->symbol_white_list);
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1408
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1409
1410
  		break;
  	}
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1411
1412
  	case XXXINIT_TO_SOME_INIT:
  	case XXXEXIT_TO_SOME_EXIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1413
1414
  		prl_from = sec2annotation(fromsec);
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1415
1416
1417
1418
1419
1420
1421
1422
1423
  		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...
1424
1425
  		from, prl_from, fromsym, from_p,
  		to, prl_to, tosym, to_p,
b1d2675a6   Geert Uytterhoeven   kbuild: fix rever...
1426
  		tosym, fromsym, tosym);
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1427
1428
  		free(prl_from);
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1429
  		break;
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1430
  	case ANY_INIT_TO_ANY_EXIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1431
1432
  		prl_from = sec2annotation(fromsec);
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
  		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...
1447
1448
  		from, prl_from, fromsym, from_p,
  		to, prl_to, tosym, to_p,
5003bab82   Andrew Morton   fix "scripts/mod/...
1449
  		prl_to, tosym, to_p);
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1450
1451
  		free(prl_from);
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1452
  		break;
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1453
  	case ANY_EXIT_TO_ANY_INIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1454
1455
  		prl_from = sec2annotation(fromsec);
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
  		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...
1470
1471
1472
1473
1474
  		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...
1475
1476
  		break;
  	case EXPORT_TO_INIT_EXIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1477
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1478
1479
1480
1481
1482
1483
  		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...
1484
1485
  		tosym, prl_to, prl_to, tosym);
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1486
  		break;
52dc0595d   Quentin Casasnovas   modpost: handle r...
1487
1488
1489
1490
  	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...
1491
1492
1493
  	}
  	fprintf(stderr, "
  ");
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1494
  }
644e8f14c   Quentin Casasnovas   modpost: add hand...
1495
1496
1497
  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...
1498
1499
  {
  	const char *tosec;
644e8f14c   Quentin Casasnovas   modpost: add hand...
1500
1501
1502
1503
  	Elf_Sym *to;
  	Elf_Sym *from;
  	const char *tosym;
  	const char *fromsym;
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1504

644e8f14c   Quentin Casasnovas   modpost: add hand...
1505
1506
  	from = find_elf_symbol2(elf, r->r_offset, fromsec);
  	fromsym = sym_name(elf, from);
644e8f14c   Quentin Casasnovas   modpost: add hand...
1507
1508
1509
1510
  
  	if (!strncmp(fromsym, "reference___initcall",
  		     sizeof("reference___initcall")-1))
  		return;
c7a65e064   Quentin Casasnovas   modpost: mismatch...
1511
1512
1513
  	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...
1514
1515
1516
1517
1518
1519
1520
1521
1522
  	/* 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...
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
  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...
1537
  static void find_extable_entry_size(const char* const sec, const Elf_Rela* r)
52dc0595d   Quentin Casasnovas   modpost: handle r...
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
  {
  	/*
  	 * 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...
1548
  	if (!extable_entry_size)
52dc0595d   Quentin Casasnovas   modpost: handle r...
1549
1550
  		extable_entry_size = r->r_offset * 2;
  }
e84048aa1   Quentin Casasnovas   modpost: fix exta...
1551

52dc0595d   Quentin Casasnovas   modpost: handle r...
1552
1553
  static inline bool is_extable_fault_address(Elf_Rela *r)
  {
d3df4de7e   Quentin Casasnovas   modpost: fix inve...
1554
1555
1556
1557
1558
1559
  	/*
  	 * 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...
1560
1561
1562
1563
1564
1565
  		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...
1566
1567
  #define is_second_extable_reloc(Start, Cur, Sec)			\
  	(((Cur) == (Start) + 1) && (strcmp("__ex_table", (Sec)) == 0))
52dc0595d   Quentin Casasnovas   modpost: handle r...
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
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
  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...
1666
1667
1668
1669
1670
  static void check_section_mismatch(const char *modname, struct elf_info *elf,
  				   Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
  {
  	const char *tosec = sec_name(elf, get_secindex(elf, sym));;
  	const struct sectioncheck *mismatch = section_mismatch(fromsec, tosec);
0d2a636ee   Uwe Kleine-König   modpost: pass aro...
1671
  	if (mismatch) {
644e8f14c   Quentin Casasnovas   modpost: add hand...
1672
1673
1674
1675
1676
1677
  		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...
1678
1679
  	}
  }
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1680
  static unsigned int *reloc_location(struct elf_info *elf,
5b24c0715   Sam Ravnborg   kbuild: code refa...
1681
  				    Elf_Shdr *sechdr, Elf_Rela *r)
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1682
1683
  {
  	Elf_Shdr *sechdrs = elf->sechdrs;
6845756b2   Anders Kaseorg   modpost: Update 6...
1684
  	int section = sechdr->sh_info;
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1685
1686
  
  	return (void *)elf->hdr + sechdrs[section].sh_offset +
731ece41f   Olof Johansson   modpost: Fix addr...
1687
  		r->r_offset;
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1688
  }
5b24c0715   Sam Ravnborg   kbuild: code refa...
1689
  static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1690
1691
  {
  	unsigned int r_typ = ELF_R_TYPE(r->r_info);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1692
  	unsigned int *location = reloc_location(elf, sechdr, r);
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
  
  	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...
1707
1708
1709
1710
1711
1712
  #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...
1713
1714
1715
1716
1717
1718
1719
1720
1721
  #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...
1722
  static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
56a974fa2   Sam Ravnborg   kbuild: make bett...
1723
1724
1725
1726
1727
1728
  {
  	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 ...
1729
  		r->r_addend = (int)(long)
bb66fc671   Masahiro Yamada   kbuild: trivial -...
1730
  			      (elf->symtab_start + ELF_R_SYM(r->r_info));
56a974fa2   Sam Ravnborg   kbuild: make bett...
1731
1732
  		break;
  	case R_ARM_PC24:
6e2e340b5   Tony Lindgren   ARM: 7324/1: modp...
1733
1734
  	case R_ARM_CALL:
  	case R_ARM_JUMP24:
c9698e5cd   David A. Long   ARM: 7964/1: Dete...
1735
1736
1737
  	case R_ARM_THM_CALL:
  	case R_ARM_THM_JUMP24:
  	case R_ARM_THM_JUMP19:
56a974fa2   Sam Ravnborg   kbuild: make bett...
1738
  		/* From ARM ABI: ((S + A) | T) - P */
df578e7d8   Sam Ravnborg   kbuild: clean up ...
1739
  		r->r_addend = (int)(long)(elf->hdr +
bb66fc671   Masahiro Yamada   kbuild: trivial -...
1740
1741
  			      sechdr->sh_offset +
  			      (r->r_offset - sechdr->sh_addr));
56a974fa2   Sam Ravnborg   kbuild: make bett...
1742
1743
1744
1745
1746
1747
  		break;
  	default:
  		return 1;
  	}
  	return 0;
  }
5b24c0715   Sam Ravnborg   kbuild: code refa...
1748
  static int addend_mips_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1749
1750
  {
  	unsigned int r_typ = ELF_R_TYPE(r->r_info);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1751
  	unsigned int *location = reloc_location(elf, sechdr, r);
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
  	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...
1770
  static void section_rela(const char *modname, struct elf_info *elf,
bb66fc671   Masahiro Yamada   kbuild: trivial -...
1771
  			 Elf_Shdr *sechdr)
5b24c0715   Sam Ravnborg   kbuild: code refa...
1772
1773
1774
1775
1776
1777
  {
  	Elf_Sym  *sym;
  	Elf_Rela *rela;
  	Elf_Rela r;
  	unsigned int r_sym;
  	const char *fromsec;
5b24c0715   Sam Ravnborg   kbuild: code refa...
1778

ff13f9269   Sam Ravnborg   kbuild: introduce...
1779
  	Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset;
5b24c0715   Sam Ravnborg   kbuild: code refa...
1780
  	Elf_Rela *stop  = (void *)start + sechdr->sh_size;
ff13f9269   Sam Ravnborg   kbuild: introduce...
1781
  	fromsec = sech_name(elf, sechdr);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1782
1783
  	fromsec += strlen(".rela");
  	/* if from section (name) is know good then skip it */
b614a697d   Anders Kaseorg   kbuild, modpost: ...
1784
  	if (match(fromsec, section_white_list))
5b24c0715   Sam Ravnborg   kbuild: code refa...
1785
  		return;
e241a6303   Sam Ravnborg   kbuild: warn abou...
1786

5b24c0715   Sam Ravnborg   kbuild: code refa...
1787
1788
1789
  	for (rela = start; rela < stop; rela++) {
  		r.r_offset = TO_NATIVE(rela->r_offset);
  #if KERNEL_ELFCLASS == ELFCLASS64
ff13f9269   Sam Ravnborg   kbuild: introduce...
1790
  		if (elf->hdr->e_machine == EM_MIPS) {
5b24c0715   Sam Ravnborg   kbuild: code refa...
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
  			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 ...
1807
  		if (is_shndx_special(sym->st_shndx))
5b24c0715   Sam Ravnborg   kbuild: code refa...
1808
  			continue;
e84048aa1   Quentin Casasnovas   modpost: fix exta...
1809
1810
  		if (is_second_extable_reloc(start, rela, fromsec))
  			find_extable_entry_size(fromsec, &r);
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1811
  		check_section_mismatch(modname, elf, &r, sym, fromsec);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1812
1813
1814
1815
  	}
  }
  
  static void section_rel(const char *modname, struct elf_info *elf,
bb66fc671   Masahiro Yamada   kbuild: trivial -...
1816
  			Elf_Shdr *sechdr)
5b24c0715   Sam Ravnborg   kbuild: code refa...
1817
1818
1819
1820
1821
1822
  {
  	Elf_Sym *sym;
  	Elf_Rel *rel;
  	Elf_Rela r;
  	unsigned int r_sym;
  	const char *fromsec;
5b24c0715   Sam Ravnborg   kbuild: code refa...
1823

ff13f9269   Sam Ravnborg   kbuild: introduce...
1824
  	Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset;
5b24c0715   Sam Ravnborg   kbuild: code refa...
1825
  	Elf_Rel *stop  = (void *)start + sechdr->sh_size;
ff13f9269   Sam Ravnborg   kbuild: introduce...
1826
  	fromsec = sech_name(elf, sechdr);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1827
1828
  	fromsec += strlen(".rel");
  	/* if from section (name) is know good then skip it */
b614a697d   Anders Kaseorg   kbuild, modpost: ...
1829
  	if (match(fromsec, section_white_list))
5b24c0715   Sam Ravnborg   kbuild: code refa...
1830
1831
1832
1833
1834
  		return;
  
  	for (rel = start; rel < stop; rel++) {
  		r.r_offset = TO_NATIVE(rel->r_offset);
  #if KERNEL_ELFCLASS == ELFCLASS64
ff13f9269   Sam Ravnborg   kbuild: introduce...
1835
  		if (elf->hdr->e_machine == EM_MIPS) {
5b24c0715   Sam Ravnborg   kbuild: code refa...
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
  			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...
1850
  		switch (elf->hdr->e_machine) {
5b24c0715   Sam Ravnborg   kbuild: code refa...
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
  		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 ...
1866
  		if (is_shndx_special(sym->st_shndx))
5b24c0715   Sam Ravnborg   kbuild: code refa...
1867
  			continue;
e84048aa1   Quentin Casasnovas   modpost: fix exta...
1868
1869
  		if (is_second_extable_reloc(start, rel, fromsec))
  			find_extable_entry_size(fromsec, &r);
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1870
  		check_section_mismatch(modname, elf, &r, sym, fromsec);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1871
1872
  	}
  }
b39927cf4   Sam Ravnborg   kbuild: check for...
1873
1874
1875
1876
  /**
   * 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...
1877
   * marked __initdata will be discarded when the module has been initialized.
b39927cf4   Sam Ravnborg   kbuild: check for...
1878
1879
   * 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...
1880
   * only when a module is unloaded which never happens for built-in modules.
b39927cf4   Sam Ravnborg   kbuild: check for...
1881
1882
1883
1884
1885
   * 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 -...
1886
  			  struct elf_info *elf)
b39927cf4   Sam Ravnborg   kbuild: check for...
1887
1888
  {
  	int i;
b39927cf4   Sam Ravnborg   kbuild: check for...
1889
  	Elf_Shdr *sechdrs = elf->sechdrs;
62070fa42   Sam Ravnborg   kbuild: kill trai...
1890

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

fcd38ed0f   Michal Nazarewicz   scripts: modpost:...
1905
1906
1907
  	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...
1908
1909
1910
1911
  			s[n] = 0;
  	}
  	return s;
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
1912
  static void read_symbols(char *modname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1913
1914
1915
  {
  	const char *symname;
  	char *version;
b817f6fef   Sam Ravnborg   kbuild: check lic...
1916
  	char *license;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1917
1918
1919
  	struct module *mod;
  	struct elf_info info = { };
  	Elf_Sym *sym;
85bd2fddd   Sam Ravnborg   kbuild: fix secti...
1920
1921
  	if (!parse_elf(&info, modname))
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1922
1923
1924
1925
1926
1927
  
  	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
1928
  		have_vmlinux = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1929
1930
  		mod->skip = 1;
  	}
b817f6fef   Sam Ravnborg   kbuild: check lic...
1931
  	license = get_modinfo(info.modinfo, info.modinfo_len, "license");
2fa365682   Sam Ravnborg   kbuild: soften MO...
1932
1933
1934
1935
1936
1937
  	if (info.modinfo && !license && !is_vmlinux(modname))
  		warn("modpost: missing MODULE_LICENSE() in %s
  "
  		     "see include/linux/module.h for "
  		     "more information
  ", modname);
b817f6fef   Sam Ravnborg   kbuild: check lic...
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
  	while (license) {
  		if (license_is_gpl_compatible(license))
  			mod->gpl_compatible = 1;
  		else {
  			mod->gpl_compatible = 0;
  			break;
  		}
  		license = get_next_modinfo(info.modinfo, info.modinfo_len,
  					   "license", license);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1948
  	for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
7d02b490e   Andi Kleen   Kbuild, lto: Drop...
1949
  		symname = remove_dot(info.strtab + sym->st_name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1950
1951
1952
1953
  
  		handle_modversions(mod, &info, sym, symname);
  		handle_moddevtable(mod, &info, sym, symname);
  	}
d1f25e665   Sam Ravnborg   kbuild: fix so mo...
1954
  	if (!is_vmlinux(modname) ||
10668220a   Sam Ravnborg   kbuild: introduce...
1955
1956
  	     (is_vmlinux(modname) && vmlinux_section_warnings))
  		check_sec_ref(mod, modname, &info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
  
  	version = get_modinfo(info.modinfo, info.modinfo_len, "version");
  	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...
1967
  	/* Our trick to get versioning for module struct etc. - it's
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1968
1969
1970
1971
  	 * 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...
1972
  		mod->unres = alloc_symbol("module_layout", 0, mod->unres);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1973
  }
712f9b468   Rusty Russell   modpost: add -T o...
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
  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
1995
1996
1997
1998
1999
  #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...
2000
2001
  void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf,
  						      const char *fmt, ...)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2002
2003
2004
2005
  {
  	char tmp[SZ];
  	int len;
  	va_list ap;
62070fa42   Sam Ravnborg   kbuild: kill trai...
2006

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

5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
2364
  static void write_dump(const char *fname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2365
2366
2367
2368
2369
2370
2371
2372
  {
  	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 ...
2373
  			if (dump_sym(symbol))
bd5cbcedf   Ram Pai   kbuild: export-ty...
2374
2375
  				buf_printf(&buf, "0x%08x\t%s\t%s\t%s
  ",
62070fa42   Sam Ravnborg   kbuild: kill trai...
2376
  					symbol->crc, symbol->name,
bd5cbcedf   Ram Pai   kbuild: export-ty...
2377
2378
  					symbol->module->name,
  					export_str(symbol->export));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2379
2380
2381
2382
2383
  			symbol = symbol->next;
  		}
  	}
  	write_if_changed(&buf, fname);
  }
2d04b5ae1   Richard Hacker   kbuild: support l...
2384
2385
2386
2387
  struct ext_sym_list {
  	struct ext_sym_list *next;
  	const char *file;
  };
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
2388
  int main(int argc, char **argv)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2389
2390
2391
  {
  	struct module *mod;
  	struct buffer buf = { };
040fcc819   Sam Ravnborg   kbuild: improved ...
2392
  	char *kernel_read = NULL, *module_read = NULL;
712f9b468   Rusty Russell   modpost: add -T o...
2393
  	char *dump_write = NULL, *files_source = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2394
  	int opt;
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
2395
  	int err;
2d04b5ae1   Richard Hacker   kbuild: support l...
2396
2397
  	struct ext_sym_list *extsym_iter;
  	struct ext_sym_list *extsym_start = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2398

47490ec14   Nicolas Boichat   modpost: Add flag...
2399
  	while ((opt = getopt(argc, argv, "i:I:e:mnsST:o:awM:K:E")) != -1) {
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2400
2401
2402
2403
2404
2405
2406
2407
  		switch (opt) {
  		case 'i':
  			kernel_read = optarg;
  			break;
  		case 'I':
  			module_read = optarg;
  			external_module = 1;
  			break;
2d04b5ae1   Richard Hacker   kbuild: support l...
2408
2409
2410
2411
2412
2413
2414
2415
  		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 ...
2416
2417
2418
  		case 'm':
  			modversions = 1;
  			break;
eed380f3f   Guenter Roeck   modpost: Optional...
2419
2420
2421
  		case 'n':
  			ignore_missing_files = 1;
  			break;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2422
2423
2424
2425
2426
2427
2428
2429
2430
  		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...
2431
2432
2433
  		case 'S':
  			sec_mismatch_verbose = 0;
  			break;
712f9b468   Rusty Russell   modpost: add -T o...
2434
2435
2436
  		case 'T':
  			files_source = optarg;
  			break;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2437
2438
2439
  		case 'w':
  			warn_unresolved = 1;
  			break;
47490ec14   Nicolas Boichat   modpost: Add flag...
2440
2441
2442
  		case 'E':
  			sec_mismatch_fatal = 1;
  			break;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2443
2444
  		default:
  			exit(1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2445
2446
  		}
  	}
040fcc819   Sam Ravnborg   kbuild: improved ...
2447
2448
2449
2450
  	if (kernel_read)
  		read_dump(kernel_read, 1);
  	if (module_read)
  		read_dump(module_read, 0);
2d04b5ae1   Richard Hacker   kbuild: support l...
2451
2452
2453
2454
2455
2456
  	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
2457

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

712f9b468   Rusty Russell   modpost: add -T o...
2461
2462
  	if (files_source)
  		read_symbols_from_files(files_source);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2463
2464
2465
  	for (mod = modules; mod; mod = mod->next) {
  		if (mod->skip)
  			continue;
c96fca213   Sam Ravnborg   kbuild: warn when...
2466
  		check_exports(mod);
b817f6fef   Sam Ravnborg   kbuild: check lic...
2467
  	}
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
2468
  	err = 0;
b817f6fef   Sam Ravnborg   kbuild: check lic...
2469
  	for (mod = modules; mod; mod = mod->next) {
d93e1719a   Mathias Krause   modpost: simplify...
2470
  		char fname[PATH_MAX];
666ab414f   Andi Kleen   kbuild: fix a buf...
2471

b817f6fef   Sam Ravnborg   kbuild: check lic...
2472
2473
  		if (mod->skip)
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2474
2475
2476
2477
  
  		buf.pos = 0;
  
  		add_header(&buf, mod);
2449b8ba0   Ben Hutchings   module,bug: Add T...
2478
  		add_intree_flag(&buf, !external_module);
a9860bf05   Greg Kroah-Hartman   Staging: add TAIN...
2479
  		add_staging_flag(&buf, mod->name);
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
2480
  		err |= add_versions(&buf, mod);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2481
2482
2483
2484
2485
2486
2487
  		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
2488
2489
  	if (dump_write)
  		write_dump(dump_write);
47490ec14   Nicolas Boichat   modpost: Add flag...
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
  	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.
  ");
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2507

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