aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/boot
diff options
context:
space:
mode:
authorVivek Goyal <vgoyal@in.ibm.com>2006-12-06 20:14:04 -0500
committerAndi Kleen <andi@basil.nowhere.org>2006-12-06 20:14:04 -0500
commit6a044b3a0a1829ef19bb29548ffe553f48e8d80c (patch)
tree47e55193ddfd36cd4564cd0f6794e9568c390b08 /arch/i386/boot
parent968de4f02621db35b8ae5239c8cfc6664fb872d8 (diff)
[PATCH] i386: Warn upon absolute relocations being present
o Relocations generated w.r.t absolute symbols are not processed as by definition, absolute symbols are not to be relocated. Explicitly warn user about absolutions relocations present at compile time. o These relocations get introduced either due to linker optimizations or some programming oversights. o Also create a list of symbols which have been audited to be safe and don't emit warnings for these. Signed-off-by: Vivek Goyal <vgoyal@in.ibm.com> Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/i386/boot')
-rw-r--r--arch/i386/boot/compressed/Makefile2
-rw-r--r--arch/i386/boot/compressed/relocs.c82
2 files changed, 73 insertions, 11 deletions
diff --git a/arch/i386/boot/compressed/Makefile b/arch/i386/boot/compressed/Makefile
index cc28da3a881e..a661217f33ec 100644
--- a/arch/i386/boot/compressed/Makefile
+++ b/arch/i386/boot/compressed/Makefile
@@ -20,7 +20,7 @@ $(obj)/vmlinux.bin: vmlinux FORCE
20 $(call if_changed,objcopy) 20 $(call if_changed,objcopy)
21 21
22quiet_cmd_relocs = RELOCS $@ 22quiet_cmd_relocs = RELOCS $@
23 cmd_relocs = $(obj)/relocs $< > $@ 23 cmd_relocs = $(obj)/relocs $< > $@;$(obj)/relocs --abs-relocs $<
24$(obj)/vmlinux.relocs: vmlinux $(obj)/relocs FORCE 24$(obj)/vmlinux.relocs: vmlinux $(obj)/relocs FORCE
25 $(call if_changed,relocs) 25 $(call if_changed,relocs)
26 26
diff --git a/arch/i386/boot/compressed/relocs.c b/arch/i386/boot/compressed/relocs.c
index 0551ceb21bed..468da89153c4 100644
--- a/arch/i386/boot/compressed/relocs.c
+++ b/arch/i386/boot/compressed/relocs.c
@@ -19,6 +19,33 @@ static char *strtab[MAX_SHDRS];
19static unsigned long reloc_count, reloc_idx; 19static unsigned long reloc_count, reloc_idx;
20static unsigned long *relocs; 20static unsigned long *relocs;
21 21
22/*
23 * Following symbols have been audited. There values are constant and do
24 * not change if bzImage is loaded at a different physical address than
25 * the address for which it has been compiled. Don't warn user about
26 * absolute relocations present w.r.t these symbols.
27 */
28static const char* safe_abs_relocs[] = {
29 "__kernel_vsyscall",
30 "__kernel_rt_sigreturn",
31 "__kernel_sigreturn",
32 "SYSENTER_RETURN",
33};
34
35static int is_safe_abs_reloc(const char* sym_name)
36{
37 int i, array_size;
38
39 array_size = sizeof(safe_abs_relocs)/sizeof(char*);
40
41 for(i = 0; i < array_size; i++) {
42 if (!strcmp(sym_name, safe_abs_relocs[i]))
43 /* Match found */
44 return 1;
45 }
46 return 0;
47}
48
22static void die(char *fmt, ...) 49static void die(char *fmt, ...)
23{ 50{
24 va_list ap; 51 va_list ap;
@@ -359,9 +386,8 @@ static void print_absolute_symbols(void)
359 386
360static void print_absolute_relocs(void) 387static void print_absolute_relocs(void)
361{ 388{
362 int i; 389 int i, printed = 0;
363 printf("Absolute relocations\n"); 390
364 printf("Offset Info Type Sym.Value Sym.Name\n");
365 for(i = 0; i < ehdr.e_shnum; i++) { 391 for(i = 0; i < ehdr.e_shnum; i++) {
366 char *sym_strtab; 392 char *sym_strtab;
367 Elf32_Sym *sh_symtab; 393 Elf32_Sym *sh_symtab;
@@ -387,6 +413,31 @@ static void print_absolute_relocs(void)
387 if (sym->st_shndx != SHN_ABS) { 413 if (sym->st_shndx != SHN_ABS) {
388 continue; 414 continue;
389 } 415 }
416
417 /* Absolute symbols are not relocated if bzImage is
418 * loaded at a non-compiled address. Display a warning
419 * to user at compile time about the absolute
420 * relocations present.
421 *
422 * User need to audit the code to make sure
423 * some symbols which should have been section
424 * relative have not become absolute because of some
425 * linker optimization or wrong programming usage.
426 *
427 * Before warning check if this absolute symbol
428 * relocation is harmless.
429 */
430 if (is_safe_abs_reloc(name))
431 continue;
432
433 if (!printed) {
434 printf("WARNING: Absolute relocations"
435 " present\n");
436 printf("Offset Info Type Sym.Value "
437 "Sym.Name\n");
438 printed = 1;
439 }
440
390 printf("%08x %08x %10s %08x %s\n", 441 printf("%08x %08x %10s %08x %s\n",
391 rel->r_offset, 442 rel->r_offset,
392 rel->r_info, 443 rel->r_info,
@@ -395,7 +446,9 @@ static void print_absolute_relocs(void)
395 name); 446 name);
396 } 447 }
397 } 448 }
398 printf("\n"); 449
450 if (printed)
451 printf("\n");
399} 452}
400 453
401static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym)) 454static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym))
@@ -508,25 +561,31 @@ static void emit_relocs(int as_text)
508 561
509static void usage(void) 562static void usage(void)
510{ 563{
511 die("i386_reloc [--abs | --text] vmlinux\n"); 564 die("relocs [--abs-syms |--abs-relocs | --text] vmlinux\n");
512} 565}
513 566
514int main(int argc, char **argv) 567int main(int argc, char **argv)
515{ 568{
516 int show_absolute; 569 int show_absolute_syms, show_absolute_relocs;
517 int as_text; 570 int as_text;
518 const char *fname; 571 const char *fname;
519 FILE *fp; 572 FILE *fp;
520 int i; 573 int i;
521 574
522 show_absolute = 0; 575 show_absolute_syms = 0;
576 show_absolute_relocs = 0;
523 as_text = 0; 577 as_text = 0;
524 fname = NULL; 578 fname = NULL;
525 for(i = 1; i < argc; i++) { 579 for(i = 1; i < argc; i++) {
526 char *arg = argv[i]; 580 char *arg = argv[i];
527 if (*arg == '-') { 581 if (*arg == '-') {
528 if (strcmp(argv[1], "--abs") == 0) { 582 if (strcmp(argv[1], "--abs-syms") == 0) {
529 show_absolute = 1; 583 show_absolute_syms = 1;
584 continue;
585 }
586
587 if (strcmp(argv[1], "--abs-relocs") == 0) {
588 show_absolute_relocs = 1;
530 continue; 589 continue;
531 } 590 }
532 else if (strcmp(argv[1], "--text") == 0) { 591 else if (strcmp(argv[1], "--text") == 0) {
@@ -553,8 +612,11 @@ int main(int argc, char **argv)
553 read_strtabs(fp); 612 read_strtabs(fp);
554 read_symtabs(fp); 613 read_symtabs(fp);
555 read_relocs(fp); 614 read_relocs(fp);
556 if (show_absolute) { 615 if (show_absolute_syms) {
557 print_absolute_symbols(); 616 print_absolute_symbols();
617 return 0;
618 }
619 if (show_absolute_relocs) {
558 print_absolute_relocs(); 620 print_absolute_relocs();
559 return 0; 621 return 0;
560 } 622 }