powerpc64/module elfv1: Set opd addresses after module relocation
authorNaveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Tue, 29 May 2018 06:51:00 +0000 (12:21 +0530)
committerMichael Ellerman <mpe@ellerman.id.au>
Sat, 20 Oct 2018 02:26:47 +0000 (13:26 +1100)
module_frob_arch_sections() is called before the module is moved to its
final location. The function descriptor section addresses we are setting
here are thus invalid. Fix this by processing opd section during
module_finalize()

Fixes: 5633e85b2c313 ("powerpc64: Add .opd based function descriptor dereference")
Cc: stable@vger.kernel.org # v4.16
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/kernel/module.c
arch/powerpc/kernel/module_64.c

index 77371c9ef3d8f9fd46894e47a119e215ca86ae3a..2d861a36662ed310e5efbff4f1ae133047ffcb57 100644 (file)
@@ -74,6 +74,14 @@ int module_finalize(const Elf_Ehdr *hdr,
                                  (void *)sect->sh_addr + sect->sh_size);
 #endif /* CONFIG_PPC64 */
 
+#ifdef PPC64_ELF_ABI_v1
+       sect = find_section(hdr, sechdrs, ".opd");
+       if (sect != NULL) {
+               me->arch.start_opd = sect->sh_addr;
+               me->arch.end_opd = sect->sh_addr + sect->sh_size;
+       }
+#endif /* PPC64_ELF_ABI_v1 */
+
 #ifdef CONFIG_PPC_BARRIER_NOSPEC
        sect = find_section(hdr, sechdrs, "__spec_barrier_fixup");
        if (sect != NULL)
index b8d61e019d06189f74d56114c23aa3637d1579b7..2c53de9f3b6ade5a20215748e71ec712a524c102 100644 (file)
@@ -360,11 +360,6 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr,
                else if (strcmp(secstrings+sechdrs[i].sh_name,"__versions")==0)
                        dedotify_versions((void *)hdr + sechdrs[i].sh_offset,
                                          sechdrs[i].sh_size);
-               else if (!strcmp(secstrings + sechdrs[i].sh_name, ".opd")) {
-                       me->arch.start_opd = sechdrs[i].sh_addr;
-                       me->arch.end_opd = sechdrs[i].sh_addr +
-                                          sechdrs[i].sh_size;
-               }
 
                /* We don't handle .init for the moment: rename to _init */
                while ((p = strstr(secstrings + sechdrs[i].sh_name, ".init")))