Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc: Check for unsupported relocs when using CONFIG_RELOCATABLE

When using CONFIG_RELOCATABLE, we build the kernel as a position
independent executable. The kernel then uses a little bit of relocation
code to relocate itself. That code only deals with R_PPC64_RELATIVE
relocations though. If for some reason you use assembly constructs
such as LOAD_REG_IMMEDIATE() to load the address of a symbol, you'll
generate different kinds of relocations that won't be processed properly
and bad things will happen. (We have 2 such bugs today).

The perl script tries to filter out "known" bad ones. It's possible
that we are missing some in the case of a weak function that nobody
implements, we'll see if we get false positive and fix it.

Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

authored by

Tony Breeds and committed by
Benjamin Herrenschmidt
144ef909 ad08587e

+67
+11
arch/powerpc/Makefile
··· 164 164 165 165 boot := arch/$(ARCH)/boot 166 166 167 + ifeq ($(CONFIG_RELOCATABLE),y) 168 + quiet_cmd_relocs_check = CALL $< 169 + cmd_relocs_check = perl $< "$(OBJDUMP)" "$(obj)/vmlinux" 170 + 171 + PHONY += relocs_check 172 + relocs_check: arch/powerpc/relocs_check.pl vmlinux 173 + $(call cmd,relocs_check) 174 + 175 + zImage: relocs_check 176 + endif 177 + 167 178 $(BOOT_TARGETS): vmlinux 168 179 $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@) 169 180
+56
arch/powerpc/relocs_check.pl
··· 1 + #!/usr/bin/perl 2 + 3 + # Copyright © 2009 IBM Corporation 4 + 5 + # This program is free software; you can redistribute it and/or 6 + # modify it under the terms of the GNU General Public License 7 + # as published by the Free Software Foundation; either version 8 + # 2 of the License, or (at your option) any later version. 9 + 10 + # This script checks the relcoations of a vmlinux for "suspicious" 11 + # relocations. 12 + 13 + use strict; 14 + use warnings; 15 + 16 + if ($#ARGV != 1) { 17 + die "$0 [path to objdump] [path to vmlinux]\n"; 18 + } 19 + 20 + # Have Kbuild supply the path to objdump so we handle cross compilation. 21 + my $objdump = shift; 22 + my $vmlinux = shift; 23 + my $bad_relocs_count = 0; 24 + my $bad_relocs = ""; 25 + my $old_binutils = 0; 26 + 27 + open(FD, "$objdump -R $vmlinux|") or die; 28 + while (<FD>) { 29 + study $_; 30 + 31 + # Only look at relcoation lines. 32 + next if (!/\s+R_/); 33 + 34 + # These relocations are okay 35 + next if (/R_PPC64_RELATIVE/ or /R_PPC64_NONE/ or 36 + /R_PPC64_ADDR64\s+mach_/); 37 + 38 + # If we see this type of relcoation it's an idication that 39 + # we /may/ be using an old version of binutils. 40 + if (/R_PPC64_UADDR64/) { 41 + $old_binutils++; 42 + } 43 + 44 + $bad_relocs_count++; 45 + $bad_relocs .= $_; 46 + } 47 + 48 + if ($bad_relocs_count) { 49 + print "WARNING: $bad_relocs_count bad relocations\n"; 50 + print $bad_relocs; 51 + } 52 + 53 + if ($old_binutils) { 54 + print "WARNING: You need at binutils >= 2.19 to build a ". 55 + "CONFIG_RELCOATABLE kernel\n"; 56 + }