Commit f749edae authored by Alan Modra's avatar Alan Modra Committed by Paul Mackerras

[PATCH] powerpc64: Fix loading of modules without a .toc section

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: default avatarPaul Mackerras <paulus@samba.org>
parent d882995c
...@@ -191,11 +191,19 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr, ...@@ -191,11 +191,19 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr,
(void *)hdr (void *)hdr
+ sechdrs[sechdrs[i].sh_link].sh_offset); + 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; 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 */ /* Override the stubs size */
sechdrs[me->arch.stubs_section].sh_size = get_stubs_size(hdr, sechdrs); sechdrs[me->arch.stubs_section].sh_size = get_stubs_size(hdr, sechdrs);
return 0; return 0;
...@@ -342,7 +350,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, ...@@ -342,7 +350,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
break; break;
case R_PPC64_TOC16: case R_PPC64_TOC16:
/* Subtact TOC pointer */ /* Subtract TOC pointer */
value -= my_r2(sechdrs, me); value -= my_r2(sechdrs, me);
if (value + 0x8000 > 0xffff) { if (value + 0x8000 > 0xffff) {
printk("%s: bad TOC16 relocation (%lu)\n", printk("%s: bad TOC16 relocation (%lu)\n",
...@@ -355,7 +363,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, ...@@ -355,7 +363,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
break; break;
case R_PPC64_TOC16_DS: case R_PPC64_TOC16_DS:
/* Subtact TOC pointer */ /* Subtract TOC pointer */
value -= my_r2(sechdrs, me); value -= my_r2(sechdrs, me);
if ((value & 3) != 0 || value + 0x8000 > 0xffff) { if ((value & 3) != 0 || value + 0x8000 > 0xffff) {
printk("%s: bad TOC16_DS relocation (%lu)\n", printk("%s: bad TOC16_DS relocation (%lu)\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment