[PATCH] powerpc64: Fix loading of modules without a .toc section
authorAlan Modra <amodra@bigpond.net.au>
Mon, 24 Apr 2006 12:41:51 +0000 (22:11 +0930)
committerPaul Mackerras <paulus@samba.org>
Fri, 28 Apr 2006 11:04:49 +0000 (21:04 +1000)
Normally, ppc64 module .ko files contain a table-of-contents (.toc)
section, but if the module doesn't reference any static or external
data or external procedures, it is possible for gcc/binutils to
generate a .ko that doesn't have a .toc.  Currently the module
loader refuses to load such a module, since it needs the address
of the .toc section to use in relocations.

This patch fixes the problem by using the address of the .stubs
section instead, which is an acceptable substitute in this situation.

Signed-off-by: Paul Mackerras <paulus@samba.org>
arch/powerpc/kernel/module_64.c

index 928b8581fcb043142c088052885b3f5b671ec4cf..ba34001fca8e8420b6c1aab0df0f9b0a43de3bda 100644 (file)
@@ -191,11 +191,19 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr,
                                 (void *)hdr
                                 + sechdrs[sechdrs[i].sh_link].sh_offset);
        }
-       if (!me->arch.stubs_section || !me->arch.toc_section) {
-               printk("%s: doesn't contain .toc or .stubs.\n", me->name);
+
+       if (!me->arch.stubs_section) {
+               printk("%s: doesn't contain .stubs.\n", me->name);
                return -ENOEXEC;
        }
 
+       /* If we don't have a .toc, just use .stubs.  We need to set r2
+          to some reasonable value in case the module calls out to
+          other functions via a stub, or if a function pointer escapes
+          the module by some means.  */
+       if (!me->arch.toc_section)
+               me->arch.toc_section = me->arch.stubs_section;
+
        /* Override the stubs size */
        sechdrs[me->arch.stubs_section].sh_size = get_stubs_size(hdr, sechdrs);
        return 0;
@@ -342,7 +350,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
                        break;
 
                case R_PPC64_TOC16:
-                       /* Subtact TOC pointer */
+                       /* Subtract TOC pointer */
                        value -= my_r2(sechdrs, me);
                        if (value + 0x8000 > 0xffff) {
                                printk("%s: bad TOC16 relocation (%lu)\n",
@@ -355,7 +363,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
                        break;
 
                case R_PPC64_TOC16_DS:
-                       /* Subtact TOC pointer */
+                       /* Subtract TOC pointer */
                        value -= my_r2(sechdrs, me);
                        if ((value & 3) != 0 || value + 0x8000 > 0xffff) {
                                printk("%s: bad TOC16_DS relocation (%lu)\n",