Blame view

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

56fc82c53   Tejun Heo   modpost: NOBITS s...
438
  		if (!nobits && sechdrs[i].sh_offset > info->size) {
df578e7d8   Sam Ravnborg   kbuild: clean up ...
439
440
441
442
443
  			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...
444
445
  			return 0;
  		}
bd5cbcedf   Ram Pai   kbuild: export-ty...
446
447
  		secname = secstrings + sechdrs[i].sh_name;
  		if (strcmp(secname, ".modinfo") == 0) {
56fc82c53   Tejun Heo   modpost: NOBITS s...
448
449
450
  			if (nobits)
  				fatal("%s has NOBITS .modinfo
  ", filename);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
451
452
  			info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
  			info->modinfo_len = sechdrs[i].sh_size;
bd5cbcedf   Ram Pai   kbuild: export-ty...
453
454
  		} else if (strcmp(secname, "__ksymtab") == 0)
  			info->export_sec = i;
c96fca213   Sam Ravnborg   kbuild: warn when...
455
456
  		else if (strcmp(secname, "__ksymtab_unused") == 0)
  			info->export_unused_sec = i;
bd5cbcedf   Ram Pai   kbuild: export-ty...
457
458
  		else if (strcmp(secname, "__ksymtab_gpl") == 0)
  			info->export_gpl_sec = i;
c96fca213   Sam Ravnborg   kbuild: warn when...
459
460
  		else if (strcmp(secname, "__ksymtab_unused_gpl") == 0)
  			info->export_unused_gpl_sec = i;
bd5cbcedf   Ram Pai   kbuild: export-ty...
461
462
  		else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
  			info->export_gpl_future_sec = i;
1ce53adf1   Denys Vlasenko   modpost: support ...
463
464
465
466
467
468
469
470
471
472
473
  		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;
  			sh_link_idx = shndx2secindex(sechdrs[i].sh_link);
  			info->strtab       = (void *)hdr +
  			    sechdrs[sh_link_idx].sh_offset;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
474

1ce53adf1   Denys Vlasenko   modpost: support ...
475
476
477
478
479
480
481
482
  		/* 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
483
  	}
df578e7d8   Sam Ravnborg   kbuild: clean up ...
484
  	if (!info->symtab_start)
cb80514d9   Sam Ravnborg   kbuild: use warn(...
485
486
  		fatal("%s has no symtab?
  ", filename);
df578e7d8   Sam Ravnborg   kbuild: clean up ...
487

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
488
489
490
491
492
493
494
  	/* 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 ...
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
  
  	if (symtab_shndx_idx != ~0U) {
  		Elf32_Word *p;
  		if (symtab_idx !=
  		    shndx2secindex(sechdrs[symtab_shndx_idx].sh_link))
  			fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u
  ",
  			      filename,
  			      shndx2secindex(sechdrs[symtab_shndx_idx].sh_link),
  			      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...
510
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
511
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
512
  static void parse_elf_finish(struct elf_info *info)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
513
514
515
  {
  	release_file(info->hdr, info->size);
  }
4d7365d66   Sam Ravnborg   kbuild: ignore po...
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
  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...
531
532
533
534
535
  	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...
536
537
538
  	/* Do not ignore this symbol */
  	return 0;
  }
f7b05e64b   Luke Yang   kbuild: Fix bug i...
539
540
  #define CRC_PFX     MODULE_SYMBOL_PREFIX "__crc_"
  #define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
541

5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
542
543
  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
544
545
  {
  	unsigned int crc;
1ce53adf1   Denys Vlasenko   modpost: support ...
546
  	enum export export = export_from_sec(info, get_secindex(info, sym));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
547
548
549
  
  	switch (sym->st_shndx) {
  	case SHN_COMMON:
cb80514d9   Sam Ravnborg   kbuild: use warn(...
550
551
  		warn("\"%s\" [%s] is COMMON symbol
  ", symname, mod->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
552
553
554
  		break;
  	case SHN_ABS:
  		/* CRC'd symbol */
8d99513c1   Michal Marek   modpost: fix segf...
555
  		if (strncmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
556
  			crc = (unsigned int) sym->st_value;
bd5cbcedf   Ram Pai   kbuild: export-ty...
557
558
  			sym_update_crc(symname + strlen(CRC_PFX), mod, crc,
  					export);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
559
560
561
562
563
564
565
  		}
  		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...
566
  		if (ignore_undef_symbol(info, symname))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
567
  			break;
8d5290149   Ben Colline   [SPARC]: Deal wit...
568
569
570
571
572
573
  /* 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
574
575
576
  		if (info->hdr->e_machine == EM_SPARC ||
  		    info->hdr->e_machine == EM_SPARCV9) {
  			/* Ignore register directives. */
8d5290149   Ben Colline   [SPARC]: Deal wit...
577
  			if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
578
  				break;
62070fa42   Sam Ravnborg   kbuild: kill trai...
579
580
581
582
583
584
  			if (symname[0] == '.') {
  				char *munged = strdup(symname);
  				munged[0] = '_';
  				munged[1] = toupper(munged[1]);
  				symname = munged;
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
585
586
  		}
  #endif
62070fa42   Sam Ravnborg   kbuild: kill trai...
587

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
588
  		if (memcmp(symname, MODULE_SYMBOL_PREFIX,
df578e7d8   Sam Ravnborg   kbuild: clean up ...
589
590
591
592
593
594
595
  			   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
596
597
598
  		break;
  	default:
  		/* All exported symbols */
8d99513c1   Michal Marek   modpost: fix segf...
599
  		if (strncmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
bd5cbcedf   Ram Pai   kbuild: export-ty...
600
601
  			sym_add_exported(symname + strlen(KSYMTAB_PFX), mod,
  					export);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
602
603
604
605
606
607
608
609
  		}
  		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...
610
611
612
  /**
   * Parse tag=value strings from .modinfo section
   **/
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
  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...
630
631
  static char *get_next_modinfo(void *modinfo, unsigned long modinfo_len,
  			      const char *tag, char *info)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
632
633
634
635
  {
  	char *p;
  	unsigned int taglen = strlen(tag);
  	unsigned long size = modinfo_len;
b817f6fef   Sam Ravnborg   kbuild: check lic...
636
637
638
639
  	if (info) {
  		size -= info - (char *)modinfo;
  		modinfo = next_string(info, &size);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
640
641
642
643
644
645
  	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...
646
647
648
649
650
651
  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...
652
  /**
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
653
654
655
656
657
   * 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 ...
658
  	int slen, sublen;
62070fa42   Sam Ravnborg   kbuild: kill trai...
659

4c8fbca58   Sam Ravnborg   kbuild: whitelist...
660
661
  	if (!s || !sub)
  		return 1;
62070fa42   Sam Ravnborg   kbuild: kill trai...
662

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

4c8fbca58   Sam Ravnborg   kbuild: whitelist...
666
667
  	if ((slen == 0) || (sublen == 0))
  		return 1;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
668
669
  	if (sublen > slen)
  		return 1;
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
670

df578e7d8   Sam Ravnborg   kbuild: clean up ...
671
  	return memcmp(s + slen - sublen, sub, sublen);
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
672
  }
ff13f9269   Sam Ravnborg   kbuild: introduce...
673
674
  static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
  {
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
675
676
677
  	if (sym)
  		return elf->strtab + sym->st_name;
  	else
f666751a0   Sam Ravnborg   kbuild/modpost: i...
678
  		return "(unknown)";
ff13f9269   Sam Ravnborg   kbuild: introduce...
679
  }
1ce53adf1   Denys Vlasenko   modpost: support ...
680
  static const char *sec_name(struct elf_info *elf, int secindex)
ff13f9269   Sam Ravnborg   kbuild: introduce...
681
682
683
  {
  	Elf_Shdr *sechdrs = elf->sechdrs;
  	return (void *)elf->hdr +
1ce53adf1   Denys Vlasenko   modpost: support ...
684
685
  		elf->sechdrs[elf->secindex_strings].sh_offset +
  		sechdrs[secindex].sh_name;
ff13f9269   Sam Ravnborg   kbuild: introduce...
686
687
688
689
690
  }
  
  static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr)
  {
  	return (void *)elf->hdr +
1ce53adf1   Denys Vlasenko   modpost: support ...
691
692
  		elf->sechdrs[elf->secindex_strings].sh_offset +
  		sechdr->sh_name;
ff13f9269   Sam Ravnborg   kbuild: introduce...
693
  }
10668220a   Sam Ravnborg   kbuild: introduce...
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
  /* 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...
714
   * "*foo" will match a string that ends with "foo"
10668220a   Sam Ravnborg   kbuild: introduce...
715
716
717
718
719
720
   * "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...
721
  static int match(const char *sym, const char * const pat[])
10668220a   Sam Ravnborg   kbuild: introduce...
722
723
724
725
726
  {
  	const char *p;
  	while (*pat) {
  		p = *pat++;
  		const char *endp = p + strlen(p) - 1;
6c5bd235b   Sam Ravnborg   kbuild: check sec...
727
728
729
730
731
  		/* "*foo" */
  		if (*p == '*') {
  			if (strrcmp(sym, p + 1) == 0)
  				return 1;
  		}
10668220a   Sam Ravnborg   kbuild: introduce...
732
  		/* "foo*" */
6c5bd235b   Sam Ravnborg   kbuild: check sec...
733
  		else if (*endp == '*') {
10668220a   Sam Ravnborg   kbuild: introduce...
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
  			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...
753
754
  /* sections that we do not want to do full section mismatch check on */
  static const char *section_white_list[] =
4391ed6aa   Sam Ravnborg   kbuild, modpost: ...
755
756
757
  {
  	".comment*",
  	".debug*",
019fca84e   David Howells   MN10300: Permit ....
758
  	".GCC-command-line",	/* mn10300 */
4391ed6aa   Sam Ravnborg   kbuild, modpost: ...
759
760
761
762
763
764
765
766
  	".mdebug*",        /* alpha, score, mips etc. */
  	".pdr",            /* alpha, score, mips etc. */
  	".stab*",
  	".note*",
  	".got*",
  	".toc*",
  	NULL
  };
10668220a   Sam Ravnborg   kbuild: introduce...
767

e241a6303   Sam Ravnborg   kbuild: warn abou...
768
  /*
b614a697d   Anders Kaseorg   kbuild, modpost: ...
769
   * This is used to find sections missing the SHF_ALLOC flag.
e241a6303   Sam Ravnborg   kbuild: warn abou...
770
   * The cause of this is often a section specified in assembler
b614a697d   Anders Kaseorg   kbuild, modpost: ...
771
   * without "ax" / "aw".
e241a6303   Sam Ravnborg   kbuild: warn abou...
772
   */
b614a697d   Anders Kaseorg   kbuild, modpost: ...
773
774
  static void check_section(const char *modname, struct elf_info *elf,
                            Elf_Shdr *sechdr)
e241a6303   Sam Ravnborg   kbuild: warn abou...
775
  {
b614a697d   Anders Kaseorg   kbuild, modpost: ...
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
  	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...
791
  	}
e241a6303   Sam Ravnborg   kbuild: warn abou...
792
  }
eb8f68904   Sam Ravnborg   Use separate sect...
793
  #define ALL_INIT_DATA_SECTIONS \
fd6c3a8dc   Jan Beulich   initconst adjustm...
794
795
  	".init.setup$", ".init.rodata$", \
  	".devinit.rodata$", ".cpuinit.rodata$", ".meminit.rodata$" \
eb8f68904   Sam Ravnborg   Use separate sect...
796
797
798
  	".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...
799

eb8f68904   Sam Ravnborg   Use separate sect...
800
801
802
803
  #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...
804

4a31a229f   Uwe Kleine-König   modpost: define A...
805
806
807
808
809
810
811
  #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...
812

6c5bd235b   Sam Ravnborg   kbuild: check sec...
813
  #define DATA_SECTIONS ".data$", ".data.rel$"
10668220a   Sam Ravnborg   kbuild: introduce...
814
  #define TEXT_SECTIONS ".text$"
fd6c3a8dc   Jan Beulich   initconst adjustm...
815
816
817
818
  #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...
819

fd6c3a8dc   Jan Beulich   initconst adjustm...
820
821
822
823
  #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...
824

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

6a841528d   Rusty Russell   param: silence .i...
1040
1041
1042
1043
1044
  	/* 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...
1045
  	/* Check for pattern 2 */
6c5bd235b   Sam Ravnborg   kbuild: check sec...
1046
1047
  	if (match(tosec, init_exit_sections) &&
  	    match(fromsec, data_sections) &&
af92a82d0   Uwe Kleine-König   modpost: make sym...
1048
  	    match(fromsym, mismatch->symbol_white_list))
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1049
  		return 0;
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1050

9bf8cb9b7   Sam Ravnborg   kbuild: fix warni...
1051
  	/* Check for pattern 3 */
6c5bd235b   Sam Ravnborg   kbuild: check sec...
1052
1053
  	if (match(fromsec, head_sections) &&
  	    match(tosec, init_sections))
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1054
  		return 0;
9bf8cb9b7   Sam Ravnborg   kbuild: fix warni...
1055

1d8af559f   Sam Ravnborg   kbuild: consolida...
1056
  	/* Check for pattern 4 */
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1057
1058
  	if (match(tosym, linker_symbols))
  		return 0;
9bf8cb9b7   Sam Ravnborg   kbuild: fix warni...
1059

58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1060
  	return 1;
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1061
1062
1063
  }
  
  /**
93684d3b8   Sam Ravnborg   kbuild: include s...
1064
1065
1066
1067
1068
1069
   * 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...
1070
  static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,
93684d3b8   Sam Ravnborg   kbuild: include s...
1071
1072
1073
  				Elf_Sym *relsym)
  {
  	Elf_Sym *sym;
9ad21c3f3   Sam Ravnborg   kbuild: try harde...
1074
1075
1076
  	Elf_Sym *near = NULL;
  	Elf64_Sword distance = 20;
  	Elf64_Sword d;
1ce53adf1   Denys Vlasenko   modpost: support ...
1077
  	unsigned int relsym_secindex;
93684d3b8   Sam Ravnborg   kbuild: include s...
1078
1079
1080
  
  	if (relsym->st_name != 0)
  		return relsym;
1ce53adf1   Denys Vlasenko   modpost: support ...
1081
1082
  
  	relsym_secindex = get_secindex(elf, relsym);
93684d3b8   Sam Ravnborg   kbuild: include s...
1083
  	for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
1ce53adf1   Denys Vlasenko   modpost: support ...
1084
  		if (get_secindex(elf, sym) != relsym_secindex)
93684d3b8   Sam Ravnborg   kbuild: include s...
1085
  			continue;
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1086
1087
  		if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
  			continue;
93684d3b8   Sam Ravnborg   kbuild: include s...
1088
1089
  		if (sym->st_value == addr)
  			return sym;
9ad21c3f3   Sam Ravnborg   kbuild: try harde...
1090
1091
1092
1093
1094
1095
1096
1097
  		/* 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...
1098
  	}
9ad21c3f3   Sam Ravnborg   kbuild: try harde...
1099
1100
1101
1102
1103
  	/* We need a close match */
  	if (distance < 20)
  		return near;
  	else
  		return NULL;
93684d3b8   Sam Ravnborg   kbuild: include s...
1104
  }
da68d61f8   David Brownell   [PATCH] remove mo...
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
  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...
1128
  /*
43c74d179   Sam Ravnborg   kbuild: in the se...
1129
1130
1131
1132
   * 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...
1133
   **/
157c23c80   Sam Ravnborg   kbuild: use simpl...
1134
1135
  static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
  				 const char *sec)
b39927cf4   Sam Ravnborg   kbuild: check for...
1136
1137
  {
  	Elf_Sym *sym;
157c23c80   Sam Ravnborg   kbuild: use simpl...
1138
  	Elf_Sym *near = NULL;
157c23c80   Sam Ravnborg   kbuild: use simpl...
1139
  	Elf_Addr distance = ~0;
62070fa42   Sam Ravnborg   kbuild: kill trai...
1140

b39927cf4   Sam Ravnborg   kbuild: check for...
1141
1142
  	for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
  		const char *symsec;
1ce53adf1   Denys Vlasenko   modpost: support ...
1143
  		if (is_shndx_special(sym->st_shndx))
b39927cf4   Sam Ravnborg   kbuild: check for...
1144
  			continue;
1ce53adf1   Denys Vlasenko   modpost: support ...
1145
  		symsec = sec_name(elf, get_secindex(elf, sym));
b39927cf4   Sam Ravnborg   kbuild: check for...
1146
1147
  		if (strcmp(symsec, sec) != 0)
  			continue;
da68d61f8   David Brownell   [PATCH] remove mo...
1148
1149
  		if (!is_valid_name(elf, sym))
  			continue;
b39927cf4   Sam Ravnborg   kbuild: check for...
1150
  		if (sym->st_value <= addr) {
157c23c80   Sam Ravnborg   kbuild: use simpl...
1151
1152
1153
1154
1155
  			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...
1156
  			}
b39927cf4   Sam Ravnborg   kbuild: check for...
1157
1158
  		}
  	}
157c23c80   Sam Ravnborg   kbuild: use simpl...
1159
  	return near;
b39927cf4   Sam Ravnborg   kbuild: check for...
1160
  }
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1161
  /*
588ccd732   Sam Ravnborg   kbuild: add verbo...
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
   * Convert a section name to the function/data attribute
   * .init.text => __init
   * .cpuinit.data => __cpudata
   * .memexitconst => __memconst
   * etc.
  */
  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, " ");
  		return r; /* we leak her but we do not care */
  	} else {
5003bab82   Andrew Morton   fix "scripts/mod/...
1191
  		return strdup("");
588ccd732   Sam Ravnborg   kbuild: add verbo...
1192
1193
1194
1195
1196
1197
1198
1199
  	}
  }
  
  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...
1200
  		return -1;
588ccd732   Sam Ravnborg   kbuild: add verbo...
1201
1202
1203
  }
  
  /*
b39927cf4   Sam Ravnborg   kbuild: check for...
1204
1205
   * Print a warning about a section mismatch.
   * Try to find symbols near it so user can find it.
4c8fbca58   Sam Ravnborg   kbuild: whitelist...
1206
   * Check whitelist before warning - it may be a false positive.
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1207
   */
0d2a636ee   Uwe Kleine-König   modpost: pass aro...
1208
1209
  static void report_sec_mismatch(const char *modname,
  				const struct sectioncheck *mismatch,
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1210
1211
1212
                                  const char *fromsec,
                                  unsigned long long fromaddr,
                                  const char *fromsym,
588ccd732   Sam Ravnborg   kbuild: add verbo...
1213
1214
1215
1216
1217
1218
                                  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...
1219
1220
  	char *prl_from;
  	char *prl_to;
f666751a0   Sam Ravnborg   kbuild/modpost: i...
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
  
  	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...
1232

e5f95c8b7   Sam Ravnborg   kbuild: print onl...
1233
1234
1235
  	sec_mismatch_count++;
  	if (!sec_mismatch_verbose)
  		return;
7c0ac495e   Geert Uytterhoeven   kbuild/modpost: U...
1236
1237
1238
1239
1240
  	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...
1241

0d2a636ee   Uwe Kleine-König   modpost: pass aro...
1242
  	switch (mismatch->mismatch) {
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1243
  	case TEXT_TO_ANY_INIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1244
1245
  		prl_from = sec2annotation(fromsec);
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1246
  		fprintf(stderr,
f666751a0   Sam Ravnborg   kbuild/modpost: i...
1247
1248
  		"The function %s%s() references
  "
588ccd732   Sam Ravnborg   kbuild: add verbo...
1249
1250
1251
1252
1253
1254
  		"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...
1255
1256
1257
1258
1259
  		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...
1260
  		break;
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1261
  	case DATA_TO_ANY_INIT: {
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1262
  		prl_to = sec2annotation(tosec);
af92a82d0   Uwe Kleine-König   modpost: make sym...
1263
  		const char *const *s = mismatch->symbol_white_list;
588ccd732   Sam Ravnborg   kbuild: add verbo...
1264
1265
1266
1267
1268
1269
1270
  		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 ...
1271
  		"variable with __init* or __refdata (see linux/init.h) "
588ccd732   Sam Ravnborg   kbuild: add verbo...
1272
1273
  		"or name the variable:
  ",
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1274
  		fromsym, to, prl_to, tosym, to_p);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1275
1276
1277
1278
  		while (*s)
  			fprintf(stderr, "%s, ", *s++);
  		fprintf(stderr, "
  ");
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1279
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1280
  		break;
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1281
  	}
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1282
  	case TEXT_TO_ANY_EXIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1283
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1284
1285
1286
1287
1288
1289
1290
  		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...
1291
1292
  		fromsym, to, to, tosym, to_p, prl_to, tosym);
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1293
  		break;
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1294
  	case DATA_TO_ANY_EXIT: {
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1295
  		prl_to = sec2annotation(tosec);
af92a82d0   Uwe Kleine-König   modpost: make sym...
1296
  		const char *const *s = mismatch->symbol_white_list;
588ccd732   Sam Ravnborg   kbuild: add verbo...
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
  		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...
1307
  		fromsym, to, prl_to, tosym, to_p);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1308
1309
1310
1311
  		while (*s)
  			fprintf(stderr, "%s, ", *s++);
  		fprintf(stderr, "
  ");
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1312
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1313
1314
  		break;
  	}
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1315
1316
  	case XXXINIT_TO_SOME_INIT:
  	case XXXEXIT_TO_SOME_EXIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1317
1318
  		prl_from = sec2annotation(fromsec);
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1319
1320
1321
1322
1323
1324
1325
1326
1327
  		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...
1328
1329
  		from, prl_from, fromsym, from_p,
  		to, prl_to, tosym, to_p,
b1d2675a6   Geert Uytterhoeven   kbuild: fix rever...
1330
  		tosym, fromsym, tosym);
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1331
1332
  		free(prl_from);
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1333
  		break;
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1334
  	case ANY_INIT_TO_ANY_EXIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1335
1336
  		prl_from = sec2annotation(fromsec);
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
  		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...
1351
1352
  		from, prl_from, fromsym, from_p,
  		to, prl_to, tosym, to_p,
5003bab82   Andrew Morton   fix "scripts/mod/...
1353
  		prl_to, tosym, to_p);
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1354
1355
  		free(prl_from);
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1356
  		break;
bbd3f4fb8   Uwe Kleine-König   modpost: give mos...
1357
  	case ANY_EXIT_TO_ANY_INIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1358
1359
  		prl_from = sec2annotation(fromsec);
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
  		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...
1374
1375
1376
1377
1378
  		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...
1379
1380
  		break;
  	case EXPORT_TO_INIT_EXIT:
37ed19d5c   Alexey Fomenko   scripts/mod/modpo...
1381
  		prl_to = sec2annotation(tosec);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1382
1383
1384
1385
1386
1387
  		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...
1388
1389
  		tosym, prl_to, prl_to, tosym);
  		free(prl_to);
588ccd732   Sam Ravnborg   kbuild: add verbo...
1390
1391
1392
1393
  		break;
  	}
  	fprintf(stderr, "
  ");
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1394
1395
1396
1397
1398
1399
  }
  
  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...
1400
  	const struct sectioncheck *mismatch;
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1401

1ce53adf1   Denys Vlasenko   modpost: support ...
1402
  	tosec = sec_name(elf, get_secindex(elf, sym));
588ccd732   Sam Ravnborg   kbuild: add verbo...
1403
  	mismatch = section_mismatch(fromsec, tosec);
0d2a636ee   Uwe Kleine-König   modpost: pass aro...
1404
  	if (mismatch) {
588ccd732   Sam Ravnborg   kbuild: add verbo...
1405
1406
  		Elf_Sym *to;
  		Elf_Sym *from;
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1407
  		const char *tosym;
588ccd732   Sam Ravnborg   kbuild: add verbo...
1408
  		const char *fromsym;
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1409

588ccd732   Sam Ravnborg   kbuild: add verbo...
1410
1411
1412
1413
  		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...
1414
1415
  
  		/* check whitelist - we may ignore it */
af92a82d0   Uwe Kleine-König   modpost: make sym...
1416
1417
  		if (secref_whitelist(mismatch,
  					fromsec, fromsym, tosec, tosym)) {
588ccd732   Sam Ravnborg   kbuild: add verbo...
1418
1419
1420
1421
  			report_sec_mismatch(modname, mismatch,
  			   fromsec, r->r_offset, fromsym,
  			   is_function(from), tosec, tosym,
  			   is_function(to));
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1422
  		}
b39927cf4   Sam Ravnborg   kbuild: check for...
1423
1424
  	}
  }
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1425
  static unsigned int *reloc_location(struct elf_info *elf,
5b24c0715   Sam Ravnborg   kbuild: code refa...
1426
  				    Elf_Shdr *sechdr, Elf_Rela *r)
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1427
1428
  {
  	Elf_Shdr *sechdrs = elf->sechdrs;
1ce53adf1   Denys Vlasenko   modpost: support ...
1429
  	int section = shndx2secindex(sechdr->sh_info);
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1430
1431
  
  	return (void *)elf->hdr + sechdrs[section].sh_offset +
1c938663d   Krzysztof Halasa   kbuild: Fix modpo...
1432
  		r->r_offset - sechdrs[section].sh_addr;
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1433
  }
5b24c0715   Sam Ravnborg   kbuild: code refa...
1434
  static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1435
1436
  {
  	unsigned int r_typ = ELF_R_TYPE(r->r_info);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1437
  	unsigned int *location = reloc_location(elf, sechdr, r);
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
  
  	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...
1452
  static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
56a974fa2   Sam Ravnborg   kbuild: make bett...
1453
1454
1455
1456
1457
1458
  {
  	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 ...
1459
1460
  		r->r_addend = (int)(long)
  		              (elf->symtab_start + ELF_R_SYM(r->r_info));
56a974fa2   Sam Ravnborg   kbuild: make bett...
1461
1462
1463
  		break;
  	case R_ARM_PC24:
  		/* From ARM ABI: ((S + A) | T) - P */
df578e7d8   Sam Ravnborg   kbuild: clean up ...
1464
  		r->r_addend = (int)(long)(elf->hdr +
5b24c0715   Sam Ravnborg   kbuild: code refa...
1465
1466
  		              sechdr->sh_offset +
  		              (r->r_offset - sechdr->sh_addr));
56a974fa2   Sam Ravnborg   kbuild: make bett...
1467
1468
1469
1470
1471
1472
  		break;
  	default:
  		return 1;
  	}
  	return 0;
  }
5b24c0715   Sam Ravnborg   kbuild: code refa...
1473
  static int addend_mips_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1474
1475
  {
  	unsigned int r_typ = ELF_R_TYPE(r->r_info);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1476
  	unsigned int *location = reloc_location(elf, sechdr, r);
ae4ac1232   Atsushi Nemoto   kbuild: make bett...
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
  	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...
1495
  static void section_rela(const char *modname, struct elf_info *elf,
10668220a   Sam Ravnborg   kbuild: introduce...
1496
                           Elf_Shdr *sechdr)
5b24c0715   Sam Ravnborg   kbuild: code refa...
1497
1498
1499
1500
1501
1502
  {
  	Elf_Sym  *sym;
  	Elf_Rela *rela;
  	Elf_Rela r;
  	unsigned int r_sym;
  	const char *fromsec;
5b24c0715   Sam Ravnborg   kbuild: code refa...
1503

ff13f9269   Sam Ravnborg   kbuild: introduce...
1504
  	Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset;
5b24c0715   Sam Ravnborg   kbuild: code refa...
1505
  	Elf_Rela *stop  = (void *)start + sechdr->sh_size;
ff13f9269   Sam Ravnborg   kbuild: introduce...
1506
  	fromsec = sech_name(elf, sechdr);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1507
1508
  	fromsec += strlen(".rela");
  	/* if from section (name) is know good then skip it */
b614a697d   Anders Kaseorg   kbuild, modpost: ...
1509
  	if (match(fromsec, section_white_list))
5b24c0715   Sam Ravnborg   kbuild: code refa...
1510
  		return;
e241a6303   Sam Ravnborg   kbuild: warn abou...
1511

5b24c0715   Sam Ravnborg   kbuild: code refa...
1512
1513
1514
  	for (rela = start; rela < stop; rela++) {
  		r.r_offset = TO_NATIVE(rela->r_offset);
  #if KERNEL_ELFCLASS == ELFCLASS64
ff13f9269   Sam Ravnborg   kbuild: introduce...
1515
  		if (elf->hdr->e_machine == EM_MIPS) {
5b24c0715   Sam Ravnborg   kbuild: code refa...
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
  			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 ...
1532
  		if (is_shndx_special(sym->st_shndx))
5b24c0715   Sam Ravnborg   kbuild: code refa...
1533
  			continue;
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1534
  		check_section_mismatch(modname, elf, &r, sym, fromsec);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1535
1536
1537
1538
  	}
  }
  
  static void section_rel(const char *modname, struct elf_info *elf,
10668220a   Sam Ravnborg   kbuild: introduce...
1539
                          Elf_Shdr *sechdr)
5b24c0715   Sam Ravnborg   kbuild: code refa...
1540
1541
1542
1543
1544
1545
  {
  	Elf_Sym *sym;
  	Elf_Rel *rel;
  	Elf_Rela r;
  	unsigned int r_sym;
  	const char *fromsec;
5b24c0715   Sam Ravnborg   kbuild: code refa...
1546

ff13f9269   Sam Ravnborg   kbuild: introduce...
1547
  	Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset;
5b24c0715   Sam Ravnborg   kbuild: code refa...
1548
  	Elf_Rel *stop  = (void *)start + sechdr->sh_size;
ff13f9269   Sam Ravnborg   kbuild: introduce...
1549
  	fromsec = sech_name(elf, sechdr);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1550
1551
  	fromsec += strlen(".rel");
  	/* if from section (name) is know good then skip it */
b614a697d   Anders Kaseorg   kbuild, modpost: ...
1552
  	if (match(fromsec, section_white_list))
5b24c0715   Sam Ravnborg   kbuild: code refa...
1553
1554
1555
1556
1557
  		return;
  
  	for (rel = start; rel < stop; rel++) {
  		r.r_offset = TO_NATIVE(rel->r_offset);
  #if KERNEL_ELFCLASS == ELFCLASS64
ff13f9269   Sam Ravnborg   kbuild: introduce...
1558
  		if (elf->hdr->e_machine == EM_MIPS) {
5b24c0715   Sam Ravnborg   kbuild: code refa...
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
  			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...
1573
  		switch (elf->hdr->e_machine) {
5b24c0715   Sam Ravnborg   kbuild: code refa...
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
  		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 ...
1589
  		if (is_shndx_special(sym->st_shndx))
5b24c0715   Sam Ravnborg   kbuild: code refa...
1590
  			continue;
58fb0d4f2   Sam Ravnborg   kbuild: simplifie...
1591
  		check_section_mismatch(modname, elf, &r, sym, fromsec);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1592
1593
  	}
  }
b39927cf4   Sam Ravnborg   kbuild: check for...
1594
1595
1596
1597
1598
1599
1600
  /**
   * 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
   * marked __initdata will be discarded when the module has been intialized.
   * 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...
1601
   * only when a module is unloaded which never happens for built-in modules.
b39927cf4   Sam Ravnborg   kbuild: check for...
1602
1603
1604
1605
1606
   * 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...
1607
                            struct elf_info *elf)
b39927cf4   Sam Ravnborg   kbuild: check for...
1608
1609
  {
  	int i;
b39927cf4   Sam Ravnborg   kbuild: check for...
1610
  	Elf_Shdr *sechdrs = elf->sechdrs;
62070fa42   Sam Ravnborg   kbuild: kill trai...
1611

b39927cf4   Sam Ravnborg   kbuild: check for...
1612
  	/* Walk through all sections */
1ce53adf1   Denys Vlasenko   modpost: support ...
1613
  	for (i = 0; i < elf->num_sections; i++) {
b614a697d   Anders Kaseorg   kbuild, modpost: ...
1614
  		check_section(modname, elf, &elf->sechdrs[i]);
b39927cf4   Sam Ravnborg   kbuild: check for...
1615
  		/* We want to process only relocation sections and not .init */
5b24c0715   Sam Ravnborg   kbuild: code refa...
1616
  		if (sechdrs[i].sh_type == SHT_RELA)
10668220a   Sam Ravnborg   kbuild: introduce...
1617
  			section_rela(modname, elf, &elf->sechdrs[i]);
5b24c0715   Sam Ravnborg   kbuild: code refa...
1618
  		else if (sechdrs[i].sh_type == SHT_REL)
10668220a   Sam Ravnborg   kbuild: introduce...
1619
  			section_rel(modname, elf, &elf->sechdrs[i]);
b39927cf4   Sam Ravnborg   kbuild: check for...
1620
1621
  	}
  }
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
1622
  static void read_symbols(char *modname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1623
1624
1625
  {
  	const char *symname;
  	char *version;
b817f6fef   Sam Ravnborg   kbuild: check lic...
1626
  	char *license;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1627
1628
1629
  	struct module *mod;
  	struct elf_info info = { };
  	Elf_Sym *sym;
85bd2fddd   Sam Ravnborg   kbuild: fix secti...
1630
1631
  	if (!parse_elf(&info, modname))
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1632
1633
1634
1635
1636
1637
  
  	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
1638
  		have_vmlinux = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1639
1640
  		mod->skip = 1;
  	}
b817f6fef   Sam Ravnborg   kbuild: check lic...
1641
  	license = get_modinfo(info.modinfo, info.modinfo_len, "license");
2fa365682   Sam Ravnborg   kbuild: soften MO...
1642
1643
1644
1645
1646
1647
  	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...
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
  	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
1658
1659
1660
1661
1662
1663
  	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...
1664
  	if (!is_vmlinux(modname) ||
10668220a   Sam Ravnborg   kbuild: introduce...
1665
1666
  	     (is_vmlinux(modname) && vmlinux_section_warnings))
  		check_sec_ref(mod, modname, &info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
  
  	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...
1677
  	/* Our trick to get versioning for module struct etc. - it's
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1678
1679
1680
1681
  	 * 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...
1682
  		mod->unres = alloc_symbol("module_layout", 0, mod->unres);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1683
1684
1685
1686
1687
1688
1689
  }
  
  #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...
1690
1691
  void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf,
  						      const char *fmt, ...)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1692
1693
1694
1695
  {
  	char tmp[SZ];
  	int len;
  	va_list ap;
62070fa42   Sam Ravnborg   kbuild: kill trai...
1696

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

5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
2033
  static void write_dump(const char *fname)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2034
2035
2036
2037
2038
2039
2040
2041
  {
  	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 ...
2042
  			if (dump_sym(symbol))
bd5cbcedf   Ram Pai   kbuild: export-ty...
2043
2044
  				buf_printf(&buf, "0x%08x\t%s\t%s\t%s
  ",
62070fa42   Sam Ravnborg   kbuild: kill trai...
2045
  					symbol->crc, symbol->name,
bd5cbcedf   Ram Pai   kbuild: export-ty...
2046
2047
  					symbol->module->name,
  					export_str(symbol->export));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2048
2049
2050
2051
2052
  			symbol = symbol->next;
  		}
  	}
  	write_if_changed(&buf, fname);
  }
2d04b5ae1   Richard Hacker   kbuild: support l...
2053
2054
2055
2056
  struct ext_sym_list {
  	struct ext_sym_list *next;
  	const char *file;
  };
5c3ead8c7   Sam Ravnborg   kbuild: apply Cod...
2057
  int main(int argc, char **argv)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2058
2059
2060
  {
  	struct module *mod;
  	struct buffer buf = { };
040fcc819   Sam Ravnborg   kbuild: improved ...
2061
2062
  	char *kernel_read = NULL, *module_read = NULL;
  	char *dump_write = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2063
  	int opt;
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
2064
  	int err;
2d04b5ae1   Richard Hacker   kbuild: support l...
2065
2066
  	struct ext_sym_list *extsym_iter;
  	struct ext_sym_list *extsym_start = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2067

2d04b5ae1   Richard Hacker   kbuild: support l...
2068
  	while ((opt = getopt(argc, argv, "i:I:e:cmsSo:awM:K:")) != -1) {
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2069
2070
2071
2072
2073
2074
2075
2076
  		switch (opt) {
  		case 'i':
  			kernel_read = optarg;
  			break;
  		case 'I':
  			module_read = optarg;
  			external_module = 1;
  			break;
4ce6efed4   Sam Ravnborg   kbuild: soften mo...
2077
2078
2079
  		case 'c':
  			cross_build = 1;
  			break;
2d04b5ae1   Richard Hacker   kbuild: support l...
2080
2081
2082
2083
2084
2085
2086
2087
  		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 ...
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
  		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...
2100
2101
2102
  		case 'S':
  			sec_mismatch_verbose = 0;
  			break;
df578e7d8   Sam Ravnborg   kbuild: clean up ...
2103
2104
2105
2106
2107
  		case 'w':
  			warn_unresolved = 1;
  			break;
  		default:
  			exit(1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2108
2109
  		}
  	}
040fcc819   Sam Ravnborg   kbuild: improved ...
2110
2111
2112
2113
  	if (kernel_read)
  		read_dump(kernel_read, 1);
  	if (module_read)
  		read_dump(module_read, 0);
2d04b5ae1   Richard Hacker   kbuild: support l...
2114
2115
2116
2117
2118
2119
  	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
2120

df578e7d8   Sam Ravnborg   kbuild: clean up ...
2121
  	while (optind < argc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2122
  		read_symbols(argv[optind++]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2123
2124
2125
2126
  
  	for (mod = modules; mod; mod = mod->next) {
  		if (mod->skip)
  			continue;
c96fca213   Sam Ravnborg   kbuild: warn when...
2127
  		check_exports(mod);
b817f6fef   Sam Ravnborg   kbuild: check lic...
2128
  	}
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
2129
  	err = 0;
b817f6fef   Sam Ravnborg   kbuild: check lic...
2130
  	for (mod = modules; mod; mod = mod->next) {
666ab414f   Andi Kleen   kbuild: fix a buf...
2131
  		char fname[strlen(mod->name) + 10];
b817f6fef   Sam Ravnborg   kbuild: check lic...
2132
2133
  		if (mod->skip)
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2134
2135
2136
2137
  
  		buf.pos = 0;
  
  		add_header(&buf, mod);
a9860bf05   Greg Kroah-Hartman   Staging: add TAIN...
2138
  		add_staging_flag(&buf, mod->name);
c53ddacdc   Kirill Korotaev   kbuild: fail kern...
2139
  		err |= add_versions(&buf, mod);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
  		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...
2150
  	if (sec_mismatch_count && !sec_mismatch_verbose)
7c0ac495e   Geert Uytterhoeven   kbuild/modpost: U...
2151
2152
2153
2154
2155
2156
2157
  		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
2158

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