Blame view

scripts/mod/modpost.c 56.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>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
  #include "modpost.h"
5a865c060   Linus Torvalds   Merge branch 'for...
18
  #include "../../include/generated/autoconf.h"
b817f6fef   Sam Ravnborg   kbuild: check lic...
19
  #include "../../include/linux/license.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20

9e1b9b807   Alan Jenkins   module: make MODU...
21
22
23
24
25
26
  /* Some toolchains use a `_' prefix for all user symbols. */
  #ifdef CONFIG_SYMBOL_PREFIX
  #define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX
  #else
  #define MODULE_SYMBOL_PREFIX ""
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
29
30
31
32
  /* 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 ...
33
34
  /* If we are modposting external module set to 1 */
  static int external_module = 0;
8d8d8289d   Sam Ravnborg   kbuild: do not do...
35
36
  /* Warn about section mismatch in vmlinux if set to 1 */
  static int vmlinux_section_warnings = 1;
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
37
38
  /* Only warn about unresolved symbols */
  static int warn_unresolved = 0;
bd5cbcedf   Ram Pai   kbuild: export-ty...
39
  /* How a symbol is exported */
588ccd732   Sam Ravnborg   kbuild: add verbo...
40
41
  static int sec_mismatch_count = 0;
  static int sec_mismatch_verbose = 1;
c96fca213   Sam Ravnborg   kbuild: warn when...
42
43
44
45
  enum export {
  	export_plain,      export_unused,     export_gpl,
  	export_unused_gpl, export_gpl_future, export_unknown
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
98
99
100
101
  	return ptr;
  }
  
  /* A list of all modules we processed */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102
  static struct module *modules;
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
103
  static struct module *find_module(char *modname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
104
105
106
107
108
109
110
111
  {
  	struct module *mod;
  
  	for (mod = modules; mod; mod = mod->next)
  		if (strcmp(mod->name, modname) == 0)
  			break;
  	return mod;
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
112
  static struct module *new_module(char *modname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
114
115
  {
  	struct module *mod;
  	char *p, *s;
62070fa42   Sam Ravnborg   kbuild: kill trai...
116

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

534b89a9f   Sam Ravnborg   kbuild: fix segv ...
232
233
  	if (!s)
  		return export_unknown;
bd5cbcedf   Ram Pai   kbuild: export-ty...
234
235
236
237
238
239
  	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...
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
  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 ...
261
  static enum export export_from_sec(struct elf_info *elf, unsigned int sec)
bd5cbcedf   Ram Pai   kbuild: export-ty...
262
263
264
  {
  	if (sec == elf->export_sec)
  		return export_plain;
c96fca213   Sam Ravnborg   kbuild: warn when...
265
266
  	else if (sec == elf->export_unused_sec)
  		return export_unused;
bd5cbcedf   Ram Pai   kbuild: export-ty...
267
268
  	else if (sec == elf->export_gpl_sec)
  		return export_gpl;
c96fca213   Sam Ravnborg   kbuild: warn when...
269
270
  	else if (sec == elf->export_unused_gpl_sec)
  		return export_unused_gpl;
bd5cbcedf   Ram Pai   kbuild: export-ty...
271
272
273
274
275
  	else if (sec == elf->export_gpl_future_sec)
  		return export_gpl_future;
  	else
  		return export_unknown;
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
276
277
278
279
  /**
   * 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...
280
281
  static struct symbol *sym_add_exported(const char *name, struct module *mod,
  				       enum export export)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282
283
284
285
  {
  	struct symbol *s = find_symbol(name);
  
  	if (!s) {
bd5cbcedf   Ram Pai   kbuild: export-ty...
286
  		s = new_symbol(name, mod, export);
8e70c4588   Sam Ravnborg   kbuild: warn abou...
287
288
  	} else {
  		if (!s->preloaded) {
7b75b13cd   Sam Ravnborg   kbuild: when warn...
289
  			warn("%s: '%s' exported twice. Previous export "
8e70c4588   Sam Ravnborg   kbuild: warn abou...
290
291
292
293
  			     "was in %s%s
  ", mod->name, name,
  			     s->module->name,
  			     is_vmlinux(s->module->name) ?"":".ko");
4b21960f9   Trent Piepho   kbuild: modpost p...
294
295
296
  		} else {
  			/* In case Modules.symvers was out of date */
  			s->module = mod;
8e70c4588   Sam Ravnborg   kbuild: warn abou...
297
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
298
  	}
8e70c4588   Sam Ravnborg   kbuild: warn abou...
299
  	s->preloaded = 0;
040fcc819   Sam Ravnborg   kbuild: improved ...
300
301
  	s->vmlinux   = is_vmlinux(mod->name);
  	s->kernel    = 0;
bd5cbcedf   Ram Pai   kbuild: export-ty...
302
  	s->export    = export;
040fcc819   Sam Ravnborg   kbuild: improved ...
303
304
305
306
  	return s;
  }
  
  static void sym_update_crc(const char *name, struct module *mod,
bd5cbcedf   Ram Pai   kbuild: export-ty...
307
  			   unsigned int crc, enum export export)
040fcc819   Sam Ravnborg   kbuild: improved ...
308
309
310
311
  {
  	struct symbol *s = find_symbol(name);
  
  	if (!s)
bd5cbcedf   Ram Pai   kbuild: export-ty...
312
  		s = new_symbol(name, mod, export);
040fcc819   Sam Ravnborg   kbuild: improved ...
313
314
  	s->crc = crc;
  	s->crc_valid = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
315
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
316
  void *grab_file(const char *filename, unsigned long *size)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
  {
  	struct stat st;
  	void *map;
  	int fd;
  
  	fd = open(filename, O_RDONLY);
  	if (fd < 0 || fstat(fd, &st) != 0)
  		return NULL;
  
  	*size = st.st_size;
  	map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
  	close(fd);
  
  	if (map == MAP_FAILED)
  		return NULL;
  	return map;
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
334
335
336
337
338
  /**
    * 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 ...
339
  char *get_next_line(unsigned long *pos, void *file, unsigned long size)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
340
341
342
343
344
345
  {
  	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 ...
346
  	for (; *pos < size ; (*pos)++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
  		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...
367
  void release_file(void *file, unsigned long size)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
368
369
370
  {
  	munmap(file, size);
  }
85bd2fddd   Sam Ravnborg   kbuild: fix secti...
371
  static int parse_elf(struct elf_info *info, const char *filename)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
372
373
  {
  	unsigned int i;
85bd2fddd   Sam Ravnborg   kbuild: fix secti...
374
  	Elf_Ehdr *hdr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
375
376
  	Elf_Shdr *sechdrs;
  	Elf_Sym  *sym;
1ce53adf1   Denys Vlasenko   modpost: support ...
377
378
  	const char *secstrings;
  	unsigned int symtab_idx = ~0U, symtab_shndx_idx = ~0U;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
379
380
381
382
  
  	hdr = grab_file(filename, &info->size);
  	if (!hdr) {
  		perror(filename);
6803dc0ea   Sam Ravnborg   kbuild: replace a...
383
  		exit(1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
384
385
  	}
  	info->hdr = hdr;
85bd2fddd   Sam Ravnborg   kbuild: fix secti...
386
387
388
389
390
391
392
393
394
395
396
397
  	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
398
  	/* Fix endianness in ELF header */
7d875a028   Anders Kaseorg   kbuild, modpost: ...
399
400
401
402
403
404
405
406
407
408
409
410
411
  	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
412
413
  	sechdrs = (void *)hdr + hdr->e_shoff;
  	info->sechdrs = sechdrs;
a83710e58   Petr Stetiar   kbuild: fix segfa...
414
415
  	/* Check if file offset is correct */
  	if (hdr->e_shoff > info->size) {
df578e7d8   Sam Ravnborg   kbuild: clean up ...
416
417
418
419
  		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...
420
421
  		return 0;
  	}
6845756b2   Anders Kaseorg   modpost: Update 6...
422
  	if (hdr->e_shnum == SHN_UNDEF) {
1ce53adf1   Denys Vlasenko   modpost: support ...
423
424
425
  		/*
  		 * There are more than 64k sections,
  		 * read count from .sh_size.
1ce53adf1   Denys Vlasenko   modpost: support ...
426
427
428
429
430
431
432
  		 */
  		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...
433
  		info->secindex_strings = TO_NATIVE(sechdrs[0].sh_link);
1ce53adf1   Denys Vlasenko   modpost: support ...
434
435
436
437
  	}
  	else {
  		info->secindex_strings = hdr->e_shstrndx;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
438
  	/* Fix endianness in section headers */
1ce53adf1   Denys Vlasenko   modpost: support ...
439
  	for (i = 0; i < info->num_sections; i++) {
7d875a028   Anders Kaseorg   kbuild, modpost: ...
440
441
442
443
444
445
446
447
448
449
  		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
450
451
  	}
  	/* Find symbol table. */
1ce53adf1   Denys Vlasenko   modpost: support ...
452
453
  	secstrings = (void *)hdr + sechdrs[info->secindex_strings].sh_offset;
  	for (i = 1; i < info->num_sections; i++) {
bd5cbcedf   Ram Pai   kbuild: export-ty...
454
  		const char *secname;
56fc82c53   Tejun Heo   modpost: NOBITS s...
455
  		int nobits = sechdrs[i].sh_type == SHT_NOBITS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
456

56fc82c53   Tejun Heo   modpost: NOBITS s...
457
  		if (!nobits && sechdrs[i].sh_offset > info->size) {
df578e7d8   Sam Ravnborg   kbuild: clean up ...
458
459
460
461
462
  			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...
463
464
  			return 0;
  		}
bd5cbcedf   Ram Pai   kbuild: export-ty...
465
466
  		secname = secstrings + sechdrs[i].sh_name;
  		if (strcmp(secname, ".modinfo") == 0) {
56fc82c53   Tejun Heo   modpost: NOBITS s...
467
468
469
  			if (nobits)
  				fatal("%s has NOBITS .modinfo
  ", filename);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
470
471
  			info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
  			info->modinfo_len = sechdrs[i].sh_size;
bd5cbcedf   Ram Pai   kbuild: export-ty...
472
473
  		} else if (strcmp(secname, "__ksymtab") == 0)
  			info->export_sec = i;
c96fca213   Sam Ravnborg   kbuild: warn when...
474
475
  		else if (strcmp(secname, "__ksymtab_unused") == 0)
  			info->export_unused_sec = i;
bd5cbcedf   Ram Pai   kbuild: export-ty...
476
477
  		else if (strcmp(secname, "__ksymtab_gpl") == 0)
  			info->export_gpl_sec = i;
c96fca213   Sam Ravnborg   kbuild: warn when...
478
479
  		else if (strcmp(secname, "__ksymtab_unused_gpl") == 0)
  			info->export_unused_gpl_sec = i;
bd5cbcedf   Ram Pai   kbuild: export-ty...
480
481
  		else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
  			info->export_gpl_future_sec = i;
1ce53adf1   Denys Vlasenko   modpost: support ...
482
483
484
485
486
487
488
  		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...
489
  			sh_link_idx = sechdrs[i].sh_link;
1ce53adf1   Denys Vlasenko   modpost: support ...
490
491
492
  			info->strtab       = (void *)hdr +
  			    sechdrs[sh_link_idx].sh_offset;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
493

1ce53adf1   Denys Vlasenko   modpost: support ...
494
495
496
497
498
499
500
501
  		/* 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
502
  	}
df578e7d8   Sam Ravnborg   kbuild: clean up ...
503
  	if (!info->symtab_start)
cb80514d9   Sam Ravnborg   kbuild: use warn(...
504
505
  		fatal("%s has no symtab?
  ", filename);
df578e7d8   Sam Ravnborg   kbuild: clean up ...
506

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
507
508
509
510
511
512
513
  	/* 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 ...
514
515
516
  
  	if (symtab_shndx_idx != ~0U) {
  		Elf32_Word *p;
6845756b2   Anders Kaseorg   modpost: Update 6...
517
  		if (symtab_idx != sechdrs[symtab_shndx_idx].sh_link)
1ce53adf1   Denys Vlasenko   modpost: support ...
518
519
  			fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u
  ",
6845756b2   Anders Kaseorg   modpost: Update 6...
520
  			      filename, sechdrs[symtab_shndx_idx].sh_link,
1ce53adf1   Denys Vlasenko   modpost: support ...
521
522
523
524
525
526
  			      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...
527
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
528
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
529
  static void parse_elf_finish(struct elf_info *info)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
530
531
532
  {
  	release_file(info->hdr, info->size);
  }
4d7365d66   Sam Ravnborg   kbuild: ignore po...
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
  static int ignore_undef_symbol(struct elf_info *info, const char *symname)
  {
  	/* ignore __this_module, it will be resolved shortly */
  	if (strcmp(symname, MODULE_SYMBOL_PREFIX "__this_module") == 0)
  		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 ||
  		    strncmp(symname, "_save32gpr_", sizeof("_save32gpr_") - 1) == 0)
  			return 1;
7fca5dc8a   Stephen Rothwell   powerpc: Fix modu...
548
549
550
551
552
  	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 ||
  		    strncmp(symname, "_savegpr0_", sizeof("_savegpr0_") - 1) == 0)
  			return 1;
4d7365d66   Sam Ravnborg   kbuild: ignore po...
553
554
555
  	/* Do not ignore this symbol */
  	return 0;
  }
f7b05e64b   Luke Yang   kbuild: Fix bug i...
556
557
  #define CRC_PFX     MODULE_SYMBOL_PREFIX "__crc_"
  #define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
558

5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
559
560
  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
561
562
  {
  	unsigned int crc;
62a263561   Alessio Igor Bogani   modpost: Fix modp...
563
564
565
566
567
568
  	enum export export;
  
  	if (!is_vmlinux(mod->name) && strncmp(symname, "__ksymtab", 9) == 0)
  		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
569
570
571
  
  	switch (sym->st_shndx) {
  	case SHN_COMMON:
cb80514d9   Sam Ravnborg   kbuild: use warn(...
572
573
  		warn("\"%s\" [%s] is COMMON symbol
  ", symname, mod->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
574
575
576
  		break;
  	case SHN_ABS:
  		/* CRC'd symbol */
8d99513c1   Michal Marek   modpost: fix segf...
577
  		if (strncmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
578
  			crc = (unsigned int) sym->st_value;
bd5cbcedf   Ram Pai   kbuild: export-ty...
579
580
  			sym_update_crc(symname + strlen(CRC_PFX), mod, crc,
  					export);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
581
582
583
584
585
586
587
  		}
  		break;
  	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...
588
  		if (ignore_undef_symbol(info, symname))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
589
  			break;
8d5290149   Ben Colline   [SPARC]: Deal wit...
590
591
592
593
594
595
  /* 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
596
597
598
  		if (info->hdr->e_machine == EM_SPARC ||
  		    info->hdr->e_machine == EM_SPARCV9) {
  			/* Ignore register directives. */
8d5290149   Ben Colline   [SPARC]: Deal wit...
599
  			if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
600
  				break;
62070fa42   Sam Ravnborg   kbuild: kill trai...
601
602
603
604
605
606
  			if (symname[0] == '.') {
  				char *munged = strdup(symname);
  				munged[0] = '_';
  				munged[1] = toupper(munged[1]);
  				symname = munged;
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
607
608
  		}
  #endif
62070fa42   Sam Ravnborg   kbuild: kill trai...
609

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
610
  		if (memcmp(symname, MODULE_SYMBOL_PREFIX,
df578e7d8   Sam Ravnborg   kbuild: clean up ...
611
612
613
614
615
616
617
  			   strlen(MODULE_SYMBOL_PREFIX)) == 0) {
  			mod->unres =
  			  alloc_symbol(symname +
  			               strlen(MODULE_SYMBOL_PREFIX),
  			               ELF_ST_BIND(sym->st_info) == STB_WEAK,
  			               mod->unres);
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
618
619
620
  		break;
  	default:
  		/* All exported symbols */
8d99513c1   Michal Marek   modpost: fix segf...
621
  		if (strncmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
bd5cbcedf   Ram Pai   kbuild: export-ty...
622
623
  			sym_add_exported(symname + strlen(KSYMTAB_PFX), mod,
  					export);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
624
625
626
627
628
629
630
631
  		}
  		if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0)
  			mod->has_init = 1;
  		if (strcmp(symname, MODULE_SYMBOL_PREFIX "cleanup_module") == 0)
  			mod->has_cleanup = 1;
  		break;
  	}
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
632
633
634
  /**
   * Parse tag=value strings from .modinfo section
   **/
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
  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...
652
653
  static char *get_next_modinfo(void *modinfo, unsigned long modinfo_len,
  			      const char *tag, char *info)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
654
655
656
657
  {
  	char *p;
  	unsigned int taglen = strlen(tag);
  	unsigned long size = modinfo_len;
b817f6fef   Sam Ravnborg   kbuild: check lic...
658
659
660
661
  	if (info) {
  		size -= info - (char *)modinfo;
  		modinfo = next_string(info, &size);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
662
663
664
665
666
667
  	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...
668
669
670
671
672
673
  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...
674
  /**
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
675
676
677
678
679
   * 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 ...
680
  	int slen, sublen;
62070fa42   Sam Ravnborg   kbuild: kill trai...
681

4c8fbca58   Sam Ravnborg   kbuild: whitelist...
682
683
  	if (!s || !sub)
  		return 1;
62070fa42   Sam Ravnborg   kbuild: kill trai...
684

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

4c8fbca58   Sam Ravnborg   kbuild: whitelist...
688
689
  	if ((slen == 0) || (sublen == 0))
  		return 1;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
690
691
  	if (sublen > slen)
  		return 1;
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
692

df578e7d8   Sam Ravnborg   kbuild: clean up ...
693
  	return memcmp(s + slen - sublen, sub, sublen);
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
694
  }
ff13f9269   Sam Ravnborg   kbuild: introduce...
695
696
  static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
  {
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
697
698
699
  	if (sym)
  		return elf->strtab + sym->st_name;
  	else
f666751a0   Sam Ravnborg   kbuild/modpost: i...
700
  		return "(unknown)";
ff13f9269   Sam Ravnborg   kbuild: introduce...
701
  }
1ce53adf1   Denys Vlasenko   modpost: support ...
702
  static const char *sec_name(struct elf_info *elf, int secindex)
ff13f9269   Sam Ravnborg   kbuild: introduce...
703
704
705
  {
  	Elf_Shdr *sechdrs = elf->sechdrs;
  	return (void *)elf->hdr +
1ce53adf1   Denys Vlasenko   modpost: support ...
706
707
  		elf->sechdrs[elf->secindex_strings].sh_offset +
  		sechdrs[secindex].sh_name;
ff13f9269   Sam Ravnborg   kbuild: introduce...
708
709
710
711
712
  }
  
  static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr)
  {
  	return (void *)elf->hdr +
1ce53adf1   Denys Vlasenko   modpost: support ...
713
714
  		elf->sechdrs[elf->secindex_strings].sh_offset +
  		sechdr->sh_name;
ff13f9269   Sam Ravnborg   kbuild: introduce...
715
  }
10668220a   Sam Ravnborg   kbuild: introduce...
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
  /* 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...
736
   * "*foo" will match a string that ends with "foo"
10668220a   Sam Ravnborg   kbuild: introduce...
737
738
739
740
741
742
   * "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...
743
  static int match(const char *sym, const char * const pat[])
10668220a   Sam Ravnborg   kbuild: introduce...
744
745
746
747
748
  {
  	const char *p;
  	while (*pat) {
  		p = *pat++;
  		const char *endp = p + strlen(p) - 1;
6c5bd235b   Sam Ravnborg   kbuild: check sec...
749
750
751
752
753
  		/* "*foo" */
  		if (*p == '*') {
  			if (strrcmp(sym, p + 1) == 0)
  				return 1;
  		}
10668220a   Sam Ravnborg   kbuild: introduce...
754
  		/* "foo*" */
6c5bd235b   Sam Ravnborg   kbuild: check sec...
755
  		else if (*endp == '*') {
10668220a   Sam Ravnborg   kbuild: introduce...
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
  			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...
775
776
  /* sections that we do not want to do full section mismatch check on */
  static const char *section_white_list[] =
4391ed6aa   Sam Ravnborg   kbuild, modpost: ...
777
778
779
  {
  	".comment*",
  	".debug*",
1121584f5   H.J. Lu   modpost: Put .zde...
780
  	".zdebug*",		/* Compressed debug sections. */
019fca84e   David Howells   MN10300: Permit ....
781
  	".GCC-command-line",	/* mn10300 */
4391ed6aa   Sam Ravnborg   kbuild, modpost: ...
782
783
784
785
786
787
788
789
  	".mdebug*",        /* alpha, score, mips etc. */
  	".pdr",            /* alpha, score, mips etc. */
  	".stab*",
  	".note*",
  	".got*",
  	".toc*",
  	NULL
  };
10668220a   Sam Ravnborg   kbuild: introduce...
790

e241a6303   Sam Ravnborg   kbuild: warn abou...
791
  /*
b614a697d   Anders Kaseorg   kbuild, modpost: ...
792
   * This is used to find sections missing the SHF_ALLOC flag.
e241a6303   Sam Ravnborg   kbuild: warn abou...
793
   * The cause of this is often a section specified in assembler
b614a697d   Anders Kaseorg   kbuild, modpost: ...
794
   * without "ax" / "aw".
e241a6303   Sam Ravnborg   kbuild: warn abou...
795
   */
b614a697d   Anders Kaseorg   kbuild, modpost: ...
796
797
  static void check_section(const char *modname, struct elf_info *elf,
                            Elf_Shdr *sechdr)
e241a6303   Sam Ravnborg   kbuild: warn abou...
798
  {
b614a697d   Anders Kaseorg   kbuild, modpost: ...
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
  	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...
814
  	}
e241a6303   Sam Ravnborg   kbuild: warn abou...
815
  }
eb8f68904   Sam Ravnborg   Use separate sect...
816
  #define ALL_INIT_DATA_SECTIONS \
fd6c3a8dc   Jan Beulich   initconst adjustm...
817
818
  	".init.setup$", ".init.rodata$", \
  	".devinit.rodata$", ".cpuinit.rodata$", ".meminit.rodata$" \
eb8f68904   Sam Ravnborg   Use separate sect...
819
820
821
  	".init.data$", ".devinit.data$", ".cpuinit.data$", ".meminit.data$"
  #define ALL_EXIT_DATA_SECTIONS \
  	".exit.data$", ".devexit.data$", ".cpuexit.data$", ".memexit.data$"
10668220a   Sam Ravnborg   kbuild: introduce...
822

eb8f68904   Sam Ravnborg   Use separate sect...
823
824
825
826
  #define ALL_INIT_TEXT_SECTIONS \
  	".init.text$", ".devinit.text$", ".cpuinit.text$", ".meminit.text$"
  #define ALL_EXIT_TEXT_SECTIONS \
  	".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$"
10668220a   Sam Ravnborg   kbuild: introduce...
827

4a31a229f   Uwe Kleine-König   modpost: define A...
828
829
830
831
832
833
834
  #define ALL_XXXINIT_SECTIONS DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, \
  	MEM_INIT_SECTIONS
  #define ALL_XXXEXIT_SECTIONS DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, \
  	MEM_EXIT_SECTIONS
  
  #define ALL_INIT_SECTIONS INIT_SECTIONS, ALL_XXXINIT_SECTIONS
  #define ALL_EXIT_SECTIONS EXIT_SECTIONS, ALL_XXXEXIT_SECTIONS
10668220a   Sam Ravnborg   kbuild: introduce...
835

6c5bd235b   Sam Ravnborg   kbuild: check sec...
836
  #define DATA_SECTIONS ".data$", ".data.rel$"
10668220a   Sam Ravnborg   kbuild: introduce...
837
  #define TEXT_SECTIONS ".text$"
fd6c3a8dc   Jan Beulich   initconst adjustm...
838
839
840
841
  #define INIT_SECTIONS      ".init.*"
  #define DEV_INIT_SECTIONS  ".devinit.*"
  #define CPU_INIT_SECTIONS  ".cpuinit.*"
  #define MEM_INIT_SECTIONS  ".meminit.*"
eb8f68904   Sam Ravnborg   Use separate sect...
842

fd6c3a8dc   Jan Beulich   initconst adjustm...
843
844
845
846
  #define EXIT_SECTIONS      ".exit.*"
  #define DEV_EXIT_SECTIONS  ".devexit.*"
  #define CPU_EXIT_SECTIONS  ".cpuexit.*"
  #define MEM_EXIT_SECTIONS  ".memexit.*"
eb8f68904   Sam Ravnborg   Use separate sect...
847

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

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

9bf8cb9b7   Sam Ravnborg   kbuild: fix warni...
1074
  	/* Check for pattern 3 */
6c5bd235b   Sam Ravnborg   kbuild: check sec...
1075
1076
  	if (match(fromsec, head_sections) &&
  	    match(tosec, init_sections))
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1077
  		return 0;
9bf8cb9b7   Sam Ravnborg   kbuild: fix warni...
1078

1d8af559f   Sam Ravnborg   kbuild: consolida...
1079
  	/* Check for pattern 4 */
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1080
1081
  	if (match(tosym, linker_symbols))
  		return 0;
9bf8cb9b7   Sam Ravnborg   kbuild: fix warni...
1082

58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1083
  	return 1;
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1084
1085
1086
  }
  
  /**
93684d3b8   Sam Ravnborg   kbuild: include s...
1087
1088
1089
1090
1091
1092
   * 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...
1093
  static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,
93684d3b8   Sam Ravnborg   kbuild: include s...
1094
1095
1096
  				Elf_Sym *relsym)
  {
  	Elf_Sym *sym;
9ad21c3f3   Sam Ravnborg   kbuild: try harde...
1097
1098
1099
  	Elf_Sym *near = NULL;
  	Elf64_Sword distance = 20;
  	Elf64_Sword d;
1ce53adf1   Denys Vlasenko   modpost: support ...
1100
  	unsigned int relsym_secindex;
93684d3b8   Sam Ravnborg   kbuild: include s...
1101
1102
1103
  
  	if (relsym->st_name != 0)
  		return relsym;
1ce53adf1   Denys Vlasenko   modpost: support ...
1104
1105
  
  	relsym_secindex = get_secindex(elf, relsym);
93684d3b8   Sam Ravnborg   kbuild: include s...
1106
  	for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
1ce53adf1   Denys Vlasenko   modpost: support ...
1107
  		if (get_secindex(elf, sym) != relsym_secindex)
93684d3b8   Sam Ravnborg   kbuild: include s...
1108
  			continue;
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1109
1110
  		if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
  			continue;
93684d3b8   Sam Ravnborg   kbuild: include s...
1111
1112
  		if (sym->st_value == addr)
  			return sym;
9ad21c3f3   Sam Ravnborg   kbuild: try harde...
1113
1114
1115
1116
1117
1118
1119
1120
  		/* 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...
1121
  	}
9ad21c3f3   Sam Ravnborg   kbuild: try harde...
1122
1123
1124
1125
1126
  	/* We need a close match */
  	if (distance < 20)
  		return near;
  	else
  		return NULL;
93684d3b8   Sam Ravnborg   kbuild: include s...
1127
  }
da68d61f8   David Brownell   [PATCH] remove mo...
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
  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...
1151
  /*
43c74d179   Sam Ravnborg   kbuild: in the se...
1152
1153
1154
1155
   * 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...
1156
   **/
157c23c80   Sam Ravnborg   kbuild: use simpl...
1157
1158
  static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
  				 const char *sec)
b39927cf4   Sam Ravnborg   kbuild: check for...
1159
1160
  {
  	Elf_Sym *sym;
157c23c80   Sam Ravnborg   kbuild: use simpl...
1161
  	Elf_Sym *near = NULL;
157c23c80   Sam Ravnborg   kbuild: use simpl...
1162
  	Elf_Addr distance = ~0;
62070fa42   Sam Ravnborg   kbuild: kill trai...
1163

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

e5f95c8b7   Sam Ravnborg   kbuild: print onl...
1271
1272
1273
  	sec_mismatch_count++;
  	if (!sec_mismatch_verbose)
  		return;
7c0ac495e   Geert Uytterhoeven   kbuild/modpost: U...
1274
1275
1276
1277
1278
  	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...
1279

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

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

588ccd732   Sam Ravnborg   kbuild: add verbo...
1440
1441
1442
1443
  		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...
1444
1445
  
  		/* check whitelist - we may ignore it */
af92a82d0   Uwe Kleine-König   modpost: make sym...
1446
1447
  		if (secref_whitelist(mismatch,
  					fromsec, fromsym, tosec, tosym)) {
588ccd732   Sam Ravnborg   kbuild: add verbo...
1448
1449
1450
1451
  			report_sec_mismatch(modname, mismatch,
  			   fromsec, r->r_offset, fromsym,
  			   is_function(from), tosec, tosym,
  			   is_function(to));
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1452
  		}
b39927cf4   Sam Ravnborg   kbuild: check for...
1453
1454
  	}
  }
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1455
  static unsigned int *reloc_location(struct elf_info *elf,
5b24c0715   Sam Ravnborg   kbuild: code refa...
1456
  				    Elf_Shdr *sechdr, Elf_Rela *r)
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1457
1458
  {
  	Elf_Shdr *sechdrs = elf->sechdrs;
6845756b2   Anders Kaseorg   modpost: Update 6...
1459
  	int section = sechdr->sh_info;
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1460
1461
  
  	return (void *)elf->hdr + sechdrs[section].sh_offset +
731ece41f   Olof Johansson   modpost: Fix addr...
1462
  		r->r_offset;
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1463
  }
5b24c0715   Sam Ravnborg   kbuild: code refa...
1464
  static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1465
1466
  {
  	unsigned int r_typ = ELF_R_TYPE(r->r_info);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1467
  	unsigned int *location = reloc_location(elf, sechdr, r);
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
  
  	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;
  }
5b24c0715   Sam Ravnborg   kbuild: code refa...
1482
  static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
56a974fa2   Sam Ravnborg   kbuild: make bett...
1483
1484
1485
1486
1487
1488
  {
  	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 ...
1489
1490
  		r->r_addend = (int)(long)
  		              (elf->symtab_start + ELF_R_SYM(r->r_info));
56a974fa2   Sam Ravnborg   kbuild: make bett...
1491
1492
1493
  		break;
  	case R_ARM_PC24:
  		/* From ARM ABI: ((S + A) | T) - P */
df578e7d8   Sam Ravnborg   kbuild: clean up ...
1494
  		r->r_addend = (int)(long)(elf->hdr +
5b24c0715   Sam Ravnborg   kbuild: code refa...
1495
1496
  		              sechdr->sh_offset +
  		              (r->r_offset - sechdr->sh_addr));
56a974fa2   Sam Ravnborg   kbuild: make bett...
1497
1498
1499
1500
1501
1502
  		break;
  	default:
  		return 1;
  	}
  	return 0;
  }
5b24c0715   Sam Ravnborg   kbuild: code refa...
1503
  static int addend_mips_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1504
1505
  {
  	unsigned int r_typ = ELF_R_TYPE(r->r_info);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1506
  	unsigned int *location = reloc_location(elf, sechdr, r);
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
  	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...
1525
  static void section_rela(const char *modname, struct elf_info *elf,
10668220a   Sam Ravnborg   kbuild: introduce...
1526
                           Elf_Shdr *sechdr)
5b24c0715   Sam Ravnborg   kbuild: code refa...
1527
1528
1529
1530
1531
1532
  {
  	Elf_Sym  *sym;
  	Elf_Rela *rela;
  	Elf_Rela r;
  	unsigned int r_sym;
  	const char *fromsec;
5b24c0715   Sam Ravnborg   kbuild: code refa...
1533

ff13f9269   Sam Ravnborg   kbuild: introduce...
1534
  	Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset;
5b24c0715   Sam Ravnborg   kbuild: code refa...
1535
  	Elf_Rela *stop  = (void *)start + sechdr->sh_size;
ff13f9269   Sam Ravnborg   kbuild: introduce...
1536
  	fromsec = sech_name(elf, sechdr);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1537
1538
  	fromsec += strlen(".rela");
  	/* if from section (name) is know good then skip it */
b614a697d   Anders Kaseorg   kbuild, modpost: ...
1539
  	if (match(fromsec, section_white_list))
5b24c0715   Sam Ravnborg   kbuild: code refa...
1540
  		return;
e241a6303   Sam Ravnborg   kbuild: warn abou...
1541

5b24c0715   Sam Ravnborg   kbuild: code refa...
1542
1543
1544
  	for (rela = start; rela < stop; rela++) {
  		r.r_offset = TO_NATIVE(rela->r_offset);
  #if KERNEL_ELFCLASS == ELFCLASS64
ff13f9269   Sam Ravnborg   kbuild: introduce...
1545
  		if (elf->hdr->e_machine == EM_MIPS) {
5b24c0715   Sam Ravnborg   kbuild: code refa...
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
  			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 ...
1562
  		if (is_shndx_special(sym->st_shndx))
5b24c0715   Sam Ravnborg   kbuild: code refa...
1563
  			continue;
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1564
  		check_section_mismatch(modname, elf, &r, sym, fromsec);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1565
1566
1567
1568
  	}
  }
  
  static void section_rel(const char *modname, struct elf_info *elf,
10668220a   Sam Ravnborg   kbuild: introduce...
1569
                          Elf_Shdr *sechdr)
5b24c0715   Sam Ravnborg   kbuild: code refa...
1570
1571
1572
1573
1574
1575
  {
  	Elf_Sym *sym;
  	Elf_Rel *rel;
  	Elf_Rela r;
  	unsigned int r_sym;
  	const char *fromsec;
5b24c0715   Sam Ravnborg   kbuild: code refa...
1576

ff13f9269   Sam Ravnborg   kbuild: introduce...
1577
  	Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset;
5b24c0715   Sam Ravnborg   kbuild: code refa...
1578
  	Elf_Rel *stop  = (void *)start + sechdr->sh_size;
ff13f9269   Sam Ravnborg   kbuild: introduce...
1579
  	fromsec = sech_name(elf, sechdr);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1580
1581
  	fromsec += strlen(".rel");
  	/* if from section (name) is know good then skip it */
b614a697d   Anders Kaseorg   kbuild, modpost: ...
1582
  	if (match(fromsec, section_white_list))
5b24c0715   Sam Ravnborg   kbuild: code refa...
1583
1584
1585
1586
1587
  		return;
  
  	for (rel = start; rel < stop; rel++) {
  		r.r_offset = TO_NATIVE(rel->r_offset);
  #if KERNEL_ELFCLASS == ELFCLASS64
ff13f9269   Sam Ravnborg   kbuild: introduce...
1588
  		if (elf->hdr->e_machine == EM_MIPS) {
5b24c0715   Sam Ravnborg   kbuild: code refa...
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
  			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...
1603
  		switch (elf->hdr->e_machine) {
5b24c0715   Sam Ravnborg   kbuild: code refa...
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
  		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 ...
1619
  		if (is_shndx_special(sym->st_shndx))
5b24c0715   Sam Ravnborg   kbuild: code refa...
1620
  			continue;
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1621
  		check_section_mismatch(modname, elf, &r, sym, fromsec);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1622
1623
  	}
  }
b39927cf4   Sam Ravnborg   kbuild: check for...
1624
1625
1626
1627
  /**
   * 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...
1628
   * marked __initdata will be discarded when the module has been initialized.
b39927cf4   Sam Ravnborg   kbuild: check for...
1629
1630
   * 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...
1631
   * only when a module is unloaded which never happens for built-in modules.
b39927cf4   Sam Ravnborg   kbuild: check for...
1632
1633
1634
1635
1636
   * 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...
1637
                            struct elf_info *elf)
b39927cf4   Sam Ravnborg   kbuild: check for...
1638
1639
  {
  	int i;
b39927cf4   Sam Ravnborg   kbuild: check for...
1640
  	Elf_Shdr *sechdrs = elf->sechdrs;
62070fa42   Sam Ravnborg   kbuild: kill trai...
1641

b39927cf4   Sam Ravnborg   kbuild: check for...
1642
  	/* Walk through all sections */
1ce53adf1   Denys Vlasenko   modpost: support ...
1643
  	for (i = 0; i < elf->num_sections; i++) {
b614a697d   Anders Kaseorg   kbuild, modpost: ...
1644
  		check_section(modname, elf, &elf->sechdrs[i]);
b39927cf4   Sam Ravnborg   kbuild: check for...
1645
  		/* We want to process only relocation sections and not .init */
5b24c0715   Sam Ravnborg   kbuild: code refa...
1646
  		if (sechdrs[i].sh_type == SHT_RELA)
10668220a   Sam Ravnborg   kbuild: introduce...
1647
  			section_rela(modname, elf, &elf->sechdrs[i]);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1648
  		else if (sechdrs[i].sh_type == SHT_REL)
10668220a   Sam Ravnborg   kbuild: introduce...
1649
  			section_rel(modname, elf, &elf->sechdrs[i]);
b39927cf4   Sam Ravnborg   kbuild: check for...
1650
1651
  	}
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
1652
  static void read_symbols(char *modname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1653
1654
1655
  {
  	const char *symname;
  	char *version;
b817f6fef   Sam Ravnborg   kbuild: check lic...
1656
  	char *license;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1657
1658
1659
  	struct module *mod;
  	struct elf_info info = { };
  	Elf_Sym *sym;
85bd2fddd   Sam Ravnborg   kbuild: fix secti...
1660
1661
  	if (!parse_elf(&info, modname))
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1662
1663
1664
1665
1666
1667
  
  	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
1668
  		have_vmlinux = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1669
1670
  		mod->skip = 1;
  	}
b817f6fef   Sam Ravnborg   kbuild: check lic...
1671
  	license = get_modinfo(info.modinfo, info.modinfo_len, "license");
2fa365682   Sam Ravnborg   kbuild: soften MO...
1672
1673
1674
1675
1676
1677
  	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...
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
  	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
1688
1689
1690
1691
1692
1693
  	for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
  		symname = info.strtab + sym->st_name;
  
  		handle_modversions(mod, &info, sym, symname);
  		handle_moddevtable(mod, &info, sym, symname);
  	}
d1f25e665   Sam Ravnborg   kbuild: fix so mo...
1694
  	if (!is_vmlinux(modname) ||
10668220a   Sam Ravnborg   kbuild: introduce...
1695
1696
  	     (is_vmlinux(modname) && vmlinux_section_warnings))
  		check_sec_ref(mod, modname, &info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
  
  	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...
1707
  	/* Our trick to get versioning for module struct etc. - it's
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1708
1709
1710
1711
  	 * 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...
1712
  		mod->unres = alloc_symbol("module_layout", 0, mod->unres);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1713
1714
1715
1716
1717
1718
1719
  }
  
  #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...
1720
1721
  void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf,
  						      const char *fmt, ...)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1722
1723
1724
1725
  {
  	char tmp[SZ];
  	int len;
  	va_list ap;
62070fa42   Sam Ravnborg   kbuild: kill trai...
1726

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1727
1728
  	va_start(ap, fmt);
  	len = vsnprintf(tmp, SZ, fmt, ap);
7670f023a   Sam Ravnborg   [PATCH] kbuild: f...
1729
  	buf_write(buf, tmp, len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1730
1731
  	va_end(ap);
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
1732
  void buf_write(struct buffer *buf, const char *s, int len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1733
1734
  {
  	if (buf->size - buf->pos < len) {
7670f023a   Sam Ravnborg   [PATCH] kbuild: f...
1735
  		buf->size += len + SZ;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1736
1737
1738
1739
1740
  		buf->p = realloc(buf->p, buf->size);
  	}
  	strncpy(buf->p + buf->pos, s, len);
  	buf->pos += len;
  }
c96fca213   Sam Ravnborg   kbuild: warn when...
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
  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 ...
1768
  static void check_for_unused(enum export exp, const char *m, const char *s)
c96fca213   Sam Ravnborg   kbuild: warn when...
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
  {
  	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...
1786
1787
1788
1789
  {
  	struct symbol *s, *exp;
  
  	for (s = mod->unres; s; s = s->next) {
6449bd621   Andrew Morton   kbuild: modpost b...
1790
  		const char *basename;
b817f6fef   Sam Ravnborg   kbuild: check lic...
1791
1792
1793
  		exp = find_symbol(s->name);
  		if (!exp || exp->module == mod)
  			continue;
6449bd621   Andrew Morton   kbuild: modpost b...
1794
  		basename = strrchr(mod->name, '/');
b817f6fef   Sam Ravnborg   kbuild: check lic...
1795
1796
  		if (basename)
  			basename++;
c96fca213   Sam Ravnborg   kbuild: warn when...
1797
1798
1799
1800
1801
  		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 ...
1802
  	}
b817f6fef   Sam Ravnborg   kbuild: check lic...
1803
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
1804
1805
1806
1807
  /**
   * Header for the generated file
   **/
  static void add_header(struct buffer *b, struct module *mod)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
  {
  	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, "
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1821
1822
1823
1824
  	buf_printf(b, "struct module __this_module
  ");
  	buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {
  ");
f83b5e323   Ustyugov Roman   kbuild: set corre...
1825
1826
  	buf_printf(b, " .name = KBUILD_MODNAME,
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
  	if (mod->has_init)
  		buf_printf(b, " .init = init_module,
  ");
  	if (mod->has_cleanup)
  		buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD
  "
  			      " .exit = cleanup_module,
  "
  			      "#endif
  ");
e61a1c1c4   Roman Zippel   Allow arch to ini...
1837
1838
  	buf_printf(b, " .arch = MODULE_ARCH_INIT,
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1839
1840
1841
  	buf_printf(b, "};
  ");
  }
2449b8ba0   Ben Hutchings   module,bug: Add T...
1842
1843
1844
1845
1846
1847
1848
  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...
1849
  static void add_staging_flag(struct buffer *b, const char *name)
a9860bf05   Greg Kroah-Hartman   Staging: add TAIN...
1850
1851
1852
1853
1854
1855
1856
1857
  {
  	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...
1858
1859
1860
  /**
   * Record CRCs for unresolved symbols
   **/
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
1861
  static int add_versions(struct buffer *b, struct module *mod)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1862
1863
  {
  	struct symbol *s, *exp;
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
1864
  	int err = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1865
1866
1867
1868
  
  	for (s = mod->unres; s; s = s->next) {
  		exp = find_symbol(s->name);
  		if (!exp || exp->module == mod) {
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
1869
  			if (have_vmlinux && !s->weak) {
2a1166594   Matthew Wilcox   kbuild: distingui...
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
  				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...
1880
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1881
1882
1883
1884
1885
1886
1887
1888
  			continue;
  		}
  		s->module = exp->module;
  		s->crc_valid = exp->crc_valid;
  		s->crc = exp->crc;
  	}
  
  	if (!modversions)
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
1889
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1890
1891
1892
1893
1894
  
  	buf_printf(b, "
  ");
  	buf_printf(b, "static const struct modversion_info ____versions[]
  ");
3ff6eecca   Adrian Bunk   remove __attribut...
1895
1896
  	buf_printf(b, "__used
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1897
1898
1899
1900
  	buf_printf(b, "__attribute__((section(\"__versions\"))) = {
  ");
  
  	for (s = mod->unres; s; s = s->next) {
df578e7d8   Sam Ravnborg   kbuild: clean up ...
1901
  		if (!s->module)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1902
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1903
  		if (!s->crc_valid) {
cb80514d9   Sam Ravnborg   kbuild: use warn(...
1904
1905
  			warn("\"%s\" [%s.ko] has no CRC!
  ",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1906
1907
1908
1909
1910
1911
1912
1913
1914
  				s->name, mod->name);
  			continue;
  		}
  		buf_printf(b, "\t{ %#8x, \"%s\" },
  ", s->crc, s->name);
  	}
  
  	buf_printf(b, "};
  ");
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
1915
1916
  
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1917
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
1918
1919
  static void add_depends(struct buffer *b, struct module *mod,
  			struct module *modules)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1920
1921
1922
1923
  {
  	struct symbol *s;
  	struct module *m;
  	int first = 1;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
1924
  	for (m = modules; m; m = m->next)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1925
  		m->seen = is_vmlinux(m->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1926
1927
1928
1929
1930
  
  	buf_printf(b, "
  ");
  	buf_printf(b, "static const char __module_depends[]
  ");
3ff6eecca   Adrian Bunk   remove __attribut...
1931
1932
  	buf_printf(b, "__used
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1933
1934
1935
1936
  	buf_printf(b, "__attribute__((section(\".modinfo\"))) =
  ");
  	buf_printf(b, "\"depends=");
  	for (s = mod->unres; s; s = s->next) {
a61b2dfd1   Sam Ravnborg   kbuild: fix segme...
1937
  		const char *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1938
1939
1940
1941
1942
1943
1944
  		if (!s->module)
  			continue;
  
  		if (s->module->seen)
  			continue;
  
  		s->module->seen = 1;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
1945
1946
  		p = strrchr(s->module->name, '/');
  		if (p)
a61b2dfd1   Sam Ravnborg   kbuild: fix segme...
1947
1948
1949
1950
  			p++;
  		else
  			p = s->module->name;
  		buf_printf(b, "%s%s", first ? "" : ",", p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1951
1952
1953
1954
1955
  		first = 0;
  	}
  	buf_printf(b, "\";
  ");
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
1956
  static void add_srcversion(struct buffer *b, struct module *mod)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1957
1958
1959
1960
1961
1962
1963
1964
1965
  {
  	if (mod->srcversion[0]) {
  		buf_printf(b, "
  ");
  		buf_printf(b, "MODULE_INFO(srcversion, \"%s\");
  ",
  			   mod->srcversion);
  	}
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
1966
  static void write_if_changed(struct buffer *b, const char *fname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
  {
  	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...
2009
  /* parse Module.symvers file. line format:
534b89a9f   Sam Ravnborg   kbuild: fix segv ...
2010
   * 0x12345678<tab>symbol<tab>module[[<tab>export]<tab>something]
bd5cbcedf   Ram Pai   kbuild: export-ty...
2011
   **/
040fcc819   Sam Ravnborg   kbuild: improved ...
2012
  static void read_dump(const char *fname, unsigned int kernel)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2013
2014
2015
2016
  {
  	unsigned long size, pos = 0;
  	void *file = grab_file(fname, &size);
  	char *line;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2017
  	if (!file)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2018
2019
2020
2021
  		/* No symbol versions, silently ignore */
  		return;
  
  	while ((line = get_next_line(&pos, file, size))) {
534b89a9f   Sam Ravnborg   kbuild: fix segv ...
2022
  		char *symname, *modname, *d, *export, *end;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2023
2024
  		unsigned int crc;
  		struct module *mod;
040fcc819   Sam Ravnborg   kbuild: improved ...
2025
  		struct symbol *s;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2026
2027
2028
2029
2030
2031
2032
  
  		if (!(symname = strchr(line, '\t')))
  			goto fail;
  		*symname++ = '\0';
  		if (!(modname = strchr(symname, '\t')))
  			goto fail;
  		*modname++ = '\0';
9ac545b0f   Laurent Riffard   kbuild: fix modul...
2033
  		if ((export = strchr(modname, '\t')) != NULL)
bd5cbcedf   Ram Pai   kbuild: export-ty...
2034
  			*export++ = '\0';
534b89a9f   Sam Ravnborg   kbuild: fix segv ...
2035
2036
  		if (export && ((end = strchr(export, '\t')) != NULL))
  			*end = '\0';
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2037
2038
2039
  		crc = strtoul(line, &d, 16);
  		if (*symname == '\0' || *modname == '\0' || *d != '\0')
  			goto fail;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2040
2041
2042
  		mod = find_module(modname);
  		if (!mod) {
  			if (is_vmlinux(modname))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2043
  				have_vmlinux = 1;
0fa3a88cf   Jan Beulich   kbuild: remove po...
2044
  			mod = new_module(modname);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2045
2046
  			mod->skip = 1;
  		}
bd5cbcedf   Ram Pai   kbuild: export-ty...
2047
  		s = sym_add_exported(symname, mod, export_no(export));
8e70c4588   Sam Ravnborg   kbuild: warn abou...
2048
2049
  		s->kernel    = kernel;
  		s->preloaded = 1;
bd5cbcedf   Ram Pai   kbuild: export-ty...
2050
  		sym_update_crc(symname, mod, crc, export_no(export));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2051
2052
2053
2054
2055
2056
  	}
  	return;
  fail:
  	fatal("parse error in symbol dump file
  ");
  }
040fcc819   Sam Ravnborg   kbuild: improved ...
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
  /* 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...
2069

5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
2070
  static void write_dump(const char *fname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2071
2072
2073
2074
2075
2076
2077
2078
  {
  	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 ...
2079
  			if (dump_sym(symbol))
bd5cbcedf   Ram Pai   kbuild: export-ty...
2080
2081
  				buf_printf(&buf, "0x%08x\t%s\t%s\t%s
  ",
62070fa42   Sam Ravnborg   kbuild: kill trai...
2082
  					symbol->crc, symbol->name,
bd5cbcedf   Ram Pai   kbuild: export-ty...
2083
2084
  					symbol->module->name,
  					export_str(symbol->export));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2085
2086
2087
2088
2089
  			symbol = symbol->next;
  		}
  	}
  	write_if_changed(&buf, fname);
  }
2d04b5ae1   Richard Hacker   kbuild: support l...
2090
2091
2092
2093
  struct ext_sym_list {
  	struct ext_sym_list *next;
  	const char *file;
  };
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
2094
  int main(int argc, char **argv)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2095
2096
2097
  {
  	struct module *mod;
  	struct buffer buf = { };
040fcc819   Sam Ravnborg   kbuild: improved ...
2098
2099
  	char *kernel_read = NULL, *module_read = NULL;
  	char *dump_write = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2100
  	int opt;
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
2101
  	int err;
2d04b5ae1   Richard Hacker   kbuild: support l...
2102
2103
  	struct ext_sym_list *extsym_iter;
  	struct ext_sym_list *extsym_start = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2104

2d04b5ae1   Richard Hacker   kbuild: support l...
2105
  	while ((opt = getopt(argc, argv, "i:I:e:cmsSo:awM:K:")) != -1) {
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2106
2107
2108
2109
2110
2111
2112
2113
  		switch (opt) {
  		case 'i':
  			kernel_read = optarg;
  			break;
  		case 'I':
  			module_read = optarg;
  			external_module = 1;
  			break;
4ce6efed4   Sam Ravnborg   kbuild: soften mo...
2114
2115
2116
  		case 'c':
  			cross_build = 1;
  			break;
2d04b5ae1   Richard Hacker   kbuild: support l...
2117
2118
2119
2120
2121
2122
2123
2124
  		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 ...
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
  		case 'm':
  			modversions = 1;
  			break;
  		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...
2137
2138
2139
  		case 'S':
  			sec_mismatch_verbose = 0;
  			break;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2140
2141
2142
2143
2144
  		case 'w':
  			warn_unresolved = 1;
  			break;
  		default:
  			exit(1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2145
2146
  		}
  	}
040fcc819   Sam Ravnborg   kbuild: improved ...
2147
2148
2149
2150
  	if (kernel_read)
  		read_dump(kernel_read, 1);
  	if (module_read)
  		read_dump(module_read, 0);
2d04b5ae1   Richard Hacker   kbuild: support l...
2151
2152
2153
2154
2155
2156
  	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
2157

df578e7d8   Sam Ravnborg   kbuild: clean up ...
2158
  	while (optind < argc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2159
  		read_symbols(argv[optind++]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2160
2161
2162
2163
  
  	for (mod = modules; mod; mod = mod->next) {
  		if (mod->skip)
  			continue;
c96fca213   Sam Ravnborg   kbuild: warn when...
2164
  		check_exports(mod);
b817f6fef   Sam Ravnborg   kbuild: check lic...
2165
  	}
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
2166
  	err = 0;
b817f6fef   Sam Ravnborg   kbuild: check lic...
2167
  	for (mod = modules; mod; mod = mod->next) {
666ab414f   Andi Kleen   kbuild: fix a buf...
2168
  		char fname[strlen(mod->name) + 10];
b817f6fef   Sam Ravnborg   kbuild: check lic...
2169
2170
  		if (mod->skip)
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2171
2172
2173
2174
  
  		buf.pos = 0;
  
  		add_header(&buf, mod);
2449b8ba0   Ben Hutchings   module,bug: Add T...
2175
  		add_intree_flag(&buf, !external_module);
a9860bf05   Greg Kroah-Hartman   Staging: add TAIN...
2176
  		add_staging_flag(&buf, mod->name);
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
2177
  		err |= add_versions(&buf, mod);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
  		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...
2188
  	if (sec_mismatch_count && !sec_mismatch_verbose)
7c0ac495e   Geert Uytterhoeven   kbuild/modpost: U...
2189
2190
2191
2192
2193
2194
2195
  		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
2196

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