diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/Kbuild.include | 9 | ||||
-rw-r--r-- | scripts/Makefile.build | 2 | ||||
-rw-r--r-- | scripts/gcc-ld | 29 | ||||
-rwxr-xr-x | scripts/ld-version.sh | 8 | ||||
-rw-r--r-- | scripts/mod/modpost.c | 25 | ||||
-rw-r--r-- | scripts/mod/modpost.h | 2 |
6 files changed, 71 insertions, 4 deletions
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 547e15d..93a0da2 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -155,6 +155,15 @@ ld-option = $(call try-run,\ # Important: no spaces around options ar-option = $(call try-run, $(AR) rc$(1) "$$TMP",$(1),$(2)) +# ld-version +# Usage: $(call ld-version) +# Note this is mainly for HJ Lu's 3 number binutil versions +ld-version = $(shell $(LD) --version | $(srctree)/scripts/ld-version.sh) + +# ld-ifversion +# Usage: $(call ld-ifversion, -ge, 22252, y) +ld-ifversion = $(shell [ $(call ld-version) $(1) $(2) ] && echo $(3)) + ###### ### diff --git a/scripts/Makefile.build b/scripts/Makefile.build index d5d859c..9f0ee22 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -198,7 +198,7 @@ $(multi-objs-y:.o=.s) : modname = $(modname-multi) $(multi-objs-y:.o=.lst) : modname = $(modname-multi) quiet_cmd_cc_s_c = CC $(quiet_modtag) $@ -cmd_cc_s_c = $(CC) $(c_flags) -fverbose-asm -S -o $@ $< +cmd_cc_s_c = $(CC) $(c_flags) $(DISABLE_LTO) -fverbose-asm -S -o $@ $< $(obj)/%.s: $(src)/%.c FORCE $(call if_changed_dep,cc_s_c) diff --git a/scripts/gcc-ld b/scripts/gcc-ld new file mode 100644 index 0000000..cadab9a --- /dev/null +++ b/scripts/gcc-ld @@ -0,0 +1,29 @@ +#!/bin/sh +# run gcc with ld options +# used as a wrapper to execute link time optimizations +# yes virginia, this is not pretty + +ARGS="-nostdlib" + +while [ "$1" != "" ] ; do + case "$1" in + -save-temps|-m32|-m64) N="$1" ;; + -r) N="$1" ;; + -[Wg]*) N="$1" ;; + -[olv]|-[Ofd]*|-nostdlib) N="$1" ;; + --end-group|--start-group) + N="-Wl,$1" ;; + -[RTFGhIezcbyYu]*|\ +--script|--defsym|-init|-Map|--oformat|-rpath|\ +-rpath-link|--sort-section|--section-start|-Tbss|-Tdata|-Ttext|\ +--version-script|--dynamic-list|--version-exports-symbol|--wrap|-m) + A="$1" ; shift ; N="-Wl,$A,$1" ;; + -[m]*) N="$1" ;; + -*) N="-Wl,$1" ;; + *) N="$1" ;; + esac + ARGS="$ARGS $N" + shift +done + +exec $CC $ARGS diff --git a/scripts/ld-version.sh b/scripts/ld-version.sh new file mode 100755 index 0000000..198580d --- /dev/null +++ b/scripts/ld-version.sh @@ -0,0 +1,8 @@ +#!/usr/bin/awk -f +# extract linker version number from stdin and turn into single number + { + gsub(".*)", ""); + split($1,a, "."); + print a[1]*10000000 + a[2]*100000 + a[3]*10000 + a[4]*100 + a[5]; + exit + } diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 99a45fd..0663556 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -623,7 +623,10 @@ static void handle_modversions(struct module *mod, struct elf_info *info, switch (sym->st_shndx) { case SHN_COMMON: - warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name); + if (!strncmp(symname, "__gnu_lto_", sizeof("__gnu_lto_")-1)) { + /* Should warn here, but modpost runs before the linker */ + } else + warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name); break; case SHN_UNDEF: /* undefined symbol */ @@ -849,6 +852,7 @@ static const char *section_white_list[] = ".xt.lit", /* xtensa */ ".arcextmap*", /* arc */ ".gnu.linkonce.arcext*", /* arc : modules */ + ".gnu.lto*", NULL }; @@ -1455,6 +1459,10 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf, to = find_elf_symbol(elf, r->r_addend, sym); tosym = sym_name(elf, to); + if (!strncmp(fromsym, "reference___initcall", + sizeof("reference___initcall")-1)) + return; + /* check whitelist - we may ignore it */ if (secref_whitelist(mismatch, fromsec, fromsym, tosec, tosym)) { @@ -1693,6 +1701,19 @@ static void check_sec_ref(struct module *mod, const char *modname, } } +static char *remove_dot(char *s) +{ + char *end; + int n = strcspn(s, "."); + + if (n > 0 && s[n] != 0) { + strtoul(s + n + 1, &end, 10); + if (end > s + n + 1 && (*end == '.' || *end == 0)) + s[n] = 0; + } + return s; +} + static void read_symbols(char *modname) { const char *symname; @@ -1731,7 +1752,7 @@ static void read_symbols(char *modname) } for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { - symname = info.strtab + sym->st_name; + symname = remove_dot(info.strtab + sym->st_name); handle_modversions(mod, &info, sym, symname); handle_moddevtable(mod, &info, sym, symname); diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 51207e4..168b43d 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -127,7 +127,7 @@ struct elf_info { Elf_Section export_gpl_sec; Elf_Section export_unused_gpl_sec; Elf_Section export_gpl_future_sec; - const char *strtab; + char *strtab; char *modinfo; unsigned int modinfo_len; |