Blame view

scripts/mod/modpost.c 57.1 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
26
27
28
29
30
  /* Are we using CONFIG_MODVERSIONS? */
  int modversions = 0;
  /* Warn about undefined symbols? (do so if we have vmlinux) */
  int have_vmlinux = 0;
  /* 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;
eed380f3f   Guenter Roeck   modpost: Optional...
40
41
  /* ignore missing files */
  static int ignore_missing_files;
588ccd732   Sam Ravnborg   kbuild: add verbo...
42

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

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

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

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

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

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

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

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
526
527
528
529
530
531
532
  	/* 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 ...
533
534
535
  
  	if (symtab_shndx_idx != ~0U) {
  		Elf32_Word *p;
6845756b2   Anders Kaseorg   modpost: Update 6...
536
  		if (symtab_idx != sechdrs[symtab_shndx_idx].sh_link)
1ce53adf1   Denys Vlasenko   modpost: support ...
537
538
  			fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u
  ",
6845756b2   Anders Kaseorg   modpost: Update 6...
539
  			      filename, sechdrs[symtab_shndx_idx].sh_link,
1ce53adf1   Denys Vlasenko   modpost: support ...
540
541
542
543
544
545
  			      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...
546
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
547
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
548
  static void parse_elf_finish(struct elf_info *info)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
549
550
551
  {
  	release_file(info->hdr, info->size);
  }
4d7365d66   Sam Ravnborg   kbuild: ignore po...
552
553
554
  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...
555
  	if (strcmp(symname, VMLINUX_SYMBOL_STR(__this_module)) == 0)
4d7365d66   Sam Ravnborg   kbuild: ignore po...
556
557
558
559
560
561
562
563
564
  		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...
565
566
567
  		    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...
568
  			return 1;
7fca5dc8a   Stephen Rothwell   powerpc: Fix modu...
569
570
571
  	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...
572
573
574
  		    strncmp(symname, "_savegpr0_", sizeof("_savegpr0_") - 1) == 0 ||
  		    strncmp(symname, "_restvr_", sizeof("_restvr_") - 1) == 0 ||
  		    strncmp(symname, "_savevr_", sizeof("_savevr_") - 1) == 0)
7fca5dc8a   Stephen Rothwell   powerpc: Fix modu...
575
  			return 1;
4d7365d66   Sam Ravnborg   kbuild: ignore po...
576
577
578
  	/* Do not ignore this symbol */
  	return 0;
  }
b92021b09   Rusty Russell   CONFIG_SYMBOL_PRE...
579
580
  #define CRC_PFX     VMLINUX_SYMBOL_STR(__crc_)
  #define KSYMTAB_PFX VMLINUX_SYMBOL_STR(__ksymtab_)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
581

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

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

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

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

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

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

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

e241a6303   Sam Ravnborg   kbuild: warn abou...
823
  /*
b614a697d   Anders Kaseorg   kbuild, modpost: ...
824
   * This is used to find sections missing the SHF_ALLOC flag.
e241a6303   Sam Ravnborg   kbuild: warn abou...
825
   * The cause of this is often a section specified in assembler
b614a697d   Anders Kaseorg   kbuild, modpost: ...
826
   * without "ax" / "aw".
e241a6303   Sam Ravnborg   kbuild: warn abou...
827
   */
b614a697d   Anders Kaseorg   kbuild, modpost: ...
828
829
  static void check_section(const char *modname, struct elf_info *elf,
                            Elf_Shdr *sechdr)
e241a6303   Sam Ravnborg   kbuild: warn abou...
830
  {
b614a697d   Anders Kaseorg   kbuild, modpost: ...
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
  	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...
846
  	}
e241a6303   Sam Ravnborg   kbuild: warn abou...
847
  }
eb8f68904   Sam Ravnborg   Use separate sect...
848
  #define ALL_INIT_DATA_SECTIONS \
e24f66288   Paul Gortmaker   modpost: remove a...
849
850
  	".init.setup$", ".init.rodata$", ".meminit.rodata$", \
  	".init.data$", ".meminit.data$"
eb8f68904   Sam Ravnborg   Use separate sect...
851
  #define ALL_EXIT_DATA_SECTIONS \
e24f66288   Paul Gortmaker   modpost: remove a...
852
  	".exit.data$", ".memexit.data$"
10668220a   Sam Ravnborg   kbuild: introduce...
853

eb8f68904   Sam Ravnborg   Use separate sect...
854
  #define ALL_INIT_TEXT_SECTIONS \
e24f66288   Paul Gortmaker   modpost: remove a...
855
  	".init.text$", ".meminit.text$"
eb8f68904   Sam Ravnborg   Use separate sect...
856
  #define ALL_EXIT_TEXT_SECTIONS \
e24f66288   Paul Gortmaker   modpost: remove a...
857
  	".exit.text$", ".memexit.text$"
10668220a   Sam Ravnborg   kbuild: introduce...
858

bb15d8db7   Sebastian Andrzej Siewior   scripts/modpost: ...
859
860
861
862
  #define ALL_PCI_INIT_SECTIONS	\
  	".pci_fixup_early$", ".pci_fixup_header$", ".pci_fixup_final$", \
  	".pci_fixup_enable$", ".pci_fixup_resume$", \
  	".pci_fixup_resume_early$", ".pci_fixup_suspend$"
e24f66288   Paul Gortmaker   modpost: remove a...
863
864
  #define ALL_XXXINIT_SECTIONS MEM_INIT_SECTIONS
  #define ALL_XXXEXIT_SECTIONS MEM_EXIT_SECTIONS
4a31a229f   Uwe Kleine-König   modpost: define A...
865
866
867
  
  #define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS
  #define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS
10668220a   Sam Ravnborg   kbuild: introduce...
868

6c5bd235b   Sam Ravnborg   kbuild: check sec...
869
  #define DATA_SECTIONS ".data$", ".data.rel$"
06df44ee4   Tom Rini   modpost.c: Add .t...
870
  #define TEXT_SECTIONS ".text$", ".text.unlikely$"
10668220a   Sam Ravnborg   kbuild: introduce...
871

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

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

6c5bd235b   Sam Ravnborg   kbuild: check sec...
878
  /* init data sections */
eb8f68904   Sam Ravnborg   Use separate sect...
879
  static const char *init_data_sections[] = { ALL_INIT_DATA_SECTIONS, NULL };
6c5bd235b   Sam Ravnborg   kbuild: check sec...
880
881
  
  /* all init sections */
eb8f68904   Sam Ravnborg   Use separate sect...
882
  static const char *init_sections[] = { ALL_INIT_SECTIONS, NULL };
6c5bd235b   Sam Ravnborg   kbuild: check sec...
883
884
885
  
  /* All init and exit sections (code + data) */
  static const char *init_exit_sections[] =
eb8f68904   Sam Ravnborg   Use separate sect...
886
  	{ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL };
6c5bd235b   Sam Ravnborg   kbuild: check sec...
887
888
889
  
  /* data section */
  static const char *data_sections[] = { DATA_SECTIONS, NULL };
6c5bd235b   Sam Ravnborg   kbuild: check sec...
890
891
  
  /* symbols in .data that may refer to init/exit sections */
af92a82d0   Uwe Kleine-König   modpost: make sym...
892
893
894
895
896
897
898
899
900
  #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...
901
902
903
904
  
  static const char *head_sections[] = { ".head.text*", NULL };
  static const char *linker_symbols[] =
  	{ "__init_begin", "_sinittext", "_einittext", NULL };
588ccd732   Sam Ravnborg   kbuild: add verbo...
905
  enum mismatch {
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
906
907
908
909
910
911
912
913
  	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...
914
915
  	EXPORT_TO_INIT_EXIT,
  };
10668220a   Sam Ravnborg   kbuild: introduce...
916
917
918
  struct sectioncheck {
  	const char *fromsec[20];
  	const char *tosec[20];
588ccd732   Sam Ravnborg   kbuild: add verbo...
919
  	enum mismatch mismatch;
af92a82d0   Uwe Kleine-König   modpost: make sym...
920
  	const char *symbol_white_list[20];
10668220a   Sam Ravnborg   kbuild: introduce...
921
922
923
924
925
926
927
  };
  
  const struct sectioncheck sectioncheck[] = {
  /* Do not reference init/exit code/data from
   * normal code and data
   */
  {
588ccd732   Sam Ravnborg   kbuild: add verbo...
928
929
  	.fromsec = { TEXT_SECTIONS, NULL },
  	.tosec   = { ALL_INIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
930
  	.mismatch = TEXT_TO_ANY_INIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
931
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
588ccd732   Sam Ravnborg   kbuild: add verbo...
932
933
934
  },
  {
  	.fromsec = { DATA_SECTIONS, NULL },
0db252452   Uwe Kleine-König   modpost: don't al...
935
  	.tosec   = { ALL_XXXINIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
936
  	.mismatch = DATA_TO_ANY_INIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
937
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
588ccd732   Sam Ravnborg   kbuild: add verbo...
938
939
  },
  {
0db252452   Uwe Kleine-König   modpost: don't al...
940
941
942
943
944
945
946
947
948
  	.fromsec = { DATA_SECTIONS, NULL },
  	.tosec   = { INIT_SECTIONS, NULL },
  	.mismatch = DATA_TO_ANY_INIT,
  	.symbol_white_list = {
  		"*_template", "*_timer", "*_sht", "*_ops",
  		"*_probe", "*_probe_one", "*_console", NULL
  	},
  },
  {
588ccd732   Sam Ravnborg   kbuild: add verbo...
949
950
  	.fromsec = { TEXT_SECTIONS, NULL },
  	.tosec   = { ALL_EXIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
951
  	.mismatch = TEXT_TO_ANY_EXIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
952
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
588ccd732   Sam Ravnborg   kbuild: add verbo...
953
954
955
956
  },
  {
  	.fromsec = { DATA_SECTIONS, NULL },
  	.tosec   = { ALL_EXIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
957
  	.mismatch = DATA_TO_ANY_EXIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
958
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
eb8f68904   Sam Ravnborg   Use separate sect...
959
  },
e24f66288   Paul Gortmaker   modpost: remove a...
960
  /* Do not reference init code/data from meminit code/data */
eb8f68904   Sam Ravnborg   Use separate sect...
961
  {
4a31a229f   Uwe Kleine-König   modpost: define A...
962
  	.fromsec = { ALL_XXXINIT_SECTIONS, NULL },
588ccd732   Sam Ravnborg   kbuild: add verbo...
963
  	.tosec   = { INIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
964
  	.mismatch = XXXINIT_TO_SOME_INIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
965
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
eb8f68904   Sam Ravnborg   Use separate sect...
966
  },
e24f66288   Paul Gortmaker   modpost: remove a...
967
  /* Do not reference exit code/data from memexit code/data */
eb8f68904   Sam Ravnborg   Use separate sect...
968
  {
4a31a229f   Uwe Kleine-König   modpost: define A...
969
  	.fromsec = { ALL_XXXEXIT_SECTIONS, NULL },
588ccd732   Sam Ravnborg   kbuild: add verbo...
970
  	.tosec   = { EXIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
971
  	.mismatch = XXXEXIT_TO_SOME_EXIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
972
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
10668220a   Sam Ravnborg   kbuild: introduce...
973
974
975
  },
  /* Do not use exit code/data from init code */
  {
eb8f68904   Sam Ravnborg   Use separate sect...
976
977
  	.fromsec = { ALL_INIT_SECTIONS, NULL },
  	.tosec   = { ALL_EXIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
978
  	.mismatch = ANY_INIT_TO_ANY_EXIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
979
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
10668220a   Sam Ravnborg   kbuild: introduce...
980
981
982
  },
  /* Do not use init code/data from exit code */
  {
eb8f68904   Sam Ravnborg   Use separate sect...
983
  	.fromsec = { ALL_EXIT_SECTIONS, NULL },
588ccd732   Sam Ravnborg   kbuild: add verbo...
984
  	.tosec   = { ALL_INIT_SECTIONS, NULL },
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
985
  	.mismatch = ANY_EXIT_TO_ANY_INIT,
af92a82d0   Uwe Kleine-König   modpost: make sym...
986
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
10668220a   Sam Ravnborg   kbuild: introduce...
987
  },
bb15d8db7   Sebastian Andrzej Siewior   scripts/modpost: ...
988
989
990
991
992
993
  {
  	.fromsec = { ALL_PCI_INIT_SECTIONS, NULL },
  	.tosec   = { INIT_SECTIONS, NULL },
  	.mismatch = ANY_INIT_TO_ANY_EXIT,
  	.symbol_white_list = { NULL },
  },
10668220a   Sam Ravnborg   kbuild: introduce...
994
995
996
  /* Do not export init/exit functions or data */
  {
  	.fromsec = { "__ksymtab*", NULL },
fa95eb1f1   Sam Ravnborg   kbuild: do not wa...
997
  	.tosec   = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
af92a82d0   Uwe Kleine-König   modpost: make sym...
998
999
  	.mismatch = EXPORT_TO_INIT_EXIT,
  	.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
10668220a   Sam Ravnborg   kbuild: introduce...
1000
1001
  }
  };
0d2a636ee   Uwe Kleine-König   modpost: pass aro...
1002
1003
  static const struct sectioncheck *section_mismatch(
  		const char *fromsec, const char *tosec)
10668220a   Sam Ravnborg   kbuild: introduce...
1004
1005
1006
1007
1008
1009
1010
1011
  {
  	int i;
  	int elems = sizeof(sectioncheck) / sizeof(struct sectioncheck);
  	const struct sectioncheck *check = &sectioncheck[0];
  
  	for (i = 0; i < elems; i++) {
  		if (match(fromsec, check->fromsec) &&
  		    match(tosec, check->tosec))
0d2a636ee   Uwe Kleine-König   modpost: pass aro...
1012
  			return check;
10668220a   Sam Ravnborg   kbuild: introduce...
1013
1014
  		check++;
  	}
0d2a636ee   Uwe Kleine-König   modpost: pass aro...
1015
  	return NULL;
10668220a   Sam Ravnborg   kbuild: introduce...
1016
  }
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1017
1018
  /**
   * Whitelist to allow certain references to pass with no warning.
0e0d314e6   Sam Ravnborg   kbuild: introduce...
1019
   *
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1020
1021
1022
1023
1024
1025
1026
   * 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...
1027
   *   fromsec = .data*
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1028
   *   atsym   =__param*
62070fa42   Sam Ravnborg   kbuild: kill trai...
1029
   *
6a841528d   Rusty Russell   param: silence .i...
1030
1031
1032
1033
1034
1035
1036
   * 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...
1037
   * Pattern 2:
72ee59b57   Randy Dunlap   kbuild modpost - ...
1038
   *   Many drivers utilise a *driver container with references to
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1039
   *   add, remove, probe functions etc.
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1040
   *   the pattern is identified by:
83cda2bb3   Sam Ravnborg   kbuild: be more f...
1041
1042
   *   tosec   = init or exit section
   *   fromsec = data section
df578e7d8   Sam Ravnborg   kbuild: clean up ...
1043
1044
   *   atsym = *driver, *_template, *_sht, *_ops, *_probe,
   *           *probe_one, *_console, *_timer
ee6a8545a   Vivek Goyal   [PATCH] x86-64: M...
1045
1046
   *
   * Pattern 3:
c993971f4   Sam Ravnborg   kbuild: fix comme...
1047
   *   Whitelist all references from .head.text to any init section
9bf8cb9b7   Sam Ravnborg   kbuild: fix warni...
1048
   *
1d8af559f   Sam Ravnborg   kbuild: consolida...
1049
   * Pattern 4:
ee6a8545a   Vivek Goyal   [PATCH] x86-64: M...
1050
1051
1052
1053
1054
1055
1056
   *   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...
1057
   *
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1058
   **/
af92a82d0   Uwe Kleine-König   modpost: make sym...
1059
1060
  static int secref_whitelist(const struct sectioncheck *mismatch,
  			    const char *fromsec, const char *fromsym,
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1061
  			    const char *tosec, const char *tosym)
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1062
  {
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1063
  	/* Check for pattern 1 */
6c5bd235b   Sam Ravnborg   kbuild: check sec...
1064
1065
  	if (match(tosec, init_data_sections) &&
  	    match(fromsec, data_sections) &&
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1066
1067
  	    (strncmp(fromsym, "__param", strlen("__param")) == 0))
  		return 0;
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1068

6a841528d   Rusty Russell   param: silence .i...
1069
1070
1071
1072
1073
  	/* 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...
1074
  	/* Check for pattern 2 */
6c5bd235b   Sam Ravnborg   kbuild: check sec...
1075
1076
  	if (match(tosec, init_exit_sections) &&
  	    match(fromsec, data_sections) &&
af92a82d0   Uwe Kleine-König   modpost: make sym...
1077
  	    match(fromsym, mismatch->symbol_white_list))
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1078
  		return 0;
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1079

9bf8cb9b7   Sam Ravnborg   kbuild: fix warni...
1080
  	/* Check for pattern 3 */
6c5bd235b   Sam Ravnborg   kbuild: check sec...
1081
1082
  	if (match(fromsec, head_sections) &&
  	    match(tosec, init_sections))
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1083
  		return 0;
9bf8cb9b7   Sam Ravnborg   kbuild: fix warni...
1084

1d8af559f   Sam Ravnborg   kbuild: consolida...
1085
  	/* Check for pattern 4 */
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1086
1087
  	if (match(tosym, linker_symbols))
  		return 0;
9bf8cb9b7   Sam Ravnborg   kbuild: fix warni...
1088

58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1089
  	return 1;
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1090
1091
1092
  }
  
  /**
93684d3b8   Sam Ravnborg   kbuild: include s...
1093
1094
1095
1096
1097
1098
   * 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...
1099
  static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,
93684d3b8   Sam Ravnborg   kbuild: include s...
1100
1101
1102
  				Elf_Sym *relsym)
  {
  	Elf_Sym *sym;
9ad21c3f3   Sam Ravnborg   kbuild: try harde...
1103
1104
1105
  	Elf_Sym *near = NULL;
  	Elf64_Sword distance = 20;
  	Elf64_Sword d;
1ce53adf1   Denys Vlasenko   modpost: support ...
1106
  	unsigned int relsym_secindex;
93684d3b8   Sam Ravnborg   kbuild: include s...
1107
1108
1109
  
  	if (relsym->st_name != 0)
  		return relsym;
1ce53adf1   Denys Vlasenko   modpost: support ...
1110
1111
  
  	relsym_secindex = get_secindex(elf, relsym);
93684d3b8   Sam Ravnborg   kbuild: include s...
1112
  	for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
1ce53adf1   Denys Vlasenko   modpost: support ...
1113
  		if (get_secindex(elf, sym) != relsym_secindex)
93684d3b8   Sam Ravnborg   kbuild: include s...
1114
  			continue;
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1115
1116
  		if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
  			continue;
93684d3b8   Sam Ravnborg   kbuild: include s...
1117
1118
  		if (sym->st_value == addr)
  			return sym;
9ad21c3f3   Sam Ravnborg   kbuild: try harde...
1119
1120
1121
1122
1123
1124
1125
1126
  		/* 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...
1127
  	}
9ad21c3f3   Sam Ravnborg   kbuild: try harde...
1128
1129
1130
1131
1132
  	/* We need a close match */
  	if (distance < 20)
  		return near;
  	else
  		return NULL;
93684d3b8   Sam Ravnborg   kbuild: include s...
1133
  }
da68d61f8   David Brownell   [PATCH] remove mo...
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
  static inline int is_arm_mapping_symbol(const char *str)
  {
  	return str[0] == '$' && strchr("atd", str[1])
  	       && (str[2] == '\0' || str[2] == '.');
  }
  
  /*
   * If there's no name there, ignore it; likewise, ignore it if it's
   * one of the magic symbols emitted used by current ARM tools.
   *
   * Otherwise if find_symbols_between() returns those symbols, they'll
   * fail the whitelist tests and cause lots of false alarms ... fixable
   * only by merging __exit and __init sections into __text, bloating
   * the kernel (which is especially evil on embedded platforms).
   */
  static inline int is_valid_name(struct elf_info *elf, Elf_Sym *sym)
  {
  	const char *name = elf->strtab + sym->st_name;
  
  	if (!name || !strlen(name))
  		return 0;
  	return !is_arm_mapping_symbol(name);
  }
b39927cf4   Sam Ravnborg   kbuild: check for...
1157
  /*
43c74d179   Sam Ravnborg   kbuild: in the se...
1158
1159
1160
1161
   * 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...
1162
   **/
157c23c80   Sam Ravnborg   kbuild: use simpl...
1163
1164
  static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
  				 const char *sec)
b39927cf4   Sam Ravnborg   kbuild: check for...
1165
1166
  {
  	Elf_Sym *sym;
157c23c80   Sam Ravnborg   kbuild: use simpl...
1167
  	Elf_Sym *near = NULL;
157c23c80   Sam Ravnborg   kbuild: use simpl...
1168
  	Elf_Addr distance = ~0;
62070fa42   Sam Ravnborg   kbuild: kill trai...
1169

b39927cf4   Sam Ravnborg   kbuild: check for...
1170
1171
  	for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
  		const char *symsec;
1ce53adf1   Denys Vlasenko   modpost: support ...
1172
  		if (is_shndx_special(sym->st_shndx))
b39927cf4   Sam Ravnborg   kbuild: check for...
1173
  			continue;
1ce53adf1   Denys Vlasenko   modpost: support ...
1174
  		symsec = sec_name(elf, get_secindex(elf, sym));
b39927cf4   Sam Ravnborg   kbuild: check for...
1175
1176
  		if (strcmp(symsec, sec) != 0)
  			continue;
da68d61f8   David Brownell   [PATCH] remove mo...
1177
1178
  		if (!is_valid_name(elf, sym))
  			continue;
b39927cf4   Sam Ravnborg   kbuild: check for...
1179
  		if (sym->st_value <= addr) {
157c23c80   Sam Ravnborg   kbuild: use simpl...
1180
1181
1182
1183
1184
  			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...
1185
  			}
b39927cf4   Sam Ravnborg   kbuild: check for...
1186
1187
  		}
  	}
157c23c80   Sam Ravnborg   kbuild: use simpl...
1188
  	return near;
b39927cf4   Sam Ravnborg   kbuild: check for...
1189
  }
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1190
  /*
588ccd732   Sam Ravnborg   kbuild: add verbo...
1191
1192
   * Convert a section name to the function/data attribute
   * .init.text => __init
588ccd732   Sam Ravnborg   kbuild: add verbo...
1193
1194
   * .memexitconst => __memconst
   * etc.
cbcf14a94   Andy Shevchenko   scripts/mod/modpo...
1195
1196
1197
   *
   * 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...
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
  */
  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...
1220
  		return r;
588ccd732   Sam Ravnborg   kbuild: add verbo...
1221
  	} else {
5003bab82   Andrew Morton   fix "scripts/mod/...
1222
  		return strdup("");
588ccd732   Sam Ravnborg   kbuild: add verbo...
1223
1224
1225
1226
1227
1228
1229
1230
  	}
  }
  
  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...
1231
  		return -1;
588ccd732   Sam Ravnborg   kbuild: add verbo...
1232
  }
00759c0ea   Randy Dunlap   modpost: fix trai...
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
  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, "
  ");
  }
588ccd732   Sam Ravnborg   kbuild: add verbo...
1246
  /*
b39927cf4   Sam Ravnborg   kbuild: check for...
1247
1248
   * Print a warning about a section mismatch.
   * Try to find symbols near it so user can find it.
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1249
   * Check whitelist before warning - it may be a false positive.
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1250
   */
0d2a636ee   Uwe Kleine-König   modpost: pass aro...
1251
1252
  static void report_sec_mismatch(const char *modname,
  				const struct sectioncheck *mismatch,
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1253
1254
1255
                                  const char *fromsec,
                                  unsigned long long fromaddr,
                                  const char *fromsym,
588ccd732   Sam Ravnborg   kbuild: add verbo...
1256
1257
1258
1259
1260
1261
                                  int from_is_func,
                                  const char *tosec, const char *tosym,
                                  int to_is_func)
  {
  	const char *from, *from_p;
  	const char *to, *to_p;
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1262
1263
  	char *prl_from;
  	char *prl_to;
f666751a0   Sam Ravnborg   kbuild/modpost: i...
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
  
  	switch (from_is_func) {
  	case 0: from = "variable"; from_p = "";   break;
  	case 1: from = "function"; from_p = "()"; break;
  	default: from = "(unknown reference)"; from_p = ""; break;
  	}
  	switch (to_is_func) {
  	case 0: to = "variable"; to_p = "";   break;
  	case 1: to = "function"; to_p = "()"; break;
  	default: to = "(unknown reference)"; to_p = ""; break;
  	}
588ccd732   Sam Ravnborg   kbuild: add verbo...
1275

e5f95c8b7   Sam Ravnborg   kbuild: print onl...
1276
1277
1278
  	sec_mismatch_count++;
  	if (!sec_mismatch_verbose)
  		return;
7c0ac495e   Geert Uytterhoeven   kbuild/modpost: U...
1279
1280
1281
1282
1283
  	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...
1284

0d2a636ee   Uwe Kleine-König   modpost: pass aro...
1285
  	switch (mismatch->mismatch) {
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1286
  	case TEXT_TO_ANY_INIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1287
1288
  		prl_from = sec2annotation(fromsec);
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1289
  		fprintf(stderr,
f666751a0   Sam Ravnborg   kbuild/modpost: i...
1290
1291
  		"The function %s%s() references
  "
588ccd732   Sam Ravnborg   kbuild: add verbo...
1292
1293
1294
1295
1296
1297
  		"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...
1298
1299
1300
1301
1302
  		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...
1303
  		break;
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1304
  	case DATA_TO_ANY_INIT: {
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1305
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1306
1307
1308
1309
1310
1311
1312
  		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 ...
1313
  		"variable with __init* or __refdata (see linux/init.h) "
588ccd732   Sam Ravnborg   kbuild: add verbo...
1314
1315
  		"or name the variable:
  ",
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1316
  		fromsym, to, prl_to, tosym, to_p);
00759c0ea   Randy Dunlap   modpost: fix trai...
1317
  		print_section_list(mismatch->symbol_white_list);
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1318
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1319
  		break;
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1320
  	}
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1321
  	case TEXT_TO_ANY_EXIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1322
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1323
1324
1325
1326
1327
1328
1329
  		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...
1330
1331
  		fromsym, to, to, tosym, to_p, prl_to, tosym);
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1332
  		break;
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1333
  	case DATA_TO_ANY_EXIT: {
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1334
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
  		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...
1345
  		fromsym, to, prl_to, tosym, to_p);
00759c0ea   Randy Dunlap   modpost: fix trai...
1346
  		print_section_list(mismatch->symbol_white_list);
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1347
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1348
1349
  		break;
  	}
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1350
1351
  	case XXXINIT_TO_SOME_INIT:
  	case XXXEXIT_TO_SOME_EXIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1352
1353
  		prl_from = sec2annotation(fromsec);
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1354
1355
1356
1357
1358
1359
1360
1361
1362
  		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...
1363
1364
  		from, prl_from, fromsym, from_p,
  		to, prl_to, tosym, to_p,
b1d2675a6   Geert Uytterhoeven   kbuild: fix rever...
1365
  		tosym, fromsym, tosym);
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1366
1367
  		free(prl_from);
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1368
  		break;
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1369
  	case ANY_INIT_TO_ANY_EXIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1370
1371
  		prl_from = sec2annotation(fromsec);
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
  		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...
1386
1387
  		from, prl_from, fromsym, from_p,
  		to, prl_to, tosym, to_p,
5003bab82   Andrew Morton   fix "scripts/mod/...
1388
  		prl_to, tosym, to_p);
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1389
1390
  		free(prl_from);
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1391
  		break;
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1392
  	case ANY_EXIT_TO_ANY_INIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1393
1394
  		prl_from = sec2annotation(fromsec);
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
  		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...
1409
1410
1411
1412
1413
  		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...
1414
1415
  		break;
  	case EXPORT_TO_INIT_EXIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1416
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1417
1418
1419
1420
1421
1422
  		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...
1423
1424
  		tosym, prl_to, prl_to, tosym);
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1425
1426
1427
1428
  		break;
  	}
  	fprintf(stderr, "
  ");
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1429
1430
1431
1432
1433
1434
  }
  
  static void check_section_mismatch(const char *modname, struct elf_info *elf,
                                     Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
  {
  	const char *tosec;
0d2a636ee   Uwe Kleine-König   modpost: pass aro...
1435
  	const struct sectioncheck *mismatch;
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1436

1ce53adf1   Denys Vlasenko   modpost: support ...
1437
  	tosec = sec_name(elf, get_secindex(elf, sym));
588ccd732   Sam Ravnborg   kbuild: add verbo...
1438
  	mismatch = section_mismatch(fromsec, tosec);
0d2a636ee   Uwe Kleine-König   modpost: pass aro...
1439
  	if (mismatch) {
588ccd732   Sam Ravnborg   kbuild: add verbo...
1440
1441
  		Elf_Sym *to;
  		Elf_Sym *from;
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1442
  		const char *tosym;
588ccd732   Sam Ravnborg   kbuild: add verbo...
1443
  		const char *fromsym;
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1444

588ccd732   Sam Ravnborg   kbuild: add verbo...
1445
1446
1447
1448
  		from = find_elf_symbol2(elf, r->r_offset, fromsec);
  		fromsym = sym_name(elf, from);
  		to = find_elf_symbol(elf, r->r_addend, sym);
  		tosym = sym_name(elf, to);
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1449

77ab21ada   Andi Kleen   Kbuild, lto, work...
1450
1451
1452
  		if (!strncmp(fromsym, "reference___initcall",
  				sizeof("reference___initcall")-1))
  			return;
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1453
  		/* check whitelist - we may ignore it */
af92a82d0   Uwe Kleine-König   modpost: make sym...
1454
1455
  		if (secref_whitelist(mismatch,
  					fromsec, fromsym, tosec, tosym)) {
588ccd732   Sam Ravnborg   kbuild: add verbo...
1456
1457
1458
1459
  			report_sec_mismatch(modname, mismatch,
  			   fromsec, r->r_offset, fromsym,
  			   is_function(from), tosec, tosym,
  			   is_function(to));
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1460
  		}
b39927cf4   Sam Ravnborg   kbuild: check for...
1461
1462
  	}
  }
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1463
  static unsigned int *reloc_location(struct elf_info *elf,
5b24c0715   Sam Ravnborg   kbuild: code refa...
1464
  				    Elf_Shdr *sechdr, Elf_Rela *r)
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1465
1466
  {
  	Elf_Shdr *sechdrs = elf->sechdrs;
6845756b2   Anders Kaseorg   modpost: Update 6...
1467
  	int section = sechdr->sh_info;
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1468
1469
  
  	return (void *)elf->hdr + sechdrs[section].sh_offset +
731ece41f   Olof Johansson   modpost: Fix addr...
1470
  		r->r_offset;
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1471
  }
5b24c0715   Sam Ravnborg   kbuild: code refa...
1472
  static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1473
1474
  {
  	unsigned int r_typ = ELF_R_TYPE(r->r_info);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1475
  	unsigned int *location = reloc_location(elf, sechdr, r);
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
  
  	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...
1490
1491
1492
1493
1494
1495
  #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...
1496
1497
1498
1499
1500
1501
1502
1503
1504
  #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...
1505
  static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
56a974fa2   Sam Ravnborg   kbuild: make bett...
1506
1507
1508
1509
1510
1511
  {
  	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 ...
1512
1513
  		r->r_addend = (int)(long)
  		              (elf->symtab_start + ELF_R_SYM(r->r_info));
56a974fa2   Sam Ravnborg   kbuild: make bett...
1514
1515
  		break;
  	case R_ARM_PC24:
6e2e340b5   Tony Lindgren   ARM: 7324/1: modp...
1516
1517
  	case R_ARM_CALL:
  	case R_ARM_JUMP24:
c9698e5cd   David A. Long   ARM: 7964/1: Dete...
1518
1519
1520
  	case R_ARM_THM_CALL:
  	case R_ARM_THM_JUMP24:
  	case R_ARM_THM_JUMP19:
56a974fa2   Sam Ravnborg   kbuild: make bett...
1521
  		/* From ARM ABI: ((S + A) | T) - P */
df578e7d8   Sam Ravnborg   kbuild: clean up ...
1522
  		r->r_addend = (int)(long)(elf->hdr +
5b24c0715   Sam Ravnborg   kbuild: code refa...
1523
1524
  		              sechdr->sh_offset +
  		              (r->r_offset - sechdr->sh_addr));
56a974fa2   Sam Ravnborg   kbuild: make bett...
1525
1526
1527
1528
1529
1530
  		break;
  	default:
  		return 1;
  	}
  	return 0;
  }
5b24c0715   Sam Ravnborg   kbuild: code refa...
1531
  static int addend_mips_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1532
1533
  {
  	unsigned int r_typ = ELF_R_TYPE(r->r_info);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1534
  	unsigned int *location = reloc_location(elf, sechdr, r);
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
  	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...
1553
  static void section_rela(const char *modname, struct elf_info *elf,
10668220a   Sam Ravnborg   kbuild: introduce...
1554
                           Elf_Shdr *sechdr)
5b24c0715   Sam Ravnborg   kbuild: code refa...
1555
1556
1557
1558
1559
1560
  {
  	Elf_Sym  *sym;
  	Elf_Rela *rela;
  	Elf_Rela r;
  	unsigned int r_sym;
  	const char *fromsec;
5b24c0715   Sam Ravnborg   kbuild: code refa...
1561

ff13f9269   Sam Ravnborg   kbuild: introduce...
1562
  	Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset;
5b24c0715   Sam Ravnborg   kbuild: code refa...
1563
  	Elf_Rela *stop  = (void *)start + sechdr->sh_size;
ff13f9269   Sam Ravnborg   kbuild: introduce...
1564
  	fromsec = sech_name(elf, sechdr);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1565
1566
  	fromsec += strlen(".rela");
  	/* if from section (name) is know good then skip it */
b614a697d   Anders Kaseorg   kbuild, modpost: ...
1567
  	if (match(fromsec, section_white_list))
5b24c0715   Sam Ravnborg   kbuild: code refa...
1568
  		return;
e241a6303   Sam Ravnborg   kbuild: warn abou...
1569

5b24c0715   Sam Ravnborg   kbuild: code refa...
1570
1571
1572
  	for (rela = start; rela < stop; rela++) {
  		r.r_offset = TO_NATIVE(rela->r_offset);
  #if KERNEL_ELFCLASS == ELFCLASS64
ff13f9269   Sam Ravnborg   kbuild: introduce...
1573
  		if (elf->hdr->e_machine == EM_MIPS) {
5b24c0715   Sam Ravnborg   kbuild: code refa...
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
  			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 ...
1590
  		if (is_shndx_special(sym->st_shndx))
5b24c0715   Sam Ravnborg   kbuild: code refa...
1591
  			continue;
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1592
  		check_section_mismatch(modname, elf, &r, sym, fromsec);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1593
1594
1595
1596
  	}
  }
  
  static void section_rel(const char *modname, struct elf_info *elf,
10668220a   Sam Ravnborg   kbuild: introduce...
1597
                          Elf_Shdr *sechdr)
5b24c0715   Sam Ravnborg   kbuild: code refa...
1598
1599
1600
1601
1602
1603
  {
  	Elf_Sym *sym;
  	Elf_Rel *rel;
  	Elf_Rela r;
  	unsigned int r_sym;
  	const char *fromsec;
5b24c0715   Sam Ravnborg   kbuild: code refa...
1604

ff13f9269   Sam Ravnborg   kbuild: introduce...
1605
  	Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset;
5b24c0715   Sam Ravnborg   kbuild: code refa...
1606
  	Elf_Rel *stop  = (void *)start + sechdr->sh_size;
ff13f9269   Sam Ravnborg   kbuild: introduce...
1607
  	fromsec = sech_name(elf, sechdr);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1608
1609
  	fromsec += strlen(".rel");
  	/* if from section (name) is know good then skip it */
b614a697d   Anders Kaseorg   kbuild, modpost: ...
1610
  	if (match(fromsec, section_white_list))
5b24c0715   Sam Ravnborg   kbuild: code refa...
1611
1612
1613
1614
1615
  		return;
  
  	for (rel = start; rel < stop; rel++) {
  		r.r_offset = TO_NATIVE(rel->r_offset);
  #if KERNEL_ELFCLASS == ELFCLASS64
ff13f9269   Sam Ravnborg   kbuild: introduce...
1616
  		if (elf->hdr->e_machine == EM_MIPS) {
5b24c0715   Sam Ravnborg   kbuild: code refa...
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
  			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...
1631
  		switch (elf->hdr->e_machine) {
5b24c0715   Sam Ravnborg   kbuild: code refa...
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
  		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 ...
1647
  		if (is_shndx_special(sym->st_shndx))
5b24c0715   Sam Ravnborg   kbuild: code refa...
1648
  			continue;
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1649
  		check_section_mismatch(modname, elf, &r, sym, fromsec);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1650
1651
  	}
  }
b39927cf4   Sam Ravnborg   kbuild: check for...
1652
1653
1654
1655
  /**
   * 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...
1656
   * marked __initdata will be discarded when the module has been initialized.
b39927cf4   Sam Ravnborg   kbuild: check for...
1657
1658
   * 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...
1659
   * only when a module is unloaded which never happens for built-in modules.
b39927cf4   Sam Ravnborg   kbuild: check for...
1660
1661
1662
1663
1664
   * 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,
10668220a   Sam Ravnborg   kbuild: introduce...
1665
                            struct elf_info *elf)
b39927cf4   Sam Ravnborg   kbuild: check for...
1666
1667
  {
  	int i;
b39927cf4   Sam Ravnborg   kbuild: check for...
1668
  	Elf_Shdr *sechdrs = elf->sechdrs;
62070fa42   Sam Ravnborg   kbuild: kill trai...
1669

b39927cf4   Sam Ravnborg   kbuild: check for...
1670
  	/* Walk through all sections */
1ce53adf1   Denys Vlasenko   modpost: support ...
1671
  	for (i = 0; i < elf->num_sections; i++) {
b614a697d   Anders Kaseorg   kbuild, modpost: ...
1672
  		check_section(modname, elf, &elf->sechdrs[i]);
b39927cf4   Sam Ravnborg   kbuild: check for...
1673
  		/* We want to process only relocation sections and not .init */
5b24c0715   Sam Ravnborg   kbuild: code refa...
1674
  		if (sechdrs[i].sh_type == SHT_RELA)
10668220a   Sam Ravnborg   kbuild: introduce...
1675
  			section_rela(modname, elf, &elf->sechdrs[i]);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1676
  		else if (sechdrs[i].sh_type == SHT_REL)
10668220a   Sam Ravnborg   kbuild: introduce...
1677
  			section_rel(modname, elf, &elf->sechdrs[i]);
b39927cf4   Sam Ravnborg   kbuild: check for...
1678
1679
  	}
  }
7d02b490e   Andi Kleen   Kbuild, lto: Drop...
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
  static char *remove_dot(char *s)
  {
  	char *end;
  	int n = strcspn(s, ".");
  
  	if (n > 0 && s[n] != 0) {
  		strtoul(s + n + 1, &end, 10);
  		if  (end > s + n + 1 && (*end == '.' || *end == 0))
  			s[n] = 0;
  	}
  	return s;
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
1692
  static void read_symbols(char *modname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1693
1694
1695
  {
  	const char *symname;
  	char *version;
b817f6fef   Sam Ravnborg   kbuild: check lic...
1696
  	char *license;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1697
1698
1699
  	struct module *mod;
  	struct elf_info info = { };
  	Elf_Sym *sym;
85bd2fddd   Sam Ravnborg   kbuild: fix secti...
1700
1701
  	if (!parse_elf(&info, modname))
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1702
1703
1704
1705
1706
1707
  
  	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
1708
  		have_vmlinux = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1709
1710
  		mod->skip = 1;
  	}
b817f6fef   Sam Ravnborg   kbuild: check lic...
1711
  	license = get_modinfo(info.modinfo, info.modinfo_len, "license");
2fa365682   Sam Ravnborg   kbuild: soften MO...
1712
1713
1714
1715
1716
1717
  	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...
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
  	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
1728
  	for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
7d02b490e   Andi Kleen   Kbuild, lto: Drop...
1729
  		symname = remove_dot(info.strtab + sym->st_name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1730
1731
1732
1733
  
  		handle_modversions(mod, &info, sym, symname);
  		handle_moddevtable(mod, &info, sym, symname);
  	}
d1f25e665   Sam Ravnborg   kbuild: fix so mo...
1734
  	if (!is_vmlinux(modname) ||
10668220a   Sam Ravnborg   kbuild: introduce...
1735
1736
  	     (is_vmlinux(modname) && vmlinux_section_warnings))
  		check_sec_ref(mod, modname, &info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
  
  	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...
1747
  	/* Our trick to get versioning for module struct etc. - it's
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1748
1749
1750
1751
  	 * 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...
1752
  		mod->unres = alloc_symbol("module_layout", 0, mod->unres);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1753
  }
712f9b468   Rusty Russell   modpost: add -T o...
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
  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
1775
1776
1777
1778
1779
  #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...
1780
1781
  void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf,
  						      const char *fmt, ...)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1782
1783
1784
1785
  {
  	char tmp[SZ];
  	int len;
  	va_list ap;
62070fa42   Sam Ravnborg   kbuild: kill trai...
1786

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1787
1788
  	va_start(ap, fmt);
  	len = vsnprintf(tmp, SZ, fmt, ap);
7670f023a   Sam Ravnborg   [PATCH] kbuild: f...
1789
  	buf_write(buf, tmp, len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1790
1791
  	va_end(ap);
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
1792
  void buf_write(struct buffer *buf, const char *s, int len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1793
1794
  {
  	if (buf->size - buf->pos < len) {
7670f023a   Sam Ravnborg   [PATCH] kbuild: f...
1795
  		buf->size += len + SZ;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1796
1797
1798
1799
1800
  		buf->p = realloc(buf->p, buf->size);
  	}
  	strncpy(buf->p + buf->pos, s, len);
  	buf->pos += len;
  }
c96fca213   Sam Ravnborg   kbuild: warn when...
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
  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 ...
1828
  static void check_for_unused(enum export exp, const char *m, const char *s)
c96fca213   Sam Ravnborg   kbuild: warn when...
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
  {
  	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...
1846
1847
1848
1849
  {
  	struct symbol *s, *exp;
  
  	for (s = mod->unres; s; s = s->next) {
6449bd621   Andrew Morton   kbuild: modpost b...
1850
  		const char *basename;
b817f6fef   Sam Ravnborg   kbuild: check lic...
1851
1852
1853
  		exp = find_symbol(s->name);
  		if (!exp || exp->module == mod)
  			continue;
6449bd621   Andrew Morton   kbuild: modpost b...
1854
  		basename = strrchr(mod->name, '/');
b817f6fef   Sam Ravnborg   kbuild: check lic...
1855
1856
  		if (basename)
  			basename++;
c96fca213   Sam Ravnborg   kbuild: warn when...
1857
1858
1859
1860
1861
  		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 ...
1862
  	}
b817f6fef   Sam Ravnborg   kbuild: check lic...
1863
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
1864
1865
1866
1867
  /**
   * Header for the generated file
   **/
  static void add_header(struct buffer *b, struct module *mod)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
  {
  	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...
1881
1882
  	buf_printf(b, "__visible struct module __this_module
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1883
1884
  	buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {
  ");
3c7ec94d2   Greg Kroah-Hartman   modpost: use prop...
1885
1886
  	buf_printf(b, "\t.name = KBUILD_MODNAME,
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1887
  	if (mod->has_init)
3c7ec94d2   Greg Kroah-Hartman   modpost: use prop...
1888
1889
  		buf_printf(b, "\t.init = init_module,
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1890
1891
1892
  	if (mod->has_cleanup)
  		buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD
  "
3c7ec94d2   Greg Kroah-Hartman   modpost: use prop...
1893
1894
  			      "\t.exit = cleanup_module,
  "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1895
1896
  			      "#endif
  ");
3c7ec94d2   Greg Kroah-Hartman   modpost: use prop...
1897
1898
  	buf_printf(b, "\t.arch = MODULE_ARCH_INIT,
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1899
1900
1901
  	buf_printf(b, "};
  ");
  }
2449b8ba0   Ben Hutchings   module,bug: Add T...
1902
1903
1904
1905
1906
1907
1908
  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...
1909
  static void add_staging_flag(struct buffer *b, const char *name)
a9860bf05   Greg Kroah-Hartman   Staging: add TAIN...
1910
1911
1912
1913
1914
1915
1916
1917
  {
  	static const char *staging_dir = "drivers/staging";
  
  	if (strncmp(staging_dir, name, strlen(staging_dir)) == 0)
  		buf_printf(b, "
  MODULE_INFO(staging, \"Y\");
  ");
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
1918
1919
1920
  /**
   * Record CRCs for unresolved symbols
   **/
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
1921
  static int add_versions(struct buffer *b, struct module *mod)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1922
1923
  {
  	struct symbol *s, *exp;
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
1924
  	int err = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1925
1926
1927
1928
  
  	for (s = mod->unres; s; s = s->next) {
  		exp = find_symbol(s->name);
  		if (!exp || exp->module == mod) {
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
1929
  			if (have_vmlinux && !s->weak) {
2a1166594   Matthew Wilcox   kbuild: distingui...
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
  				if (warn_unresolved) {
  					warn("\"%s\" [%s.ko] undefined!
  ",
  					     s->name, mod->name);
  				} else {
  					merror("\"%s\" [%s.ko] undefined!
  ",
  					          s->name, mod->name);
  					err = 1;
  				}
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
1940
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1941
1942
1943
1944
1945
1946
1947
1948
  			continue;
  		}
  		s->module = exp->module;
  		s->crc_valid = exp->crc_valid;
  		s->crc = exp->crc;
  	}
  
  	if (!modversions)
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
1949
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1950
1951
1952
1953
1954
  
  	buf_printf(b, "
  ");
  	buf_printf(b, "static const struct modversion_info ____versions[]
  ");
3ff6eecca   Adrian Bunk   remove __attribut...
1955
1956
  	buf_printf(b, "__used
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1957
1958
1959
1960
  	buf_printf(b, "__attribute__((section(\"__versions\"))) = {
  ");
  
  	for (s = mod->unres; s; s = s->next) {
df578e7d8   Sam Ravnborg   kbuild: clean up ...
1961
  		if (!s->module)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1962
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1963
  		if (!s->crc_valid) {
cb80514d9   Sam Ravnborg   kbuild: use warn(...
1964
1965
  			warn("\"%s\" [%s.ko] has no CRC!
  ",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1966
1967
1968
  				s->name, mod->name);
  			continue;
  		}
a53a11f35   James Hogan   modpost: fix unwa...
1969
1970
  		buf_printf(b, "\t{ %#8x, __VMLINUX_SYMBOL_STR(%s) },
  ",
a4b6a77b7   James Hogan   module: fix symbo...
1971
  			   s->crc, s->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1972
1973
1974
1975
  	}
  
  	buf_printf(b, "};
  ");
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
1976
1977
  
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1978
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
1979
1980
  static void add_depends(struct buffer *b, struct module *mod,
  			struct module *modules)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1981
1982
1983
1984
  {
  	struct symbol *s;
  	struct module *m;
  	int first = 1;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
1985
  	for (m = modules; m; m = m->next)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1986
  		m->seen = is_vmlinux(m->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1987
1988
1989
1990
1991
  
  	buf_printf(b, "
  ");
  	buf_printf(b, "static const char __module_depends[]
  ");
3ff6eecca   Adrian Bunk   remove __attribut...
1992
1993
  	buf_printf(b, "__used
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1994
1995
1996
1997
  	buf_printf(b, "__attribute__((section(\".modinfo\"))) =
  ");
  	buf_printf(b, "\"depends=");
  	for (s = mod->unres; s; s = s->next) {
a61b2dfd1   Sam Ravnborg   kbuild: fix segme...
1998
  		const char *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1999
2000
2001
2002
2003
2004
2005
  		if (!s->module)
  			continue;
  
  		if (s->module->seen)
  			continue;
  
  		s->module->seen = 1;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2006
2007
  		p = strrchr(s->module->name, '/');
  		if (p)
a61b2dfd1   Sam Ravnborg   kbuild: fix segme...
2008
2009
2010
2011
  			p++;
  		else
  			p = s->module->name;
  		buf_printf(b, "%s%s", first ? "" : ",", p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2012
2013
2014
2015
2016
  		first = 0;
  	}
  	buf_printf(b, "\";
  ");
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
2017
  static void add_srcversion(struct buffer *b, struct module *mod)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2018
2019
2020
2021
2022
2023
2024
2025
2026
  {
  	if (mod->srcversion[0]) {
  		buf_printf(b, "
  ");
  		buf_printf(b, "MODULE_INFO(srcversion, \"%s\");
  ",
  			   mod->srcversion);
  	}
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
2027
  static void write_if_changed(struct buffer *b, const char *fname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
  {
  	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...
2070
  /* parse Module.symvers file. line format:
534b89a9f   Sam Ravnborg   kbuild: fix segv ...
2071
   * 0x12345678<tab>symbol<tab>module[[<tab>export]<tab>something]
bd5cbcedf   Ram Pai   kbuild: export-ty...
2072
   **/
040fcc819   Sam Ravnborg   kbuild: improved ...
2073
  static void read_dump(const char *fname, unsigned int kernel)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2074
2075
2076
2077
  {
  	unsigned long size, pos = 0;
  	void *file = grab_file(fname, &size);
  	char *line;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2078
  	if (!file)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2079
2080
2081
2082
  		/* No symbol versions, silently ignore */
  		return;
  
  	while ((line = get_next_line(&pos, file, size))) {
534b89a9f   Sam Ravnborg   kbuild: fix segv ...
2083
  		char *symname, *modname, *d, *export, *end;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2084
2085
  		unsigned int crc;
  		struct module *mod;
040fcc819   Sam Ravnborg   kbuild: improved ...
2086
  		struct symbol *s;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2087
2088
2089
2090
2091
2092
2093
  
  		if (!(symname = strchr(line, '\t')))
  			goto fail;
  		*symname++ = '\0';
  		if (!(modname = strchr(symname, '\t')))
  			goto fail;
  		*modname++ = '\0';
9ac545b0f   Laurent Riffard   kbuild: fix modul...
2094
  		if ((export = strchr(modname, '\t')) != NULL)
bd5cbcedf   Ram Pai   kbuild: export-ty...
2095
  			*export++ = '\0';
534b89a9f   Sam Ravnborg   kbuild: fix segv ...
2096
2097
  		if (export && ((end = strchr(export, '\t')) != NULL))
  			*end = '\0';
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2098
2099
2100
  		crc = strtoul(line, &d, 16);
  		if (*symname == '\0' || *modname == '\0' || *d != '\0')
  			goto fail;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2101
2102
2103
  		mod = find_module(modname);
  		if (!mod) {
  			if (is_vmlinux(modname))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2104
  				have_vmlinux = 1;
0fa3a88cf   Jan Beulich   kbuild: remove po...
2105
  			mod = new_module(modname);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2106
2107
  			mod->skip = 1;
  		}
bd5cbcedf   Ram Pai   kbuild: export-ty...
2108
  		s = sym_add_exported(symname, mod, export_no(export));
8e70c4588   Sam Ravnborg   kbuild: warn abou...
2109
2110
  		s->kernel    = kernel;
  		s->preloaded = 1;
bd5cbcedf   Ram Pai   kbuild: export-ty...
2111
  		sym_update_crc(symname, mod, crc, export_no(export));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2112
2113
2114
2115
2116
2117
  	}
  	return;
  fail:
  	fatal("parse error in symbol dump file
  ");
  }
040fcc819   Sam Ravnborg   kbuild: improved ...
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
  /* 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...
2130

5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
2131
  static void write_dump(const char *fname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2132
2133
2134
2135
2136
2137
2138
2139
  {
  	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 ...
2140
  			if (dump_sym(symbol))
bd5cbcedf   Ram Pai   kbuild: export-ty...
2141
2142
  				buf_printf(&buf, "0x%08x\t%s\t%s\t%s
  ",
62070fa42   Sam Ravnborg   kbuild: kill trai...
2143
  					symbol->crc, symbol->name,
bd5cbcedf   Ram Pai   kbuild: export-ty...
2144
2145
  					symbol->module->name,
  					export_str(symbol->export));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2146
2147
2148
2149
2150
  			symbol = symbol->next;
  		}
  	}
  	write_if_changed(&buf, fname);
  }
2d04b5ae1   Richard Hacker   kbuild: support l...
2151
2152
2153
2154
  struct ext_sym_list {
  	struct ext_sym_list *next;
  	const char *file;
  };
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
2155
  int main(int argc, char **argv)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2156
2157
2158
  {
  	struct module *mod;
  	struct buffer buf = { };
040fcc819   Sam Ravnborg   kbuild: improved ...
2159
  	char *kernel_read = NULL, *module_read = NULL;
712f9b468   Rusty Russell   modpost: add -T o...
2160
  	char *dump_write = NULL, *files_source = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2161
  	int opt;
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
2162
  	int err;
2d04b5ae1   Richard Hacker   kbuild: support l...
2163
2164
  	struct ext_sym_list *extsym_iter;
  	struct ext_sym_list *extsym_start = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2165

eed380f3f   Guenter Roeck   modpost: Optional...
2166
  	while ((opt = getopt(argc, argv, "i:I:e:mnsST:o:awM:K:")) != -1) {
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2167
2168
2169
2170
2171
2172
2173
2174
  		switch (opt) {
  		case 'i':
  			kernel_read = optarg;
  			break;
  		case 'I':
  			module_read = optarg;
  			external_module = 1;
  			break;
2d04b5ae1   Richard Hacker   kbuild: support l...
2175
2176
2177
2178
2179
2180
2181
2182
  		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 ...
2183
2184
2185
  		case 'm':
  			modversions = 1;
  			break;
eed380f3f   Guenter Roeck   modpost: Optional...
2186
2187
2188
  		case 'n':
  			ignore_missing_files = 1;
  			break;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2189
2190
2191
2192
2193
2194
2195
2196
2197
  		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...
2198
2199
2200
  		case 'S':
  			sec_mismatch_verbose = 0;
  			break;
712f9b468   Rusty Russell   modpost: add -T o...
2201
2202
2203
  		case 'T':
  			files_source = optarg;
  			break;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2204
2205
2206
2207
2208
  		case 'w':
  			warn_unresolved = 1;
  			break;
  		default:
  			exit(1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2209
2210
  		}
  	}
040fcc819   Sam Ravnborg   kbuild: improved ...
2211
2212
2213
2214
  	if (kernel_read)
  		read_dump(kernel_read, 1);
  	if (module_read)
  		read_dump(module_read, 0);
2d04b5ae1   Richard Hacker   kbuild: support l...
2215
2216
2217
2218
2219
2220
  	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
2221

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

712f9b468   Rusty Russell   modpost: add -T o...
2225
2226
  	if (files_source)
  		read_symbols_from_files(files_source);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2227
2228
2229
  	for (mod = modules; mod; mod = mod->next) {
  		if (mod->skip)
  			continue;
c96fca213   Sam Ravnborg   kbuild: warn when...
2230
  		check_exports(mod);
b817f6fef   Sam Ravnborg   kbuild: check lic...
2231
  	}
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
2232
  	err = 0;
b817f6fef   Sam Ravnborg   kbuild: check lic...
2233
  	for (mod = modules; mod; mod = mod->next) {
666ab414f   Andi Kleen   kbuild: fix a buf...
2234
  		char fname[strlen(mod->name) + 10];
b817f6fef   Sam Ravnborg   kbuild: check lic...
2235
2236
  		if (mod->skip)
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2237
2238
2239
2240
  
  		buf.pos = 0;
  
  		add_header(&buf, mod);
2449b8ba0   Ben Hutchings   module,bug: Add T...
2241
  		add_intree_flag(&buf, !external_module);
a9860bf05   Greg Kroah-Hartman   Staging: add TAIN...
2242
  		add_staging_flag(&buf, mod->name);
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
2243
  		err |= add_versions(&buf, mod);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
  		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);
  	}
  
  	if (dump_write)
  		write_dump(dump_write);
588ccd732   Sam Ravnborg   kbuild: add verbo...
2254
  	if (sec_mismatch_count && !sec_mismatch_verbose)
7c0ac495e   Geert Uytterhoeven   kbuild/modpost: U...
2255
2256
2257
2258
2259
2260
2261
  		warn("modpost: Found %d section mismatch(es).
  "
  		     "To see full details build your kernel with:
  "
  		     "'make CONFIG_DEBUG_SECTION_MISMATCH=y'
  ",
  		     sec_mismatch_count);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2262

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