diff --git a/debian/changelog b/debian/changelog index 31250bce0..29cc1089b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -454,6 +454,9 @@ linux (4.4.4-1) UNRELEASED; urgency=medium * Fix/ignore module ABI changes in 4.4.4 as appropriate * Revert "drm/radeon: call hpd_irq_event on resume", reported to cause regressions (crash/hang) on some systems + * [powerpc*] Fix module linking to work with binutils 2.26 (Closes: #808043): + - Simplify module TOC handling + - Fix dedotify for binutils >= 2.26 [ Ian Campbell ] * [armhf] dts: Add DTB for Novena, patches from Vagrant Cascadian diff --git a/debian/patches/bugfix/powerpc/powerpc-fix-dedotify-for-binutils-2.26.patch b/debian/patches/bugfix/powerpc/powerpc-fix-dedotify-for-binutils-2.26.patch new file mode 100644 index 000000000..a438f560a --- /dev/null +++ b/debian/patches/bugfix/powerpc/powerpc-fix-dedotify-for-binutils-2.26.patch @@ -0,0 +1,34 @@ +From: Andreas Schwab +Date: Fri, 5 Feb 2016 19:50:03 +0100 +Subject: powerpc: Fix dedotify for binutils >= 2.26 +Origin: https://git.kernel.org/linus/f15838e9cac8f78f0cc506529bb9d3b9fa589c1f + +Since binutils 2.26 BFD is doing suffix merging on STRTAB sections. But +dedotify modifies the symbol names in place, which can also modify +unrelated symbols with a name that matches a suffix of a dotted name. To +remove the leading dot of a symbol name we can just increment the pointer +into the STRTAB section instead. + +Backport to all stables to avoid breakage when people update their +binutils - mpe. + +Cc: stable@vger.kernel.org +Signed-off-by: Andreas Schwab +Signed-off-by: Michael Ellerman +--- + arch/powerpc/kernel/module_64.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c +index ac64ffdb52c8..08b7a40de5f8 100644 +--- a/arch/powerpc/kernel/module_64.c ++++ b/arch/powerpc/kernel/module_64.c +@@ -340,7 +340,7 @@ static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab) + if (name[0] == '.') { + if (strcmp(name+1, "TOC.") == 0) + syms[i].st_shndx = SHN_ABS; +- memmove(name, name+1, strlen(name)); ++ syms[i].st_name++; + } + } + } diff --git a/debian/patches/bugfix/powerpc/powerpc-simplify-module-toc-handling.patch b/debian/patches/bugfix/powerpc/powerpc-simplify-module-toc-handling.patch new file mode 100644 index 000000000..3caeb018f --- /dev/null +++ b/debian/patches/bugfix/powerpc/powerpc-simplify-module-toc-handling.patch @@ -0,0 +1,125 @@ +From: Alan Modra +Date: Fri, 15 Jan 2016 20:52:22 +1100 +Subject: powerpc: Simplify module TOC handling +Origin: https://git.kernel.org/linus/c153693d7eb9eeb28478aa2deaaf0b4e7b5ff5e9 + +PowerPC64 uses the symbol .TOC. much as other targets use +_GLOBAL_OFFSET_TABLE_. It identifies the value of the GOT pointer (or in +powerpc parlance, the TOC pointer). Global offset tables are generally +local to an executable or shared library, or in the kernel, module. Thus +it does not make sense for a module to resolve a relocation against +.TOC. to the kernel's .TOC. value. A module has its own .TOC., and +indeed the powerpc64 module relocation processing ignores the kernel +value of .TOC. and instead calculates a module-local value. + +This patch removes code involved in exporting the kernel .TOC., tweaks +modpost to ignore an undefined .TOC., and the module loader to twiddle +the section symbol so that .TOC. isn't seen as undefined. + +Note that if the kernel was compiled with -msingle-pic-base then ELFv2 +would not have function global entry code setting up r2. In that case +the module call stubs would need to be modified to set up r2 using the +kernel .TOC. value, requiring some of this code to be reinstated. + +mpe: Furthermore a change in binutils master (not yet released) causes +the current way we handle the TOC to no longer work when building with +MODVERSIONS=y and RELOCATABLE=n. The symptom is that modules can not be +loaded due to there being no version found for TOC. + +Cc: stable@vger.kernel.org # 3.16+ +Signed-off-by: Alan Modra +Signed-off-by: Michael Ellerman +--- + arch/powerpc/kernel/misc_64.S | 28 ---------------------------- + arch/powerpc/kernel/module_64.c | 12 +++++++++--- + scripts/mod/modpost.c | 3 ++- + 3 files changed, 11 insertions(+), 32 deletions(-) + +diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S +index db475d41b57a..f28754c497e5 100644 +--- a/arch/powerpc/kernel/misc_64.S ++++ b/arch/powerpc/kernel/misc_64.S +@@ -701,31 +701,3 @@ _GLOBAL(kexec_sequence) + li r5,0 + blr /* image->start(physid, image->start, 0); */ + #endif /* CONFIG_KEXEC */ +- +-#ifdef CONFIG_MODULES +-#if defined(_CALL_ELF) && _CALL_ELF == 2 +- +-#ifdef CONFIG_MODVERSIONS +-.weak __crc_TOC. +-.section "___kcrctab+TOC.","a" +-.globl __kcrctab_TOC. +-__kcrctab_TOC.: +- .llong __crc_TOC. +-#endif +- +-/* +- * Export a fake .TOC. since both modpost and depmod will complain otherwise. +- * Both modpost and depmod strip the leading . so we do the same here. +- */ +-.section "__ksymtab_strings","a" +-__kstrtab_TOC.: +- .asciz "TOC." +- +-.section "___ksymtab+TOC.","a" +-/* This symbol name is important: it's used by modpost to find exported syms */ +-.globl __ksymtab_TOC. +-__ksymtab_TOC.: +- .llong 0 /* .value */ +- .llong __kstrtab_TOC. +-#endif /* ELFv2 */ +-#endif /* MODULES */ +diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c +index 59663af9315f..ac64ffdb52c8 100644 +--- a/arch/powerpc/kernel/module_64.c ++++ b/arch/powerpc/kernel/module_64.c +@@ -326,7 +326,10 @@ static void dedotify_versions(struct modversion_info *vers, + } + } + +-/* Undefined symbols which refer to .funcname, hack to funcname (or .TOC.) */ ++/* ++ * Undefined symbols which refer to .funcname, hack to funcname. Make .TOC. ++ * seem to be defined (value set later). ++ */ + static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab) + { + unsigned int i; +@@ -334,8 +337,11 @@ static void dedotify(Elf64_Sym *syms, unsigned int numsyms, char *strtab) + for (i = 1; i < numsyms; i++) { + if (syms[i].st_shndx == SHN_UNDEF) { + char *name = strtab + syms[i].st_name; +- if (name[0] == '.') ++ if (name[0] == '.') { ++ if (strcmp(name+1, "TOC.") == 0) ++ syms[i].st_shndx = SHN_ABS; + memmove(name, name+1, strlen(name)); ++ } + } + } + } +@@ -351,7 +357,7 @@ static Elf64_Sym *find_dot_toc(Elf64_Shdr *sechdrs, + numsyms = sechdrs[symindex].sh_size / sizeof(Elf64_Sym); + + for (i = 1; i < numsyms; i++) { +- if (syms[i].st_shndx == SHN_UNDEF ++ if (syms[i].st_shndx == SHN_ABS + && strcmp(strtab + syms[i].st_name, "TOC.") == 0) + return &syms[i]; + } +diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c +index e080746e1a6b..48958d3cec9e 100644 +--- a/scripts/mod/modpost.c ++++ b/scripts/mod/modpost.c +@@ -594,7 +594,8 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname) + if (strncmp(symname, "_restgpr0_", sizeof("_restgpr0_") - 1) == 0 || + strncmp(symname, "_savegpr0_", sizeof("_savegpr0_") - 1) == 0 || + strncmp(symname, "_restvr_", sizeof("_restvr_") - 1) == 0 || +- strncmp(symname, "_savevr_", sizeof("_savevr_") - 1) == 0) ++ strncmp(symname, "_savevr_", sizeof("_savevr_") - 1) == 0 || ++ strcmp(symname, ".TOC.") == 0) + return 1; + /* Do not ignore this symbol */ + return 0; diff --git a/debian/patches/series b/debian/patches/series index 9ec006a5b..26e324b70 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -133,3 +133,5 @@ debian/thermal-fix-abi-change-in-4.4.4.patch debian/ipv4-fix-abi-change-in-4.4.4.patch debian/ipv6-fix-abi-change-in-4.4.4.patch bugfix/all/revert-drm-radeon-call-hpd_irq_event-on-resume.patch +bugfix/powerpc/powerpc-simplify-module-toc-handling.patch +bugfix/powerpc/powerpc-fix-dedotify-for-binutils-2.26.patch