GIT ecb0727bbc95c81cc60b76c51e2bc914d04de80c git+ssh://master.kernel.org/pub/scm/linux/kernel/git/sam/kbuild.git commit Author: Sam Ravnborg Date: Sun Jun 3 22:19:24 2007 +0200 kbuild: whitelist references from variables named _timer to .init.text arm uses a lot of ops structures named *_timer that has legitimite references to .init.text. So let's add this variable to the list of variables that may reference .init.text without causing any warning. Signed-off-by: Sam Ravnborg commit 40a7ded7e7ea111596058bee7e386d656fb568f6 Author: Sam Ravnborg Date: Sun Jun 3 00:47:53 2007 +0200 kbuild: remove hardcoded _logo names from modpost Replaced this with a __init_refok marker in front of fb_find_logo(). I think that the __initdata marker for the logo's are wrong but I have not justified this so I did not remove it. Signed-off-by: Sam Ravnborg commit 402c06644f9ec212940f408538656dded4af7e01 Author: Sam Ravnborg Date: Sun Jun 3 00:41:22 2007 +0200 kbuild: refactor code in modpost Move more checks from whitelist to the section check functions Renumber the patterns. No functional changes. Signed-off-by: Sam Ravnborg commit f0c694cb28c1e378be3b89753952e2f6d19a457c Author: Sam Ravnborg Date: Sun Jun 3 00:05:10 2007 +0200 kbuild: remove hardcoded apic_es7000 from modpost Replace the hardcoded variable name apic_es7000 in modpost with a __initdata_refok marker. Signed-off-by: Sam Ravnborg commit c8bb3b7bdccb66748056f4164a96b4ed4ce5020c Author: Sam Ravnborg Date: Sat Jun 2 21:29:20 2007 +0200 kbuild: warn about references from .init.text to .exit.text The .exit.text section may be discarded either at build or at runtime. So let modpost warn if this situation is detected. Signed-off-by: Sam Ravnborg commit 39e78f691055284edc8f50de98add0a70bd73346 Author: Sam Ravnborg Date: Sat Jun 2 21:18:51 2007 +0200 kbuild: refactor code in modpost to improve maintainability There were a great deal of overlap between the two functions that check which sections may reference .init.text and .exit.text. Factor out common check to a separate function and sort entries in the original functions. Signed-off-by: Sam Ravnborg commit dddc53f08e6c3296ede83113a17810b07a7cf55c Author: Sam Ravnborg Date: Tue May 29 23:09:35 2007 +0200 kbuild: ignore section mismatch warnings originating from .note section .note* sections are ELF notes, which are typically used by external tools to examine the kernel image. Since this is removed from any runtime consideration, it's OK to reference any section from a .note* section. Signed-off-by: Jeremy Fitzhardinge Cc: "Eric W. Biederman" Signed-off-by: Sam Ravnborg commit 7ef63e796bd297c2420e363a5a49b49f8b89f202 Author: Jeremy Fitzhardinge Date: Tue May 29 13:33:01 2007 -0700 kbuild: The .paravirtprobe section is obsolete, so modpost doesn't need to handle it The .paravirtprobe section is obsolete, so modpost doesn't need to handle it. Signed-off-by: Jeremy Fitzhardinge Cc: Rusty Russell Signed-off-by: Sam Ravnborg commit 552f07b650ab3c6dc6a97906e4ba57e492bf9e5e Author: Mike Frysinger Date: Thu May 10 22:44:28 2007 -0700 kbuild: add support for squashing uid/gid in gen_initramfs_list.sh Sometimes it is useful to squash all uid's/gid's to 0:0 regardless of current owner. For example, in build systems that get run as arbitrary users (uClinux-dist). This adds a special "squash" keyword so you can do '-g squash -u squash' and have ownership squashed to root. Signed-off-by: Mike Frysinger Cc: Sam Ravnborg Signed-off-by: Andrew Morton commit 19d9192dfc35e193a7a39c5ee2f0878fd8caf080 Author: Mike Frysinger Date: Thu May 10 22:44:28 2007 -0700 kbuild: add support for reading stdin with gen_init_cpio Treat an argument of "-" as meaning "read stdin for cpio files" so gen_init_cpio can be piped into. Signed-off-by: Mike Frysinger Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg commit 2bca8c8dedc0597b412ad46d232e45a18c074e85 Author: Mike Frysinger Date: Wed May 23 21:37:45 2007 -0400 kconfig: use POSIX equality test in check-lxdialog.sh The "==" operator is not in POSIX, so use -eq instead. Signed-off-by: Mike Frysinger Signed-off-by: Sam Ravnborg commit ffb9d6ce35bd6802ac1a478191aa4bcf2ade27af Author: H. Peter Anvin Date: Fri May 25 17:58:26 2007 -0700 scripts: Make cleanfile/cleanpatch warn about long lines Make the "cleanfile" and "cleanpatch" script warn about long lines, by default lines whose visual width exceeds 79 characters. Per suggestion from Auke Kok. Signed-off-by: H. Peter Anvin Signed-off-by: Sam Ravnborg commit 82509b3adfdbcce782e373a5d242bb00f8959a36 Author: Sam Ravnborg Date: Mon May 28 22:47:48 2007 +0200 kbuild: avoid environment to set variables used by kbuild A few of the variables used by kbuild has fixed naming. Make sure we do not pick up random values from the environment. Signed-off-by: Sam Ravnborg commit de03ae14551885cb2af73f85325e39351a1ce572 Author: Stephen Rothwell Date: Thu May 24 14:16:13 2007 +1000 kbuild: suppress modpost warnings for references from the .toc section as used by powerpc We should do better here by effetively "dereferencing" references to the .toc (or the .got2) section, but that is much harder. Signed-off-by: Stephen Rothwell Signed-off-by: Sam Ravnborg commit 0c85adfa564a0285ea5087fd1c63c191ca238a39 Author: Sam Ravnborg Date: Mon May 28 22:26:55 2007 +0200 kbuild: document cc-fullversion Signed-off-by: Sam Ravnborg commit 97f7b410024c4ef9ebe706b459e25adf80095412 Author: Segher Boessenkool Date: Sat May 19 18:49:08 2007 +0200 powerpc: Refuse to build 64-bit with GCC-4.2.0 and CONFIG_MODULES ...since this won't work (compiler bug, see ). Signed-off-by: Segher Boessenkool Signed-off-by: Sam Ravnborg commit 14ac6846ff8bd6cdc8bfcac329dc078eefd34075 Author: Segher Boessenkool Date: Sat May 19 18:49:07 2007 +0200 kbuild: New 'cc-fullversion' macro Prints a six-digit string including the GCC patchlevel. Also fix the 'usage' comment for cc-version. Signed-off-by: Segher Boessenkool Signed-off-by: Sam Ravnborg commit a17daff39c8edeadce990c9c590ce371a316cb40 Author: Atsushi Nemoto Date: Tue May 22 18:27:39 2007 +0900 kbuild: make better section mismatch reports on i386, arm and mips On i386, ARM and MIPS, warn_sec_mismatch() sometimes fails to show usefull symbol name. This is because empty 'refsym' due to 0 r_addend value. This patch is to adjust r_addend value, consulting with apply_relocate() routine in kernel code. Signed-off-by: Atsushi Nemoto Signed-off-by: Sam Ravnborg commit 12a1ba78ededb51e8b52d23a5e324141d06d3d29 Author: Sam Ravnborg Date: Mon May 28 22:14:37 2007 +0200 kbuild: asm-offsets.h is now cleaned with O=.. builds Reported by: "Robert P. J. Day" Signed-off-by: Sam Ravnborg Cc: "Robert P. J. Day" Documentation/kbuild/makefiles.txt | 14 + Kbuild | 1 arch/i386/mach-generic/es7000.c | 2 arch/powerpc/Makefile | 8 + drivers/video/logo/logo.c | 7 - scripts/Kbuild.include | 7 + scripts/Makefile.build | 16 ++ scripts/cleanfile | 54 +++++ scripts/cleanpatch | 58 +++++- scripts/gcc-version.sh | 15 + scripts/gen_initramfs_list.sh | 12 + scripts/kconfig/lxdialog/check-lxdialog.sh | 2 scripts/mod/modpost.c | 281 ++++++++++++++++------------ scripts/mod/modpost.h | 3 usr/gen_init_cpio.c | 4 15 files changed, 345 insertions(+), 139 deletions(-) diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt index bb5306e..c6d9a35 100644 --- a/Documentation/kbuild/makefiles.txt +++ b/Documentation/kbuild/makefiles.txt @@ -501,6 +501,20 @@ more details, with real examples. The third parameter may be a text as in this example, but it may also be an expanded variable or a macro. + cc-fullversion + cc-fullversion is usefull when the exact version of gcc is needed. + One typical use-case is when a specific GCC version is broken. + cc-fullversion points out a more specific version than cc-version does. + + Example: + #arch/powerpc/Makefile + $(Q)if test "$(call cc-fullversion)" = "040200" ; then \ + echo -n '*** GCC-4.2.0 cannot compile the 64-bit powerpc ' ; \ + false ; \ + fi + + In this example for a specific GCC version the build will error out explaining + the user why it stops. === 4 Host Program support diff --git a/Kbuild b/Kbuild index 163f8cb..56b8edf 100644 --- a/Kbuild +++ b/Kbuild @@ -13,6 +13,7 @@ offsets-file := include/asm-$(ARCH)/asm- always := $(offsets-file) targets := $(offsets-file) targets += arch/$(ARCH)/kernel/asm-offsets.s +clean-files := $(addprefix $(objtree)/,$(targets)) # Default sed regexp - multiline due to syntax constraints define sed-y diff --git a/arch/i386/mach-generic/es7000.c b/arch/i386/mach-generic/es7000.c index b47f951..4742626 100644 --- a/arch/i386/mach-generic/es7000.c +++ b/arch/i386/mach-generic/es7000.c @@ -66,4 +66,4 @@ static int __init acpi_madt_oem_check(ch } #endif -struct genapic apic_es7000 = APIC_INIT("es7000", probe_es7000); +struct genapic __initdata_refok apic_es7000 = APIC_INIT("es7000", probe_es7000); diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index fbafd96..85be605 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -201,6 +201,14 @@ checkbin: false; \ fi ; \ fi + @if test "$(call cc-fullversion)" = "040200" \ + && test "x${CONFIG_MODULES}${CONFIG_PPC64}" = "xyy" ; then \ + echo -n '*** GCC-4.2.0 cannot compile the 64-bit powerpc ' ; \ + echo 'kernel with modules enabled.' ; \ + echo -n '*** Please use a different GCC version or ' ; \ + echo 'disable kernel modules' ; \ + false ; \ + fi @if ! /bin/echo dssall | $(AS) -many -o $(TOUT) >/dev/null 2>&1 ; then \ echo -n '*** ${VERSION}.${PATCHLEVEL} kernels no longer build ' ; \ echo 'correctly with old versions of binutils.' ; \ diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c index 80c0361..2b0f799 100644 --- a/drivers/video/logo/logo.c +++ b/drivers/video/logo/logo.c @@ -34,8 +34,11 @@ extern const struct linux_logo logo_supe extern const struct linux_logo logo_superh_clut224; extern const struct linux_logo logo_m32r_clut224; - -const struct linux_logo *fb_find_logo(int depth) +/* logo's are marked __initdata. Use __init_refok to tell + * modpost that it is intended that this function uses data + * marked __initdata. + */ +const struct linux_logo * __init_refok fb_find_logo(int depth) { const struct linux_logo *logo = NULL; diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 06c1a37..677bc6c 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -100,9 +100,14 @@ cc-option-align = $(subst -functions=0,, $(call cc-option,-falign-functions=0,-malign-functions=0)) # cc-version -# Usage gcc-ver := $(call cc-version,$(CC)) +# Usage gcc-ver := $(call cc-version) cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CC)) +# cc-fullversion +# Usage gcc-ver := $(call cc-fullversion) +cc-fullversion = $(shell $(CONFIG_SHELL) \ + $(srctree)/scripts/gcc-version.sh -p $(CC)) + # cc-ifversion # Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1) cc-ifversion = $(shell [ $(call cc-version, $(CC)) $(1) $(2) ] && echo $(3)) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index a525112..3f7b451 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -7,6 +7,22 @@ src := $(obj) PHONY := __build __build: +# Init all relevant variables used in kbuild files so +# 1) they have correct type +# 2) they do not inherit any value from the environment +obj-y := +obj-m := +lib-y := +lib-m := +always := +targets := +subdir-y := +subdir-m := +EXTRA_AFLAGS := +EXTRA_CFLAGS := +EXTRA_CPPFLAGS := +EXTRA_LDFLAGS := + # Read .config if it exist, otherwise ignore -include include/config/auto.conf diff --git a/scripts/cleanfile b/scripts/cleanfile index f1ba8aa..cefd29e 100755 --- a/scripts/cleanfile +++ b/scripts/cleanfile @@ -7,7 +7,9 @@ # use bytes; use File::Basename; -# +# Default options +$max_width = 79; + # Clean up space-tab sequences, either by removing spaces or # replacing them with tabs. sub clean_space_tabs($) @@ -48,9 +50,49 @@ sub clean_space_tabs($) return $lo; } +# Compute the visual width of a string +sub strwidth($) { + no bytes; # Tab alignment depends on characters + + my($li) = @_; + my($c, $i); + my $pos = 0; + my $mlen = 0; + + for ($i = 0; $i < length($li); $i++) { + $c = substr($li,$i,1); + if ($c eq "\t") { + $pos = ($pos+8) & ~7; + } elsif ($c eq "\n") { + $mlen = $pos if ($pos > $mlen); + $pos = 0; + } else { + $pos++; + } + } + + $mlen = $pos if ($pos > $mlen); + return $mlen; +} + $name = basename($0); -foreach $f ( @ARGV ) { +@files = (); + +while (defined($a = shift(@ARGV))) { + if ($a =~ /^-/) { + if ($a eq '-width' || $a eq '-w') { + $max_width = shift(@ARGV)+0; + } else { + print STDERR "Usage: $name [-width #] files...\n"; + exit 1; + } + } else { + push(@files, $a); + } +} + +foreach $f ( @files ) { print STDERR "$name: $f\n"; if (! -f $f) { @@ -90,8 +132,10 @@ foreach $f ( @ARGV ) { @blanks = (); @lines = (); + $lineno = 0; while ( defined($line = ) ) { + $lineno++; $in_bytes += length($line); $line =~ s/[ \t\r]*$//; # Remove trailing spaces $line = clean_space_tabs($line); @@ -107,6 +151,12 @@ foreach $f ( @ARGV ) { @blanks = (); $blank_bytes = 0; } + + $l_width = strwidth($line); + if ($max_width && $l_width > $max_width) { + print STDERR + "$f:$lineno: line exceeds $max_width characters ($l_width)\n"; + } } # Any blanks at the end of the file are discarded diff --git a/scripts/cleanpatch b/scripts/cleanpatch index a53f987..9680d03 100755 --- a/scripts/cleanpatch +++ b/scripts/cleanpatch @@ -7,7 +7,9 @@ # use bytes; use File::Basename; -# +# Default options +$max_width = 79; + # Clean up space-tab sequences, either by removing spaces or # replacing them with tabs. sub clean_space_tabs($) @@ -48,9 +50,49 @@ sub clean_space_tabs($) return $lo; } +# Compute the visual width of a string +sub strwidth($) { + no bytes; # Tab alignment depends on characters + + my($li) = @_; + my($c, $i); + my $pos = 0; + my $mlen = 0; + + for ($i = 0; $i < length($li); $i++) { + $c = substr($li,$i,1); + if ($c eq "\t") { + $pos = ($pos+8) & ~7; + } elsif ($c eq "\n") { + $mlen = $pos if ($pos > $mlen); + $pos = 0; + } else { + $pos++; + } + } + + $mlen = $pos if ($pos > $mlen); + return $mlen; +} + $name = basename($0); -foreach $f ( @ARGV ) { +@files = (); + +while (defined($a = shift(@ARGV))) { + if ($a =~ /^-/) { + if ($a eq '-width' || $a eq '-w') { + $max_width = shift(@ARGV)+0; + } else { + print STDERR "Usage: $name [-width #] files...\n"; + exit 1; + } + } else { + push(@files, $a); + } +} + +foreach $f ( @files ) { print STDERR "$name: $f\n"; if (! -f $f) { @@ -86,6 +128,7 @@ foreach $f ( @ARGV ) { $in_bytes = 0; $out_bytes = 0; + $lineno = 0; @lines = (); @@ -93,10 +136,12 @@ foreach $f ( @ARGV ) { $err = 0; while ( defined($line = ) ) { + $lineno++; $in_bytes += length($line); if (!$in_hunk) { - if ($line =~ /^\@\@\s+\-([0-9]+),([0-9]+)\s+\+([0-9]+),([0-9]+)\s\@\@/) { + if ($line =~ + /^\@\@\s+\-([0-9]+),([0-9]+)\s+\+([0-9]+),([0-9]+)\s\@\@/) { $minus_lines = $2; $plus_lines = $4; if ($minus_lines || $plus_lines) { @@ -117,6 +162,13 @@ foreach $f ( @ARGV ) { $text =~ s/[ \t\r]*$//; # Remove trailing spaces $text = clean_space_tabs($text); + $l_width = strwidth($text); + if ($max_width && $l_width > $max_width) { + print STDERR + "$f:$lineno: adds line exceeds $max_width ", + "characters ($l_width)\n"; + } + push(@hunk_lines, '+'.$text); } elsif ($line =~ /^\-/) { $minus_lines--; diff --git a/scripts/gcc-version.sh b/scripts/gcc-version.sh index bb4fbea..8a1d187 100644 --- a/scripts/gcc-version.sh +++ b/scripts/gcc-version.sh @@ -1,14 +1,23 @@ #!/bin/sh # -# gcc-version gcc-command +# gcc-version [-p] gcc-command # # Prints the gcc version of `gcc-command' in a canonical 4-digit form # such as `0295' for gcc-2.95, `0303' for gcc-3.3, etc. # +# With the -p option, prints the patchlevel as well, for example `029503' for +# gcc-2.95.3, `030301' for gcc-3.3.1, etc. +# + +if [ $1 = "-p" ] ; then with_patchlevel=1; shift; fi compiler="$*" MAJOR=$(echo __GNUC__ | $compiler -E -xc - | tail -n 1) MINOR=$(echo __GNUC_MINOR__ | $compiler -E -xc - | tail -n 1) -printf "%02d%02d\\n" $MAJOR $MINOR - +if [ "x$with_patchlevel" != "x" ] ; then + PATCHLEVEL=$(echo __GNUC_PATCHLEVEL__ | $compiler -E -xc - | tail -n 1) + printf "%02d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL +else + printf "%02d%02d\\n" $MAJOR $MINOR +fi diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh index 683eb12..684fb9c 100644 --- a/scripts/gen_initramfs_list.sh +++ b/scripts/gen_initramfs_list.sh @@ -19,11 +19,11 @@ Usage: -o Create gzipped initramfs file named using gen_init_cpio and gzip -u User ID to map to user ID 0 (root). - is only meaningful if - is a directory. + is only meaningful if is a + directory. "squash" forces all files to uid 0. -g Group ID to map to group ID 0 (root). - is only meaningful if - is a directory. + is only meaningful if is a + directory. "squash" forces all files to gid 0. File list or directory for cpio archive. If is a .cpio file it will be used as direct input to initramfs. @@ -113,8 +113,8 @@ parse() { local gid="$4" local ftype=$(filetype "${location}") # remap uid/gid to 0 if necessary - [ "$uid" -eq "$root_uid" ] && uid=0 - [ "$gid" -eq "$root_gid" ] && gid=0 + [ "$root_uid" = "squash" ] && uid=0 || [ "$uid" -eq "$root_uid" ] && uid=0 + [ "$root_gid" = "squash" ] && gid=0 || [ "$gid" -eq "$root_gid" ] && gid=0 local str="${mode} ${uid} ${gid}" [ "${ftype}" == "invalid" ] && return 0 diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh index cdca738..9681476 100644 --- a/scripts/kconfig/lxdialog/check-lxdialog.sh +++ b/scripts/kconfig/lxdialog/check-lxdialog.sh @@ -51,7 +51,7 @@ usage() { printf "Usage: $0 [-check compiler options|-header|-library]\n" } -if [ $# == 0 ]; then +if [ $# -eq 0 ]; then usage exit 1 fi diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 8e5610d..51921aa 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -374,6 +374,7 @@ static int parse_elf(struct elf_info *in hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx); hdr->e_shnum = TO_NATIVE(hdr->e_shnum); hdr->e_machine = TO_NATIVE(hdr->e_machine); + hdr->e_type = TO_NATIVE(hdr->e_type); sechdrs = (void *)hdr + hdr->e_shoff; info->sechdrs = sechdrs; @@ -384,6 +385,8 @@ static int parse_elf(struct elf_info *in 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); + sechdrs[i].sh_info = TO_NATIVE(sechdrs[i].sh_info); + sechdrs[i].sh_addr = TO_NATIVE(sechdrs[i].sh_addr); } /* Find symbol table. */ for (i = 1; i < hdr->e_shnum; i++) { @@ -606,17 +609,13 @@ static int strrcmp(const char *s, const * the pattern is identified by: * tosec = .init.text | .exit.text | .init.data * fromsec = .data - * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one, *_console + * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one, *_console, *_timer * * Pattern 3: - * 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: + * Pattern 4: * 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 @@ -625,26 +624,6 @@ static int strrcmp(const char *s, const * This pattern is identified by * refsymname = __init_begin, _sinittext, _einittext * - * 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_ - * - * Pattern 8: - * Symbols contained in .paravirtprobe may safely reference .init.text. - * The pattern is: - * tosec = .init.text - * fromsec = .paravirtprobe - * - * Pattern 10: - * ia64 has machvec table for each platform and - * powerpc has a machine desc table for each platform. - * It is mixture of function pointers of .init.text and .text. - * fromsec = .machvec | .machine.desc **/ static int secref_whitelist(const char *modname, const char *tosec, const char *fromsec, const char *atsym, @@ -655,12 +634,12 @@ static int secref_whitelist(const char * const char *pat2sym[] = { "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", - "apic_es7000", NULL }; @@ -702,37 +681,16 @@ static int secref_whitelist(const char * return 1; /* Check for pattern 3 */ - if ((strncmp(fromsec, ".pci_fixup", strlen(".pci_fixup")) == 0) && - (strcmp(tosec, ".init.text") == 0)) - return 1; - - /* Check for pattern 4 */ if ((strcmp(fromsec, ".text.head") == 0) && ((strcmp(tosec, ".init.data") == 0) || (strcmp(tosec, ".init.text") == 0))) return 1; - /* Check for pattern 5 */ + /* Check for pattern 4 */ for (s = pat3refsym; *s; s++) if (strcmp(refsymname, *s) == 0) return 1; - /* Check for pattern 7 */ - if ((strcmp(tosec, ".init.data") == 0) && - (strncmp(fromsec, ".text", strlen(".text")) == 0) && - (strncmp(refsymname, "logo_", strlen("logo_")) == 0)) - return 1; - - /* Check for pattern 8 */ - if ((strcmp(tosec, ".init.text") == 0) && - (strcmp(fromsec, ".paravirtprobe") == 0)) - return 1; - - /* Check for pattern 10 */ - if ((strcmp(fromsec, ".machvec") == 0) || - (strcmp(fromsec, ".machine.desc") == 0)) - return 1; - return 0; } @@ -753,6 +711,8 @@ static Elf_Sym *find_elf_symbol(struct e for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { if (sym->st_shndx != relsym->st_shndx) continue; + if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) + continue; if (sym->st_value == addr) return sym; } @@ -864,11 +824,6 @@ static void warn_sec_mismatch(const char elf->strtab + before->st_name, refsymname)) return; - /* fromsec whitelist - without a valid 'before' - * powerpc has a GOT table in .got2 section */ - if (strcmp(fromsec, ".got2") == 0) - return; - if (before && after) { warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s " "(between '%s' and '%s')\n", @@ -895,6 +850,72 @@ static void warn_sec_mismatch(const char } } +static inline unsigned int *reloc_location(struct elf_info *elf, + int rsection, Elf_Rela *r) +{ + Elf_Shdr *sechdrs = elf->sechdrs; + int section = sechdrs[rsection].sh_info; + + return (void *)elf->hdr + sechdrs[section].sh_offset + + (r->r_offset - sechdrs[section].sh_addr); +} + +static void addend_386_rel(struct elf_info *elf, int rsection, Elf_Rela *r) +{ + unsigned int r_typ = ELF_R_TYPE(r->r_info); + unsigned int *location = reloc_location(elf, rsection, r); + + 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; + } +} + +static void addend_arm_rel(struct elf_info *elf, int rsection, Elf_Rela *r) +{ + unsigned int r_typ = ELF_R_TYPE(r->r_info); + unsigned int *location = reloc_location(elf, rsection, r); + + switch (r_typ) { + case R_ARM_ABS32: + r->r_addend = TO_NATIVE(*location); + break; + case R_ARM_PC24: + r->r_addend = ((TO_NATIVE(*location) & 0x00ffffff) << 2) + 8; + break; + } +} + +static int addend_mips_rel(struct elf_info *elf, int rsection, Elf_Rela *r) +{ + unsigned int r_typ = ELF_R_TYPE(r->r_info); + unsigned int *location = reloc_location(elf, rsection, r); + 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; +} + /** * A module includes a number of sections that are discarded * either when loaded or when used as built-in. @@ -938,8 +959,11 @@ static void check_sec_ref(struct module r.r_offset = TO_NATIVE(rela->r_offset); #if KERNEL_ELFCLASS == ELFCLASS64 if (hdr->e_machine == EM_MIPS) { + 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); @@ -972,8 +996,11 @@ #endif r.r_offset = TO_NATIVE(rel->r_offset); #if KERNEL_ELFCLASS == ELFCLASS64 if (hdr->e_machine == EM_MIPS) { + 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); @@ -983,6 +1010,14 @@ #else r_sym = ELF_R_SYM(r.r_info); #endif r.r_addend = 0; + if (hdr->e_machine == EM_386) + addend_386_rel(elf, i, &r); + else if (hdr->e_machine == EM_ARM) + addend_arm_rel(elf, i, &r); + else if (hdr->e_machine == EM_MIPS) { + if (addend_mips_rel(elf, i, &r)) + continue; + } sym = elf->symtab_start + r_sym; /* Skip special sections */ if (sym->st_shndx >= SHN_LORESERVE) @@ -998,6 +1033,62 @@ #endif } } +/* + * Identify sections from which references to either a + * .init or a .exit section is OK. + * + * [OPD] Keith Ownes commented: + * For our future {in}sanity, add a comment that this is the ppc .opd + * section, not the ia64 .opd section. + * ia64 .opd should not point to discarded sections. + * [.rodata] like for .init.text we ignore .rodata references -same reason + **/ +static int initexit_section_ref_ok(const char *name) +{ + const char **s; + /* Absolute section names */ + const char *namelist1[] = { + "__bug_table", /* used by powerpc for BUG() */ + "__ex_table", + ".altinstructions", + ".fixup", + ".machvec", /* ia64 + powerpc uses these */ + ".machine.desc", + ".opd", /* See comment [OPD] */ + ".parainstructions", + ".pdr", + ".plt", /* seen on ARCH=um build on x86_64. Harmless */ + ".smp_locks", + ".stab", + NULL + }; + /* Start of section names */ + const char *namelist2[] = { + ".debug", + ".eh_frame", + ".note", /* ignore ELF notes - may contain anything */ + ".got", /* powerpc - global offset table */ + ".toc", /* powerpc - table of contents */ + NULL + }; + /* part of section name */ + const char *namelist3 [] = { + ".unwind", /* Sample: IA_64.unwind.exit.text */ + NULL + }; + + for (s = namelist1; *s; s++) + if (strcmp(*s, name) == 0) + return 1; + for (s = namelist2; *s; s++) + if (strncmp(*s, name, strlen(*s)) == 0) + return 1; + for (s = namelist3; *s; s++) + if (strstr(name, *s) != NULL) + return 1; + return 0; +} + /** * Functions used only during module init is marked __init and is stored in * a .init.text section. Likewise data is marked __initdata and stored in @@ -1034,41 +1125,24 @@ static int init_section_ref_ok(const cha const char **s; /* Absolute section names */ const char *namelist1[] = { - ".init", - ".opd", /* see comment [OPD] at exit_section_ref_ok() */ - ".toc1", /* used by ppc64 */ - ".stab", - ".data.rel.ro", /* used by parisc64 */ - ".parainstructions", - ".text.lock", - "__bug_table", /* used by powerpc for BUG() */ - ".pci_fixup_header", - ".pci_fixup_final", - ".pdr", - "__param", - "__ex_table", - ".fixup", - ".smp_locks", - ".plt", /* seen on ARCH=um build on x86_64. Harmless */ "__ftr_fixup", /* powerpc cpu feature fixup */ "__fw_ftr_fixup", /* powerpc firmware feature fixup */ + "__param", + ".data.rel.ro", /* used by parisc64 */ + ".init", + ".text.lock", NULL }; /* Start of section names */ const char *namelist2[] = { ".init.", - ".altinstructions", - ".eh_frame", - ".debug", - ".parainstructions", + ".pci_fixup", ".rodata", NULL }; - /* part of section name */ - const char *namelist3 [] = { - ".unwind", /* sample: IA_64.unwind.init.text */ - NULL - }; + + if (initexit_section_ref_ok(name)) + return 1; for (s = namelist1; *s; s++) if (strcmp(*s, name) == 0) @@ -1076,9 +1150,10 @@ static int init_section_ref_ok(const cha for (s = namelist2; *s; s++) if (strncmp(*s, name, strlen(*s)) == 0) return 1; - for (s = namelist3; *s; s++) - if (strstr(name, *s) != NULL) - return 1; + + /* If section name ends with ".init" we allow references + * as is the case with .initcallN.init, .early_param.init, .taglist.init etc + */ if (strrcmp(name, ".init") == 0) return 1; return 0; @@ -1103,57 +1178,25 @@ static int exit_section(const char *name /* * Identify sections from which references to a .exit section is OK. - * - * [OPD] Keith Ownes commented: - * For our future {in}sanity, add a comment that this is the ppc .opd - * section, not the ia64 .opd section. - * ia64 .opd should not point to discarded sections. - * [.rodata] like for .init.text we ignore .rodata references -same reason **/ static int exit_section_ref_ok(const char *name) { const char **s; /* Absolute section names */ const char *namelist1[] = { - ".exit.text", ".exit.data", - ".init.text", - ".rodata", - ".opd", /* See comment [OPD] */ - ".toc1", /* used by ppc64 */ - ".altinstructions", - ".pdr", - "__bug_table", /* used by powerpc for BUG() */ + ".exit.text", ".exitcall.exit", - ".eh_frame", - ".parainstructions", - ".stab", - "__ex_table", - ".fixup", - ".smp_locks", - ".plt", /* seen on ARCH=um build on x86_64. Harmless */ - NULL - }; - /* Start of section names */ - const char *namelist2[] = { - ".debug", - NULL - }; - /* part of section name */ - const char *namelist3 [] = { - ".unwind", /* Sample: IA_64.unwind.exit.text */ + ".rodata", NULL }; + if (initexit_section_ref_ok(name)) + return 1; + for (s = namelist1; *s; s++) if (strcmp(*s, name) == 0) return 1; - for (s = namelist2; *s; s++) - if (strncmp(*s, name, strlen(*s)) == 0) - return 1; - for (s = namelist3; *s; s++) - if (strstr(name, *s) != NULL) - return 1; return 0; } diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 0858caa..4156dd3 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -60,6 +60,9 @@ typedef union #define ELF64_MIPS_R_SYM(i) \ ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_sym) +#define ELF64_MIPS_R_TYPE(i) \ + ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_type1) + #if KERNEL_ELFDATA != HOST_ELFDATA static inline void __endian(const void *src, void *dest, unsigned int size) diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c index 8365db6..7abc07f 100644 --- a/usr/gen_init_cpio.c +++ b/usr/gen_init_cpio.c @@ -498,7 +498,9 @@ int main (int argc, char *argv[]) exit(1); } - if (! (cpio_list = fopen(argv[1], "r"))) { + if (!strcmp(argv[1], "-")) + cpio_list = stdin; + else if (! (cpio_list = fopen(argv[1], "r"))) { fprintf(stderr, "ERROR: unable to open '%s': %s\n\n", argv[1], strerror(errno)); usage(argv[0]);