]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] Fix binfmt_elf.c bug on ppc64
authorAndrew Morton <akpm@digeo.com>
Fri, 20 Jun 2003 15:15:31 +0000 (08:15 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Fri, 20 Jun 2003 15:15:31 +0000 (08:15 -0700)
From: Jakub Jelinek <jakub@redhat.com>

Any prelinked shared library is impossible to run on ppc64 without this
patch, as they immediately segfault.  Say:

/bin/echo

works even if /lib64/ld64.so.1 is prelinked while

/lib64/ld64.so.1 /bin/echo

segfaults.

The problem is that ELF_PLAT_INIT is passed the virtual address of the
shared library, not the difference between the virtual address of the
shared library and p_vaddr of the first PT_LOAD segment in that library
(while for the interpreter interp_load_address is the bias).

ELF_PLAT_INIT sets gpr[2] to this absolute address, but
arch/ppc64/kernel/process.c (start_thread) assumes it is a bias and adds it
to entry and toc values loaded from the entry point descriptor.

For non-prelinked shared libraries, first PT_LOAD segment's p_vaddr is
typically 0 and thus load_addr == load_bias (which is why this bug has not
been discovered that long).

fs/binfmt_elf.c

index 929b9a9df5946e8f74f869b9c3dc5bafa8e99c2a..20b21e9e0ea0dd0ab4e2364aece6317faf37814e 100644 (file)
@@ -697,7 +697,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
                                load_bias += error -
                                             ELF_PAGESTART(load_bias + vaddr);
                                load_addr += load_bias;
-                               reloc_func_desc = load_addr;
+                               reloc_func_desc = load_bias;
                        }
                }
                k = elf_ppnt->p_vaddr;