modpost.c 40.8 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1
2
3
4
/* Postprocess module symbol versions
 *
 * Copyright 2003       Kai Germaschewski
 * Copyright 2002-2004  Rusty Russell, IBM Corporation
5
 * Copyright 2006       Sam Ravnborg
Linus Torvalds's avatar
Linus Torvalds committed
6
7
8
9
10
11
12
13
14
15
 * 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 ...
 */

#include <ctype.h>
#include "modpost.h"
16
#include "../../include/linux/license.h"
Linus Torvalds's avatar
Linus Torvalds committed
17
18
19
20
21
22
23

/* 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;
24
25
/* If we are modposting external module set to 1 */
static int external_module = 0;
26
27
/* Only warn about unresolved symbols */
static int warn_unresolved = 0;
28
/* How a symbol is exported */
29
30
31
32
enum export {
	export_plain,      export_unused,     export_gpl,
	export_unused_gpl, export_gpl_future, export_unknown
};
Linus Torvalds's avatar
Linus Torvalds committed
33

34
void fatal(const char *fmt, ...)
Linus Torvalds's avatar
Linus Torvalds committed
35
36
37
38
39
40
41
42
43
44
45
46
{
	va_list arglist;

	fprintf(stderr, "FATAL: ");

	va_start(arglist, fmt);
	vfprintf(stderr, fmt, arglist);
	va_end(arglist);

	exit(1);
}

47
void warn(const char *fmt, ...)
Linus Torvalds's avatar
Linus Torvalds committed
48
49
50
51
52
53
54
55
56
57
{
	va_list arglist;

	fprintf(stderr, "WARNING: ");

	va_start(arglist, fmt);
	vfprintf(stderr, fmt, arglist);
	va_end(arglist);
}

58
59
60
61
62
63
64
65
66
67
68
void merror(const char *fmt, ...)
{
	va_list arglist;

	fprintf(stderr, "ERROR: ");

	va_start(arglist, fmt);
	vfprintf(stderr, fmt, arglist);
	va_end(arglist);
}

69
70
71
72
73
74
75
76
77
78
79
80
static int is_vmlinux(const char *modname)
{
	const char *myname;

	if ((myname = strrchr(modname, '/')))
		myname++;
	else
		myname = modname;

	return strcmp(myname, "vmlinux") == 0;
}

Linus Torvalds's avatar
Linus Torvalds committed
81
82
83
84
85
86
87
88
89
90
91
92
void *do_nofail(void *ptr, const char *expr)
{
	if (!ptr) {
		fatal("modpost: Memory allocation failure: %s.\n", expr);
	}
	return ptr;
}

/* A list of all modules we processed */

static struct module *modules;

93
static struct module *find_module(char *modname)
Linus Torvalds's avatar
Linus Torvalds committed
94
95
96
97
98
99
100
101
102
{
	struct module *mod;

	for (mod = modules; mod; mod = mod->next)
		if (strcmp(mod->name, modname) == 0)
			break;
	return mod;
}

103
static struct module *new_module(char *modname)
Linus Torvalds's avatar
Linus Torvalds committed
104
105
106
{
	struct module *mod;
	char *p, *s;
107

Linus Torvalds's avatar
Linus Torvalds committed
108
109
110
111
112
113
114
115
116
117
118
	mod = NOFAIL(malloc(sizeof(*mod)));
	memset(mod, 0, sizeof(*mod));
	p = NOFAIL(strdup(modname));

	/* strip trailing .o */
	if ((s = strrchr(p, '.')) != NULL)
		if (strcmp(s, ".o") == 0)
			*s = '\0';

	/* add to list */
	mod->name = p;
119
	mod->gpl_compatible = -1;
Linus Torvalds's avatar
Linus Torvalds committed
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
	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;
137
138
139
	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) **/
140
	unsigned int preloaded:1;  /* 1 if symbol from Module.symvers */
141
	enum export  export;       /* Type of export */
Linus Torvalds's avatar
Linus Torvalds committed
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
	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. */
	for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++)
		value = (value + (((unsigned char *)name)[i] << (i*5 % 24)));

	return (1103515243 * value + 12345);
}

160
161
162
163
164
165
/**
 * 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)
Linus Torvalds's avatar
Linus Torvalds committed
166
167
168
169
170
171
172
173
174
175
176
{
	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 */
177
178
static struct symbol *new_symbol(const char *name, struct module *module,
				 enum export export)
Linus Torvalds's avatar
Linus Torvalds committed
179
180
181
182
183
184
185
{
	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;
186
	new->export = export;
187
	return new;
Linus Torvalds's avatar
Linus Torvalds committed
188
189
}

190
static struct symbol *find_symbol(const char *name)
Linus Torvalds's avatar
Linus Torvalds committed
191
192
193
194
195
196
197
198
199
200
201
202
203
204
{
	struct symbol *s;

	/* For our purposes, .foo matches foo.  PPC64 needs this. */
	if (name[0] == '.')
		name++;

	for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s=s->next) {
		if (strcmp(s->name, name) == 0)
			return s;
	}
	return NULL;
}

205
206
207
208
209
static struct {
	const char *str;
	enum export export;
} export_list[] = {
	{ .str = "EXPORT_SYMBOL",            .export = export_plain },
210
	{ .str = "EXPORT_UNUSED_SYMBOL",     .export = export_unused },
211
	{ .str = "EXPORT_SYMBOL_GPL",        .export = export_gpl },
212
	{ .str = "EXPORT_UNUSED_SYMBOL_GPL", .export = export_unused_gpl },
213
214
215
216
217
218
219
220
221
222
223
224
225
	{ .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;
}

static enum export export_no(const char * s)
{
	int i;
Sam Ravnborg's avatar
Sam Ravnborg committed
226
227
	if (!s)
		return export_unknown;
228
229
230
231
232
233
234
235
236
237
238
	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;
}

static enum export export_from_sec(struct elf_info *elf, Elf_Section sec)
{
	if (sec == elf->export_sec)
		return export_plain;
239
240
	else if (sec == elf->export_unused_sec)
		return export_unused;
241
242
	else if (sec == elf->export_gpl_sec)
		return export_gpl;
243
244
	else if (sec == elf->export_unused_gpl_sec)
		return export_unused_gpl;
245
246
247
248
249
250
	else if (sec == elf->export_gpl_future_sec)
		return export_gpl_future;
	else
		return export_unknown;
}

251
252
253
254
/**
 * Add an exported symbol - it may have already been added without a
 * CRC, in this case just update the CRC
 **/
255
256
static struct symbol *sym_add_exported(const char *name, struct module *mod,
				       enum export export)
Linus Torvalds's avatar
Linus Torvalds committed
257
258
259
260
{
	struct symbol *s = find_symbol(name);

	if (!s) {
261
		s = new_symbol(name, mod, export);
262
263
	} else {
		if (!s->preloaded) {
264
			warn("%s: '%s' exported twice. Previous export "
265
266
267
268
			     "was in %s%s\n", mod->name, name,
			     s->module->name,
			     is_vmlinux(s->module->name) ?"":".ko");
		}
Linus Torvalds's avatar
Linus Torvalds committed
269
	}
270
	s->preloaded = 0;
271
272
	s->vmlinux   = is_vmlinux(mod->name);
	s->kernel    = 0;
273
	s->export    = export;
274
275
276
277
	return s;
}

static void sym_update_crc(const char *name, struct module *mod,
278
			   unsigned int crc, enum export export)
279
280
281
282
{
	struct symbol *s = find_symbol(name);

	if (!s)
283
		s = new_symbol(name, mod, export);
284
285
	s->crc = crc;
	s->crc_valid = 1;
Linus Torvalds's avatar
Linus Torvalds committed
286
287
}

288
void *grab_file(const char *filename, unsigned long *size)
Linus Torvalds's avatar
Linus Torvalds committed
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
{
	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;
}

307
308
309
310
311
312
/**
  * 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.
  **/
char* get_next_line(unsigned long *pos, void *file, unsigned long size)
Linus Torvalds's avatar
Linus Torvalds committed
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
{
	static char line[4096];
	int skip = 1;
	size_t len = 0;
	signed char *p = (signed char *)file + *pos;
	char *s = line;

	for (; *pos < size ; (*pos)++)
	{
		if (skip && isspace(*p)) {
			p++;
			continue;
		}
		skip = 0;
		if (*p != '\n' && (*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;
}

342
void release_file(void *file, unsigned long size)
Linus Torvalds's avatar
Linus Torvalds committed
343
344
345
346
{
	munmap(file, size);
}

347
static int parse_elf(struct elf_info *info, const char *filename)
Linus Torvalds's avatar
Linus Torvalds committed
348
349
{
	unsigned int i;
350
	Elf_Ehdr *hdr;
Linus Torvalds's avatar
Linus Torvalds committed
351
352
353
354
355
356
	Elf_Shdr *sechdrs;
	Elf_Sym  *sym;

	hdr = grab_file(filename, &info->size);
	if (!hdr) {
		perror(filename);
357
		exit(1);
Linus Torvalds's avatar
Linus Torvalds committed
358
359
	}
	info->hdr = hdr;
360
361
362
363
364
365
366
367
368
369
370
371
	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;
	}
Linus Torvalds's avatar
Linus Torvalds committed
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
	/* Fix endianness in ELF header */
	hdr->e_shoff    = TO_NATIVE(hdr->e_shoff);
	hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx);
	hdr->e_shnum    = TO_NATIVE(hdr->e_shnum);
	hdr->e_machine  = TO_NATIVE(hdr->e_machine);
	sechdrs = (void *)hdr + hdr->e_shoff;
	info->sechdrs = sechdrs;

	/* Fix endianness in section headers */
	for (i = 0; i < hdr->e_shnum; i++) {
		sechdrs[i].sh_type   = TO_NATIVE(sechdrs[i].sh_type);
		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_name   = TO_NATIVE(sechdrs[i].sh_name);
	}
	/* Find symbol table. */
	for (i = 1; i < hdr->e_shnum; i++) {
		const char *secstrings
			= (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
392
		const char *secname;
Linus Torvalds's avatar
Linus Torvalds committed
393

394
395
396
397
		if (sechdrs[i].sh_offset > info->size) {
			fatal("%s is truncated. sechdrs[i].sh_offset=%u > sizeof(*hrd)=%ul\n", filename, (unsigned int)sechdrs[i].sh_offset, sizeof(*hdr));
			return 0;
		}
398
399
		secname = secstrings + sechdrs[i].sh_name;
		if (strcmp(secname, ".modinfo") == 0) {
Linus Torvalds's avatar
Linus Torvalds committed
400
401
			info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
			info->modinfo_len = sechdrs[i].sh_size;
402
403
		} else if (strcmp(secname, "__ksymtab") == 0)
			info->export_sec = i;
404
405
		else if (strcmp(secname, "__ksymtab_unused") == 0)
			info->export_unused_sec = i;
406
407
		else if (strcmp(secname, "__ksymtab_gpl") == 0)
			info->export_gpl_sec = i;
408
409
		else if (strcmp(secname, "__ksymtab_unused_gpl") == 0)
			info->export_unused_gpl_sec = i;
410
411
412
		else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
			info->export_gpl_future_sec = i;

Linus Torvalds's avatar
Linus Torvalds committed
413
414
415
416
		if (sechdrs[i].sh_type != SHT_SYMTAB)
			continue;

		info->symtab_start = (void *)hdr + sechdrs[i].sh_offset;
417
		info->symtab_stop  = (void *)hdr + sechdrs[i].sh_offset
Linus Torvalds's avatar
Linus Torvalds committed
418
			                         + sechdrs[i].sh_size;
419
		info->strtab       = (void *)hdr +
Linus Torvalds's avatar
Linus Torvalds committed
420
421
422
			             sechdrs[sechdrs[i].sh_link].sh_offset;
	}
	if (!info->symtab_start) {
423
		fatal("%s has no symtab?\n", filename);
Linus Torvalds's avatar
Linus Torvalds committed
424
425
426
427
428
429
430
431
	}
	/* 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);
	}
432
	return 1;
Linus Torvalds's avatar
Linus Torvalds committed
433
434
}

435
static void parse_elf_finish(struct elf_info *info)
Linus Torvalds's avatar
Linus Torvalds committed
436
437
438
439
{
	release_file(info->hdr, info->size);
}

440
441
#define CRC_PFX     MODULE_SYMBOL_PREFIX "__crc_"
#define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_"
Linus Torvalds's avatar
Linus Torvalds committed
442

443
444
static void handle_modversions(struct module *mod, struct elf_info *info,
			       Elf_Sym *sym, const char *symname)
Linus Torvalds's avatar
Linus Torvalds committed
445
446
{
	unsigned int crc;
447
	enum export export = export_from_sec(info, sym->st_shndx);
Linus Torvalds's avatar
Linus Torvalds committed
448
449
450

	switch (sym->st_shndx) {
	case SHN_COMMON:
451
		warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name);
Linus Torvalds's avatar
Linus Torvalds committed
452
453
454
455
456
		break;
	case SHN_ABS:
		/* CRC'd symbol */
		if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
			crc = (unsigned int) sym->st_value;
457
458
			sym_update_crc(symname + strlen(CRC_PFX), mod, crc,
					export);
Linus Torvalds's avatar
Linus Torvalds committed
459
460
461
462
463
464
465
466
467
468
469
470
471
		}
		break;
	case SHN_UNDEF:
		/* undefined symbol */
		if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL &&
		    ELF_ST_BIND(sym->st_info) != STB_WEAK)
			break;
		/* ignore global offset table */
		if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0)
			break;
		/* ignore __this_module, it will be resolved shortly */
		if (strcmp(symname, MODULE_SYMBOL_PREFIX "__this_module") == 0)
			break;
472
473
474
475
476
477
/* 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
Linus Torvalds's avatar
Linus Torvalds committed
478
479
480
		if (info->hdr->e_machine == EM_SPARC ||
		    info->hdr->e_machine == EM_SPARCV9) {
			/* Ignore register directives. */
481
			if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)
Linus Torvalds's avatar
Linus Torvalds committed
482
				break;
483
484
485
486
487
488
			if (symname[0] == '.') {
				char *munged = strdup(symname);
				munged[0] = '_';
				munged[1] = toupper(munged[1]);
				symname = munged;
			}
Linus Torvalds's avatar
Linus Torvalds committed
489
490
		}
#endif
491

Linus Torvalds's avatar
Linus Torvalds committed
492
493
494
495
496
497
498
499
500
501
		if (memcmp(symname, MODULE_SYMBOL_PREFIX,
			   strlen(MODULE_SYMBOL_PREFIX)) == 0)
			mod->unres = alloc_symbol(symname +
						  strlen(MODULE_SYMBOL_PREFIX),
						  ELF_ST_BIND(sym->st_info) == STB_WEAK,
						  mod->unres);
		break;
	default:
		/* All exported symbols */
		if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
502
503
			sym_add_exported(symname + strlen(KSYMTAB_PFX), mod,
					export);
Linus Torvalds's avatar
Linus Torvalds committed
504
505
506
507
508
509
510
511
512
		}
		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;
	}
}

513
514
515
/**
 * Parse tag=value strings from .modinfo section
 **/
Linus Torvalds's avatar
Linus Torvalds committed
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
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;
}

534
535
static char *get_next_modinfo(void *modinfo, unsigned long modinfo_len,
			      const char *tag, char *info)
Linus Torvalds's avatar
Linus Torvalds committed
536
537
538
539
540
{
	char *p;
	unsigned int taglen = strlen(tag);
	unsigned long size = modinfo_len;

541
542
543
544
545
	if (info) {
		size -= info - (char *)modinfo;
		modinfo = next_string(info, &size);
	}

Linus Torvalds's avatar
Linus Torvalds committed
546
547
548
549
550
551
552
	for (p = modinfo; p; p = next_string(p, &size)) {
		if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
			return p + taglen + 1;
	}
	return NULL;
}

553
554
555
556
557
558
559
static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
			 const char *tag)

{
	return get_next_modinfo(modinfo, modinfo_len, tag, NULL);
}

560
561
562
563
564
565
566
/**
 * Test if string s ends in string sub
 * return 0 if match
 **/
static int strrcmp(const char *s, const char *sub)
{
        int slen, sublen;
567

568
569
	if (!s || !sub)
		return 1;
570

571
572
	slen = strlen(s);
        sublen = strlen(sub);
573

574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
	if ((slen == 0) || (sublen == 0))
		return 1;

        if (sublen > slen)
                return 1;

        return memcmp(s + slen - sublen, sub, sublen);
}

/**
 * Whitelist to allow certain references to pass with no warning.
 * 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
592
 *   fromsec = .data*
593
 *   atsym   =__param*
594
 *
595
 * Pattern 2:
596
 *   Many drivers utilise a *driver container with references to
597
598
599
600
 *   add, remove, probe functions etc.
 *   These functions may often be marked __init and we do not want to
 *   warn here.
 *   the pattern is identified by:
601
 *   tosec   = .init.text | .exit.text | .init.data
602
 *   fromsec = .data
603
 *   atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one, *_console
604
605
 *
 * Pattern 3:
606
607
608
609
610
611
612
613
 *   Whitelist all references from .pci_fixup* section to .init.text
 *   This is part of the PCI init when built-in
 *
 * Pattern 4:
 *   Whitelist all refereces from .text.head to .init.data
 *   Whitelist all refereces from .text.head to .init.text
 *
 * Pattern 5:
614
615
616
617
618
619
620
 *   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
621
622
 *
 * Pattern 6:
623
624
625
626
627
628
 *   During the early init phase we have references from .init.text to
 *   .text we have an intended section mismatch - do not warn about it.
 *   See kernel_init() in init/main.c
 *   tosec   = .init.text
 *   fromsec = .text
 *   atsym = kernel_init
629
630
631
632
633
634
635
636
637
 *
 * Pattern 7:
 *  Logos used in drivers/video/logo reside in __initdata but the
 *  funtion that references them are EXPORT_SYMBOL() so cannot be
 *  marker __init. So we whitelist them here.
 *  The pattern is:
 *  tosec      = .init.data
 *  fromsec    = .text*
 *  refsymname = logo_
638
639
640
641
642
643
644
 *
 * Pattern 8:
 *  Symbols contained in .paravirtprobe may safely reference .init.text.
 *  The pattern is:
 *  tosec   = .init.text
 *  fromsec  = .paravirtprobe
 *
645
646
647
648
649
650
651
652
653
654
 * Pattern 9:
 *  Some of functions are common code between boot time and hotplug
 *  time. The bootmem allocater is called only boot time in its
 *  functions. So it's ok to reference.
 *  tosec    = .init.text
 *
 * Pattern 10:
 *  ia64 has machvec table for each platform. It is mixture of function
 *  pointer of .init.text and .text.
 *  fromsec  = .machvec
655
 **/
656
static int secref_whitelist(const char *modname, const char *tosec,
657
658
			    const char *fromsec, const char *atsym,
			    const char *refsymname)
659
660
661
662
{
	int f1 = 1, f2 = 1;
	const char **s;
	const char *pat2sym[] = {
663
		"driver",
664
665
		"_template", /* scsi uses *_template a lot */
		"_sht",      /* scsi also used *_sht to some extent */
666
667
668
		"_ops",
		"_probe",
		"_probe_one",
669
		"_console",
670
		"apic_es7000",
671
672
		NULL
	};
673

674
675
676
677
678
679
680
	const char *pat3refsym[] = {
		"__init_begin",
		"_sinittext",
		"_einittext",
		NULL
	};

681
682
683
684
685
686
	const char *pat4sym[] = {
		"sparse_index_alloc",
		"zone_wait_table_init",
		NULL
	};

687
688
689
	/* Check for pattern 1 */
	if (strcmp(tosec, ".init.data") != 0)
		f1 = 0;
690
	if (strncmp(fromsec, ".data", strlen(".data")) != 0)
691
692
693
694
695
696
697
698
		f1 = 0;
	if (strncmp(atsym, "__param", strlen("__param")) != 0)
		f1 = 0;

	if (f1)
		return f1;

	/* Check for pattern 2 */
699
	if ((strcmp(tosec, ".init.text") != 0) &&
700
701
	    (strcmp(tosec, ".exit.text") != 0) &&
	    (strcmp(tosec, ".init.data") != 0))
702
703
704
705
706
707
708
		f2 = 0;
	if (strcmp(fromsec, ".data") != 0)
		f2 = 0;

	for (s = pat2sym; *s; s++)
		if (strrcmp(atsym, *s) == 0)
			f1 = 1;
709
710
	if (f1 && f2)
		return 1;
711

712
713
714
715
	/* Check for pattern 3 */
	if ((strncmp(fromsec, ".pci_fixup", strlen(".pci_fixup")) == 0) &&
	    (strcmp(tosec, ".init.text") == 0))
	return 1;
716

717
	/* Check for pattern 4 */
718
719
720
721
722
723
724
725
726
727
728
	if ((strcmp(fromsec, ".text.head") == 0) &&
		((strcmp(tosec, ".init.data") == 0) ||
		(strcmp(tosec, ".init.text") == 0)))
	return 1;

	/* Check for pattern 5 */
	for (s = pat3refsym; *s; s++)
		if (strcmp(refsymname, *s) == 0)
			return 1;

	/* Check for pattern 6 */
729
730
731
	if ((strcmp(tosec, ".init.text") == 0) &&
	    (strcmp(fromsec, ".text") == 0) &&
	    (strcmp(refsymname, "kernel_init") == 0))
732
		return 1;
733

734
735
736
737
738
	/* Check for pattern 7 */
	if ((strcmp(tosec, ".init.data") == 0) &&
	    (strncmp(fromsec, ".text", strlen(".text")) == 0) &&
	    (strncmp(refsymname, "logo_", strlen("logo_")) == 0))
		return 1;
739
740
741
742

	/* Check for pattern 8 */
	if ((strcmp(tosec, ".init.text") == 0) &&
	    (strcmp(fromsec, ".paravirtprobe") == 0))
743
744
		return 1;

745
746
747
748
749
750
751
752
753
754
755
	/* Check for pattern 9 */
	if ((strcmp(tosec, ".init.text") == 0) &&
	    (strcmp(fromsec, ".text") == 0))
		for (s = pat4sym; *s; s++)
			if (strcmp(atsym, *s) == 0)
				return 1;

	/* Check for pattern 10 */
	if (strcmp(fromsec, ".machvec") == 0)
		return 1;

756
	return 0;
757
758
}

759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
/**
 * 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.
 *  **/
static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf_Addr addr,
				Elf_Sym *relsym)
{
	Elf_Sym *sym;

	if (relsym->st_name != 0)
		return relsym;
	for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
		if (sym->st_shndx != relsym->st_shndx)
			continue;
		if (sym->st_value == addr)
			return sym;
	}
	return NULL;
}

782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
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);
}

806
/*
807
808
809
810
 * 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.
811
812
813
814
815
816
817
818
819
820
821
 **/
static void find_symbols_between(struct elf_info *elf, Elf_Addr addr,
				 const char *sec,
			         Elf_Sym **before, Elf_Sym **after)
{
	Elf_Sym *sym;
	Elf_Ehdr *hdr = elf->hdr;
	Elf_Addr beforediff = ~0;
	Elf_Addr afterdiff = ~0;
	const char *secstrings = (void *)hdr +
				 elf->sechdrs[hdr->e_shstrndx].sh_offset;
822

823
824
825
826
827
828
829
830
831
832
833
	*before = NULL;
	*after = NULL;

	for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
		const char *symsec;

		if (sym->st_shndx >= SHN_LORESERVE)
			continue;
		symsec = secstrings + elf->sechdrs[sym->st_shndx].sh_name;
		if (strcmp(symsec, sec) != 0)
			continue;
834
835
		if (!is_valid_name(elf, sym))
			continue;
836
837
838
839
840
		if (sym->st_value <= addr) {
			if ((addr - sym->st_value) < beforediff) {
				beforediff = addr - sym->st_value;
				*before = sym;
			}
841
			else if ((addr - sym->st_value) == beforediff) {
842
				*before = sym;
843
			}
844
845
846
847
848
849
850
		}
		else
		{
			if ((sym->st_value - addr) < afterdiff) {
				afterdiff = sym->st_value - addr;
				*after = sym;
			}
851
			else if ((sym->st_value - addr) == afterdiff) {
852
				*after = sym;
853
			}
854
855
856
857
858
859
860
		}
	}
}

/**
 * Print a warning about a section mismatch.
 * Try to find symbols near it so user can find it.
861
 * Check whitelist before warning - it may be a false positive.
862
863
864
865
 **/
static void warn_sec_mismatch(const char *modname, const char *fromsec,
			      struct elf_info *elf, Elf_Sym *sym, Elf_Rela r)
{
866
867
868
	const char *refsymname = "";
	Elf_Sym *before, *after;
	Elf_Sym *refsym;
869
870
871
872
873
	Elf_Ehdr *hdr = elf->hdr;
	Elf_Shdr *sechdrs = elf->sechdrs;
	const char *secstrings = (void *)hdr +
				 sechdrs[hdr->e_shstrndx].sh_offset;
	const char *secname = secstrings + sechdrs[sym->st_shndx].sh_name;
874

875
876
	find_symbols_between(elf, r.r_offset, fromsec, &before, &after);

877
878
879
	refsym = find_elf_symbol(elf, r.r_addend, sym);
	if (refsym && strlen(elf->strtab + refsym->st_name))
		refsymname = elf->strtab + refsym->st_name;
880
881

	/* check whitelist - we may ignore it */
882
	if (before &&
883
	    secref_whitelist(modname, secname, fromsec,
884
			     elf->strtab + before->st_name, refsymname))
885
		return;
886

887
	if (before && after) {
888
889
890
		warn("%s - Section mismatch: reference to %s:%s from %s "
		     "between '%s' (at offset 0x%llx) and '%s'\n",
		     modname, secname, refsymname, fromsec,
891
		     elf->strtab + before->st_name,
892
		     (long long)r.r_offset,
893
894
		     elf->strtab + after->st_name);
	} else if (before) {
895
896
		warn("%s - Section mismatch: reference to %s:%s from %s "
		     "after '%s' (at offset 0x%llx)\n",
897
		     modname, secname, refsymname, fromsec,
898
		     elf->strtab + before->st_name,
899
		     (long long)r.r_offset);
900
	} else if (after) {
901
902
		warn("%s - Section mismatch: reference to %s:%s from %s "
		     "before '%s' (at offset -0x%llx)\n",
903
		     modname, secname, refsymname, fromsec,
904
		     elf->strtab + after->st_name,
905
		     (long long)r.r_offset);
906
	} else {
907
908
909
910
		warn("%s - Section mismatch: reference to %s:%s from %s "
		     "(offset 0x%llx)\n",
		     modname, secname, fromsec, refsymname,
		     (long long)r.r_offset);
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
	}
}

/**
 * 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
 * only when a moduel is unloaded which never happes for built-in modules.
 * 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,
			  struct elf_info *elf,
			  int section(const char*),
			  int section_ref_ok(const char *))
{
	int i;
	Elf_Sym  *sym;
	Elf_Ehdr *hdr = elf->hdr;
	Elf_Shdr *sechdrs = elf->sechdrs;
	const char *secstrings = (void *)hdr +
				 sechdrs[hdr->e_shstrndx].sh_offset;
937

938
939
	/* Walk through all sections */
	for (i = 0; i < hdr->e_shnum; i++) {
940
941
942
		const char *name = secstrings + sechdrs[i].sh_name;
		const char *secname;
		Elf_Rela r;
943
		unsigned int r_sym;
944
		/* We want to process only relocation sections and not .init */
945
946
947
948
949
950
951
		if (sechdrs[i].sh_type == SHT_RELA) {
			Elf_Rela *rela;
			Elf_Rela *start = (void *)hdr + sechdrs[i].sh_offset;
			Elf_Rela *stop  = (void*)start + sechdrs[i].sh_size;
			name += strlen(".rela");
			if (section_ref_ok(name))
				continue;
952

953
954
			for (rela = start; rela < stop; rela++) {
				r.r_offset = TO_NATIVE(rela->r_offset);
955
956
957
958
959
960
961
962
963
964
965
966
#if KERNEL_ELFCLASS == ELFCLASS64
				if (hdr->e_machine == EM_MIPS) {
					r_sym = ELF64_MIPS_R_SYM(rela->r_info);
					r_sym = TO_NATIVE(r_sym);
				} 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
967
				r.r_addend = TO_NATIVE(rela->r_addend);
968
				sym = elf->symtab_start + r_sym;
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
				/* Skip special sections */
				if (sym->st_shndx >= SHN_LORESERVE)
					continue;

				secname = secstrings +
					sechdrs[sym->st_shndx].sh_name;
				if (section(secname))
					warn_sec_mismatch(modname, name,
							  elf, sym, r);
			}
		} else if (sechdrs[i].sh_type == SHT_REL) {
			Elf_Rel *rel;
			Elf_Rel *start = (void *)hdr + sechdrs[i].sh_offset;
			Elf_Rel *stop  = (void*)start + sechdrs[i].sh_size;
			name += strlen(".rel");
			if (section_ref_ok(name))
985
986
				continue;

987
988
			for (rel = start; rel < stop; rel++) {
				r.r_offset = TO_NATIVE(rel->r_offset);
989
990
991
992
993
994
995
996
997
998
999
1000
#if KERNEL_ELFCLASS == ELFCLASS64
				if (hdr->e_machine == EM_MIPS) {
					r_sym = ELF64_MIPS_R_SYM(rel->r_info);
					r_sym = TO_NATIVE(r_sym);
				} 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
For faster browsing, not all history is shown. View entire blame