diff options
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/alpha/dl-machine.h | 4 | ||||
-rw-r--r-- | sysdeps/unix/alpha/sysdep.S | 2 | ||||
-rw-r--r-- | sysdeps/unix/alpha/sysdep.h | 12 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/alpha/init-first.h | 12 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/i386/init-first.h | 13 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/init-first.c | 43 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/m68k/init-first.h | 12 |
7 files changed, 57 insertions, 41 deletions
diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h index bc80b5985d..a276551b00 100644 --- a/sysdeps/alpha/dl-machine.h +++ b/sysdeps/alpha/dl-machine.h @@ -106,7 +106,7 @@ elf_alpha_fix_plt(struct link_map *l, if (edisp >= -0x100000 && edisp < 0x100000) { /* If we are in range, use br to perfect branch prediction and - elide the dependancy on the address load. This case happens, + elide the dependency on the address load. This case happens, e.g., when a shared library call is resolved to the same library. */ int hi, lo; @@ -179,7 +179,7 @@ elf_machine_rela (struct link_map *map, if (resolve) { - loadbase = (*resolve)(&sym, (Elf64_Addr)reloc_addr, + loadbase = (*resolve)(&sym, (Elf64_Addr)reloc_addr, r_info == R_ALPHA_JMP_SLOT); } else diff --git a/sysdeps/unix/alpha/sysdep.S b/sysdeps/unix/alpha/sysdep.S index 3e7666ff61..6540b80af6 100644 --- a/sysdeps/unix/alpha/sysdep.S +++ b/sysdeps/unix/alpha/sysdep.S @@ -26,10 +26,10 @@ Cambridge, MA 02139, USA. */ #endif LEAF(__syscall_error, 0) + ldgp gp, 0(t12) .prologue 1 /* Store return value in errno... */ - ldgp gp, 0(t12) stl v0, errno /* And just kick back a -1. */ diff --git a/sysdeps/unix/alpha/sysdep.h b/sysdeps/unix/alpha/sysdep.h index 4b3f9aa5d8..72d84047c2 100644 --- a/sysdeps/unix/alpha/sysdep.h +++ b/sysdeps/unix/alpha/sysdep.h @@ -99,22 +99,12 @@ name/**/: \ #undef PSEUDO_END -#ifdef PIC -/* When building a shared library, we can use a branch since the text - section of the library is much smaller than 4MB. If we ever break - this assumption, the linker will tell us. */ -# define PSEUDO_END(sym) \ -1996: \ - br zero, __syscall_error; \ - END(sym) -#else -# define PSEUDO_END(sym) \ +#define PSEUDO_END(sym) \ 1996: \ br gp, 2f; \ 2: ldgp gp, 0(gp); \ jmp zero, __syscall_error; \ END(sym) -#endif #define r0 v0 #define r1 a4 diff --git a/sysdeps/unix/sysv/linux/alpha/init-first.h b/sysdeps/unix/sysv/linux/alpha/init-first.h new file mode 100644 index 0000000000..c27c589a28 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/init-first.h @@ -0,0 +1,12 @@ +/* This fragment is invoked in the stack context of program start. + Its job is to set up a pointer to argc as an argument, pass + control to `INIT', and, if necessary, clean up after the call + to leave the stack in the same condition it was found in. */ + +#define SYSDEP_CALL_INIT(NAME, INIT) \ + asm(".globl " #NAME "\n" \ + #NAME ":\n\t" \ + "ldgp $29, 0($27)\n\t" \ + ".prologue 1\n\t" \ + "mov $30, $16\n\t" \ + "br $31, " #INIT "..ng"); diff --git a/sysdeps/unix/sysv/linux/i386/init-first.h b/sysdeps/unix/sysv/linux/i386/init-first.h new file mode 100644 index 0000000000..f42d7f2533 --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/init-first.h @@ -0,0 +1,13 @@ +/* This fragment is invoked in the stack context of program start. + Its job is to set up a pointer to argc as an argument, pass + control to `INIT', and, if necessary, clean up after the call + to leave the stack in the same condition it was found in. */ + +#define SYSDEP_CALL_INIT(NAME, INIT) \ + asm(".globl " #NAME "\n\t" \ + #NAME ":\n\t" \ + "lea 4(%esp), %eax\n\t" \ + "pushl %eax\n\t" \ + "call " #INIT "\n\t" \ + "popl %eax\n\t" \ + "ret"); diff --git a/sysdeps/unix/sysv/linux/init-first.c b/sysdeps/unix/sysv/linux/init-first.c index 6d974ea1e6..a63200c1ae 100644 --- a/sysdeps/unix/sysv/linux/init-first.c +++ b/sysdeps/unix/sysv/linux/init-first.c @@ -19,23 +19,22 @@ Cambridge, MA 02139, USA. */ #include <unistd.h> #include <sysdep.h> -#include "fpu_control.h" - -/* This code is mostly the same for all machines. This version works at - least for i386 and m68k, and probably any CISCy machine with a normal - stack arrangement. */ +#include <fpu_control.h> +#include "init-first.h" extern void __libc_init (int, char **, char **); extern void __libc_global_ctors (void); +/* The function is called from assembly stubs the compiler can't see. */ +static void init (void *) __attribute__ ((unused)); static void -init (int *data) +init (void *data) { extern int __personality (int); - int argc = *data; - char **argv = (void *) (data + 1); + int argc = *(long *)data; + char **argv = (char **)data + 1; char **envp = &argv[argc + 1]; /* The `personality' system call takes one argument that chooses the @@ -50,33 +49,23 @@ init (int *data) __environ = envp; __libc_init (argc, argv, envp); + +#ifdef PIC + __libc_global_ctors (); +#endif } #ifdef PIC -/* This function is called to initialize the shared C library. - It is called just before the user _start code from i386/elf/start.S, - with the stack set up as that code gets it. */ -/* NOTE! The linker notices the magical name `_init' and sets the DT_INIT - pointer in the dynamic section based solely on that. It is convention - for this function to be in the `.init' section, but the symbol name is - the only thing that really matters!! */ -/*void _init (int argc, ...) __attribute__ ((unused, section (".init")));*/ +SYSDEP_CALL_INIT(_init, init); void -_init (int argc, ...) +__libc_init_first (void) { - init (&argc); - - __libc_global_ctors (); } -#endif +#else + +SYSDEP_CALL_INIT(__libc_init_first, init); -void -__libc_init_first (int argc __attribute__ ((unused)), ...) -{ -#ifndef PIC - init (&argc); #endif -} diff --git a/sysdeps/unix/sysv/linux/m68k/init-first.h b/sysdeps/unix/sysv/linux/m68k/init-first.h new file mode 100644 index 0000000000..7d8c320b0a --- /dev/null +++ b/sysdeps/unix/sysv/linux/m68k/init-first.h @@ -0,0 +1,12 @@ +/* This fragment is invoked in the stack context of program start. + Its job is to set up a pointer to argc as an argument, pass + control to `INIT', and, if necessary, clean up after the call + to leave the stack in the same condition it was found in. */ + +#define SYSDEP_CALL_INIT(NAME, INIT) \ + asm(".globl " #NAME "\n\t" \ + #NAME ":\n\t" \ + "pea %sp@(4)\n\t" \ + "jbsr " #INIT "\n\t" \ + "addq #4,%sp\n\t" \ + "rts"); |