diff options
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/alpha/dl-machine.h | 4 | ||||
-rw-r--r-- | sysdeps/i386/dl-machine.h | 10 | ||||
-rw-r--r-- | sysdeps/m68k/dl-machine.h | 18 | ||||
-rw-r--r-- | sysdeps/mips/dl-machine.h | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/i386/clone.S | 1 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/m68k/clone.S | 75 |
6 files changed, 93 insertions, 17 deletions
diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h index a75011fccb..2bf8f9b7ec 100644 --- a/sysdeps/alpha/dl-machine.h +++ b/sysdeps/alpha/dl-machine.h @@ -341,8 +341,8 @@ elf_machine_rela (struct link_map *map, { Elf64_Addr loadbase, sym_value; - loadbase = RESOLVE (&sym, (Elf64_Addr)reloc_addr, - r_info == R_ALPHA_JMP_SLOT); + loadbase = RESOLVE (&sym, + r_info == R_ALPHA_JMP_SLOT ? DL_LOOKUP_NOPLT : 0); sym_value = sym ? loadbase + sym->st_value : 0; if (r_info == R_ALPHA_GLOB_DAT) diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h index 111122e437..d616bf4db8 100644 --- a/sysdeps/i386/dl-machine.h +++ b/sysdeps/i386/dl-machine.h @@ -193,15 +193,15 @@ elf_machine_rel (struct link_map *map, switch (ELF32_R_TYPE (reloc->r_info)) { case R_386_COPY: - loadbase = RESOLVE (&sym, (Elf32_Addr) reloc_addr, 0); + loadbase = RESOLVE (&sym, DL_LOOKUP_NOEXEC); memcpy (reloc_addr, (void *) (loadbase + sym->st_value), sym->st_size); break; case R_386_GLOB_DAT: - loadbase = RESOLVE (&sym, (Elf32_Addr) reloc_addr, 0); + loadbase = RESOLVE (&sym, 0); *reloc_addr = sym ? (loadbase + sym->st_value) : 0; break; case R_386_JMP_SLOT: - loadbase = RESOLVE (&sym, (Elf32_Addr) reloc_addr, 1); + loadbase = RESOLVE (&sym, DL_LOOKUP_NOPLT); *reloc_addr = sym ? (loadbase + sym->st_value) : 0; break; case R_386_32: @@ -222,7 +222,7 @@ elf_machine_rel (struct link_map *map, built-in definitions used while loading those libraries. */ undo = map->l_addr + sym->st_value; #endif - loadbase = RESOLVE (&sym, (Elf32_Addr) reloc_addr, 0); + loadbase = RESOLVE (&sym, 0); *reloc_addr += (sym ? (loadbase + sym->st_value) : 0) - undo; break; } @@ -233,7 +233,7 @@ elf_machine_rel (struct link_map *map, *reloc_addr += map->l_addr; break; case R_386_PC32: - loadbase = RESOLVE (&sym, (Elf32_Addr) reloc_addr, 0); + loadbase = RESOLVE (&sym, 0); *reloc_addr += ((sym ? (loadbase + sym->st_value) : 0) - (Elf32_Addr) reloc_addr); break; diff --git a/sysdeps/m68k/dl-machine.h b/sysdeps/m68k/dl-machine.h index 4642f00c63..15aa5325fc 100644 --- a/sysdeps/m68k/dl-machine.h +++ b/sysdeps/m68k/dl-machine.h @@ -205,29 +205,29 @@ elf_machine_rela (struct link_map *map, switch (ELF32_R_TYPE (reloc->r_info)) { case R_68K_COPY: - loadbase = RESOLVE (&sym, (Elf32_Addr) reloc_addr, 0); + loadbase = RESOLVE (&sym, DL_LOOKUP_NOEXEC); memcpy (reloc_addr, (void *) (loadbase + sym->st_value), sym->st_size); break; case R_68K_GLOB_DAT: - loadbase = RESOLVE (&sym, (Elf32_Addr) reloc_addr, 0); + loadbase = RESOLVE (&sym, 0); *reloc_addr = sym ? (loadbase + sym->st_value) : 0; break; case R_68K_JMP_SLOT: - loadbase = RESOLVE (&sym, (Elf32_Addr) reloc_addr, 1); + loadbase = RESOLVE (&sym, DL_LOOKUP_NOPLT); *reloc_addr = sym ? (loadbase + sym->st_value) : 0; break; case R_68K_8: - loadbase = RESOLVE (&sym, (Elf32_Addr) reloc_addr, 0); + loadbase = RESOLVE (&sym, 0); *(char *) reloc_addr = ((sym ? (loadbase + sym->st_value) : 0) + reloc->r_addend); break; case R_68K_16: - loadbase = RESOLVE (&sym, (Elf32_Addr) reloc_addr, 0); + loadbase = RESOLVE (&sym, 0); *(short *) reloc_addr = ((sym ? (loadbase + sym->st_value) : 0) + reloc->r_addend); break; case R_68K_32: - loadbase = RESOLVE (&sym, (Elf32_Addr) reloc_addr, 0); + loadbase = RESOLVE (&sym, 0); *reloc_addr = ((sym ? (loadbase + sym->st_value) : 0) + reloc->r_addend); break; @@ -235,17 +235,17 @@ elf_machine_rela (struct link_map *map, *reloc_addr = map->l_addr + reloc->r_addend; break; case R_68K_PC8: - loadbase = RESOLVE (&sym, (Elf32_Addr) reloc_addr, 0); + loadbase = RESOLVE (&sym, 0); *(char *) reloc_addr = ((sym ? (loadbase + sym->st_value) : 0) + reloc->r_addend - (Elf32_Addr) reloc_addr); break; case R_68K_PC16: - loadbase = RESOLVE (&sym, (Elf32_Addr) reloc_addr, 0); + loadbase = RESOLVE (&sym, 0); *(short *) reloc_addr = ((sym ? (loadbase + sym->st_value) : 0) + reloc->r_addend - (Elf32_Addr) reloc_addr); break; case R_68K_PC32: - loadbase = RESOLVE (&sym, (Elf32_Addr) reloc_addr, 0); + loadbase = RESOLVE (&sym, 0); *reloc_addr = ((sym ? (loadbase + sym->st_value) : 0) + reloc->r_addend - (Elf32_Addr) reloc_addr); break; diff --git a/sysdeps/mips/dl-machine.h b/sysdeps/mips/dl-machine.h index 50e9f64665..c0ac649144 100644 --- a/sysdeps/mips/dl-machine.h +++ b/sysdeps/mips/dl-machine.h @@ -453,7 +453,7 @@ elf_machine_rel (struct link_map *map, else #endif undo = 0; - loadbase = RESOLVE (&sym, (ElfW(Addr)) reloc_addr, 0); + loadbase = RESOLVE (&sym, 0); *reloc_addr += (sym ? (loadbase + sym->st_value) : 0) - undo; } break; diff --git a/sysdeps/unix/sysv/linux/i386/clone.S b/sysdeps/unix/sysv/linux/i386/clone.S index 02f561927e..b60bc8ed92 100644 --- a/sysdeps/unix/sysv/linux/i386/clone.S +++ b/sysdeps/unix/sysv/linux/i386/clone.S @@ -71,6 +71,7 @@ ENTRY(__clone) thread_start: subl %ebp,%ebp /* terminate the stack frame */ call *%ebx + pushl %eax #ifdef PIC call _exit@PLT #else diff --git a/sysdeps/unix/sysv/linux/m68k/clone.S b/sysdeps/unix/sysv/linux/m68k/clone.S new file mode 100644 index 0000000000..64077e00de --- /dev/null +++ b/sysdeps/unix/sysv/linux/m68k/clone.S @@ -0,0 +1,75 @@ +/* Copyright (C) 1996 Free Software Foundation, Inc. + Contributed by Andreas Schwab (schwab@issan.informatik.uni-dortmund.de) + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* clone is even more special than fork as it mucks with stacks + and invokes a function in the right context after its all over. */ + +#include <sysdep.h> +#include <errnos.h> + +/* int clone (int (*fn) (), void *child_stack, int flags, int nargs, ...) */ + + .text +ENTRY (__clone) + /* Sanity check arguments. */ + movel #-EINVAL, %d0 + movel 4(%sp), %a0 /* no NULL function pointers */ + tstl %a0 + jeq syscall_error + movel 8(%sp), %a1 /* no NULL stack pointers */ + tstl %a1 + jeq syscall_error + movel 16(%sp), %d1 /* no negative argument counts */ + jmi syscall_error + + /* Allocate space on the new stack and copy args over */ + movel %d1, %d0 + negl %d0 + lea (%a1,%d0.l*4), %a1 + jeq 2f +1: movel 16(%sp,%d1.l*4), -4(%a1,%d1.l*4) + subql #1, %d1 + jne 1b +2: + + /* Do the system call */ + exg %d2, %a1 /* save %d2 and get stack pointer */ + movel 12(%sp), %d1 /* get flags */ + movel #SYS_ify (clone), %d0 + trap #0 + exg %d2, %a1 /* restore %d2 */ + + tstl %d0 + jmi syscall_error + jeq thread_start + + rts + + SYSCALL_ERROR_HANDLER + +thread_start: + subl %fp, %fp /* terminate the stack frame */ + jsr (%a0) + movel %d0, -(%sp) +#ifdef PIC + bsrl _exit@PLTPC +#else + jbsr _exit +#endif + +weak_alias (__clone, clone) |