diff options
author | Jakub Jelinek <jakub@redhat.com> | 2005-02-08 10:05:09 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2005-02-08 10:05:09 +0000 |
commit | d585b66fa4d11059948f466c9080a6826932358d (patch) | |
tree | 8b06692920852c297635b46a7d616c3066f95fac /sysdeps/i386 | |
parent | e7cbcee4982d8caa809a91c9cfef5fda67445f0a (diff) |
Updated to fedora-glibc-20050208T0948cvs/fedora-glibc-2_3_4-6
Diffstat (limited to 'sysdeps/i386')
-rw-r--r-- | sysdeps/i386/Makefile | 4 | ||||
-rw-r--r-- | sysdeps/i386/bits/link.h | 65 | ||||
-rw-r--r-- | sysdeps/i386/bits/linkmap.h | 5 | ||||
-rw-r--r-- | sysdeps/i386/dl-machine.h | 149 | ||||
-rw-r--r-- | sysdeps/i386/dl-trampoline.S | 182 |
5 files changed, 279 insertions, 126 deletions
diff --git a/sysdeps/i386/Makefile b/sysdeps/i386/Makefile index 52faaa3109..ece94f3610 100644 --- a/sysdeps/i386/Makefile +++ b/sysdeps/i386/Makefile @@ -61,3 +61,7 @@ CFLAGS-dlopenold.c += -mpreferred-stack-boundary=4 CFLAGS-dlclose.c += -mpreferred-stack-boundary=4 CFLAGS-dlerror.c += -mpreferred-stack-boundary=4 endif + +ifneq (,$(filter -mno-tls-direct-seg-refs,$(CFLAGS))) +defines += -DNO_TLS_DIRECT_SEG_REFS +endif diff --git a/sysdeps/i386/bits/link.h b/sysdeps/i386/bits/link.h index 3be9b7eae8..985d040413 100644 --- a/sysdeps/i386/bits/link.h +++ b/sysdeps/i386/bits/link.h @@ -1,5 +1,60 @@ -struct link_map_machine - { - Elf32_Addr plt; /* Address of .plt + 0x16 */ - Elf32_Addr gotplt; /* Address of .got + 0x0c */ - }; +/* Copyright (C) 2004, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _LINK_H +# error "Never include <bits/link.h> directly; use <link.h> instead." +#endif + + +/* Registers for entry into PLT on IA-32. */ +typedef struct La_i86_regs +{ + uint32_t lr_edx; + uint32_t lr_ecx; + uint32_t lr_eax; + uint32_t lr_ebp; + uint32_t lr_esp; +} La_i86_regs; + +/* Return values for calls from PLT on IA-32. */ +typedef struct La_i86_retval +{ + uint32_t lrv_eax; + uint32_t lrv_edx; + long double lrv_st0; + long double lrv_st1; +} La_i86_retval; + + +__BEGIN_DECLS + +extern Elf32_Addr la_i86_gnu_pltenter (Elf32_Sym *__sym, unsigned int __ndx, + uintptr_t *__refcook, + uintptr_t *__defcook, + La_i86_regs *__regs, + unsigned int *__flags, + const char *__symname, + long int *__framesizep); +extern unsigned int la_i86_gnu_pltexit (Elf32_Sym *__sym, unsigned int __ndx, + uintptr_t *__refcook, + uintptr_t *__defcook, + const La_i86_regs *__inregs, + La_i86_retval *__outregs, + const char *symname); + +__END_DECLS diff --git a/sysdeps/i386/bits/linkmap.h b/sysdeps/i386/bits/linkmap.h new file mode 100644 index 0000000000..3be9b7eae8 --- /dev/null +++ b/sysdeps/i386/bits/linkmap.h @@ -0,0 +1,5 @@ +struct link_map_machine + { + Elf32_Addr plt; /* Address of .plt + 0x16 */ + Elf32_Addr gotplt; /* Address of .got + 0x0c */ + }; diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h index c48d9d325e..78c083f6ab 100644 --- a/sysdeps/i386/dl-machine.h +++ b/sysdeps/i386/dl-machine.h @@ -1,5 +1,5 @@ /* Machine-dependent ELF dynamic relocation inline functions. i386 version. - Copyright (C) 1995-2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 1995-2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -129,7 +129,8 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) { got[2] = (Elf32_Addr) &_dl_runtime_profile; - if (_dl_name_match_p (GLRO(dl_profile), l)) + if (GLRO(dl_profile) != NULL + && _dl_name_match_p (GLRO(dl_profile), l)) /* This is the object we are looking for. Say that we really want profiling and the timers are started. */ GL(dl_profile_map) = l; @@ -154,112 +155,18 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) destroys the passed register information. */ /* GKM FIXME: Fix trampoline to pass bounds so we can do without the `__unbounded' qualifier. */ -#define ARCH_FIXUP_ATTRIBUTE __attribute__ ((regparm (3), unused)) +#define ARCH_FIXUP_ATTRIBUTE __attribute__ ((regparm (3), stdcall, unused)) -static ElfW(Addr) fixup (struct link_map *__unbounded l, - ElfW(Word) reloc_offset) +extern ElfW(Addr) _dl_fixup (struct link_map *__unbounded l, + ElfW(Word) reloc_offset) ARCH_FIXUP_ATTRIBUTE; -static ElfW(Addr) profile_fixup (struct link_map *l, ElfW(Word) reloc_offset, - ElfW(Addr) retaddr) +extern ElfW(Addr) _dl_profile_fixup (struct link_map *l, + ElfW(Word) reloc_offset, + ElfW(Addr) retaddr, void *regs, + long int *framesizep) ARCH_FIXUP_ATTRIBUTE; # endif -/* This code is used in dl-runtime.c to call the `fixup' function - and then redirect to the address it returns. */ -# if !defined PROF && !__BOUNDED_POINTERS__ -# define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\ - .text\n\ - .globl _dl_runtime_resolve\n\ - .type _dl_runtime_resolve, @function\n\ - " CFI_STARTPROC "\n\ - .align 16\n\ -_dl_runtime_resolve:\n\ - " CFI_ADJUST_CFA_OFFSET (8) "\n\ - pushl %eax # Preserve registers otherwise clobbered.\n\ - " CFI_ADJUST_CFA_OFFSET (4) "\n\ - pushl %ecx\n\ - " CFI_ADJUST_CFA_OFFSET (4) "\n\ - pushl %edx\n\ - " CFI_ADJUST_CFA_OFFSET (4) "\n\ - movl 16(%esp), %edx # Copy args pushed by PLT in register. Note\n\ - movl 12(%esp), %eax # that `fixup' takes its parameters in regs.\n\ - call fixup # Call resolver.\n\ - popl %edx # Get register content back.\n\ - " CFI_ADJUST_CFA_OFFSET (-4) "\n\ - popl %ecx\n\ - " CFI_ADJUST_CFA_OFFSET (-4) "\n\ - xchgl %eax, (%esp) # Get %eax contents end store function address.\n\ - ret $8 # Jump to function address.\n\ - " CFI_ENDPROC "\n\ - .size _dl_runtime_resolve, .-_dl_runtime_resolve\n\ -\n\ - .globl _dl_runtime_profile\n\ - .type _dl_runtime_profile, @function\n\ - " CFI_STARTPROC "\n\ - .align 16\n\ -_dl_runtime_profile:\n\ - " CFI_ADJUST_CFA_OFFSET (8) "\n\ - pushl %eax # Preserve registers otherwise clobbered.\n\ - " CFI_ADJUST_CFA_OFFSET (4) "\n\ - pushl %ecx\n\ - " CFI_ADJUST_CFA_OFFSET (4) "\n\ - pushl %edx\n\ - " CFI_ADJUST_CFA_OFFSET (4) "\n\ - movl 20(%esp), %ecx # Load return address\n\ - movl 16(%esp), %edx # Copy args pushed by PLT in register. Note\n\ - movl 12(%esp), %eax # that `fixup' takes its parameters in regs.\n\ - call profile_fixup # Call resolver.\n\ - popl %edx # Get register content back.\n\ - " CFI_ADJUST_CFA_OFFSET (-4) "\n\ - popl %ecx\n\ - " CFI_ADJUST_CFA_OFFSET (-4) "\n\ - xchgl %eax, (%esp) # Get %eax contents end store function address.\n\ - ret $8 # Jump to function address.\n\ - " CFI_ENDPROC "\n\ - .size _dl_runtime_profile, .-_dl_runtime_profile\n\ - .previous\n\ -"); -# else -# define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\n\ - .text\n\ - .globl _dl_runtime_resolve\n\ - .globl _dl_runtime_profile\n\ - .type _dl_runtime_resolve, @function\n\ - .type _dl_runtime_profile, @function\n\ - " CFI_STARTPROC "\n\ - .align 16\n\ -_dl_runtime_resolve:\n\ -_dl_runtime_profile:\n\ - " CFI_ADJUST_CFA_OFFSET (8) "\n\ - pushl %eax # Preserve registers otherwise clobbered.\n\ - " CFI_ADJUST_CFA_OFFSET (4) "\n\ - pushl %ecx\n\ - " CFI_ADJUST_CFA_OFFSET (4) "\n\ - pushl %edx\n\ - " CFI_ADJUST_CFA_OFFSET (4) "\n\ - movl 16(%esp), %edx # Push the arguments for `fixup'\n\ - movl 12(%esp), %eax\n\ - pushl %edx\n\ - " CFI_ADJUST_CFA_OFFSET (4) "\n\ - pushl %eax\n\ - " CFI_ADJUST_CFA_OFFSET (4) "\n\ - call fixup # Call resolver.\n\ - popl %edx # Pop the parameters\n\ - " CFI_ADJUST_CFA_OFFSET (-4) "\n\ - popl %ecx\n\ - " CFI_ADJUST_CFA_OFFSET (-4) "\n\ - popl %edx # Get register content back.\n\ - " CFI_ADJUST_CFA_OFFSET (-4) "\n\ - popl %ecx\n\ - " CFI_ADJUST_CFA_OFFSET (-4) "\n\ - xchgl %eax, (%esp) # Get %eax contents end store function address.\n\ - ret $8 # Jump to function address.\n\ - " CFI_ENDPROC "\n\ - .size _dl_runtime_resolve, .-_dl_runtime_resolve\n\ - .size _dl_runtime_profile, .-_dl_runtime_profile\n\ - .previous\n\ -"); -# endif #endif /* Mask identifying addresses reserved for the user program, @@ -308,11 +215,21 @@ _dl_start_user:\n\ movl _rtld_local@GOTOFF(%ebx), %eax\n\ leal 8(%esp,%edx,4), %esi\n\ leal 4(%esp), %ecx\n\ + movl %esp, %ebp\n\ + # Make sure _dl_init is run with 16 byte aligned stack.\n\ + andl $-16, %esp\n\ + pushl %eax\n\ + pushl %eax\n\ + pushl %ebp\n\ pushl %esi\n\ + # Clear %ebp, so that even constructors have terminated backchain.\n\ + xorl %ebp, %ebp\n\ # Call the function to run the initializers.\n\ call _dl_init_internal@PLT\n\ # Pass our finalizer function to the user in %edx, as per ELF ABI.\n\ leal _dl_fini@GOTOFF(%ebx), %edx\n\ + # Restore %esp _start expects.\n\ + movl (%esp), %esp\n\ # Jump to the user's entry point.\n\ jmp *%edi\n\ .previous\n\ @@ -375,9 +292,14 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rel *reloc, return value; } + +/* Names of the architecture-specific auditing callback functions. */ +#define ARCH_LA_PLTENTER i86_gnu_pltenter +#define ARCH_LA_PLTEXIT i86_gnu_pltexit + #endif /* !dl_machine_h */ -#ifdef RESOLVE +#ifdef RESOLVE_MAP /* The i386 never uses Elf32_Rela relocations for the dynamic linker. Prelinked libraries may use Elf32_Rela though. */ @@ -422,17 +344,8 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, #endif /* !RTLD_BOOTSTRAP and have no -z combreloc */ { const Elf32_Sym *const refsym = sym; -#if defined USE_TLS && !defined RTLD_BOOTSTRAP struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); - Elf32_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value; -#else - Elf32_Addr value = RESOLVE (&sym, version, r_type); - -# ifndef RTLD_BOOTSTRAP - if (sym != NULL) -# endif - value += sym->st_value; -#endif /* use TLS and !RTLD_BOOTSTRAP */ + Elf32_Addr value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value; switch (r_type) { @@ -549,14 +462,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, # ifndef RESOLVE_CONFLICT_FIND_MAP const Elf32_Sym *const refsym = sym; # endif -# ifdef USE_TLS struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); Elf32_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value; -# else - Elf32_Addr value = RESOLVE (&sym, version, r_type); - if (sym != NULL) - value += sym->st_value; -# endif switch (ELF32_R_TYPE (reloc->r_info)) { @@ -692,4 +599,4 @@ elf_machine_lazy_rela (struct link_map *map, #endif /* !RTLD_BOOTSTRAP */ -#endif /* RESOLVE */ +#endif /* RESOLVE_MAP */ diff --git a/sysdeps/i386/dl-trampoline.S b/sysdeps/i386/dl-trampoline.S new file mode 100644 index 0000000000..80dd300e86 --- /dev/null +++ b/sysdeps/i386/dl-trampoline.S @@ -0,0 +1,182 @@ +/* PLT trampolines. i386 version. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> + + .text + .globl _dl_runtime_resolve + .type _dl_runtime_resolve, @function + cfi_startproc + .align 16 +_dl_runtime_resolve: + cfi_adjust_cfa_offset (8) + pushl %eax # Preserve registers otherwise clobbered. + cfi_adjust_cfa_offset (4) + pushl %ecx + cfi_adjust_cfa_offset (4) + pushl %edx + cfi_adjust_cfa_offset (4) + movl 16(%esp), %edx # Copy args pushed by PLT in register. Note + movl 12(%esp), %eax # that `fixup' takes its parameters in regs. + call _dl_fixup # Call resolver. + popl %edx # Get register content back. + cfi_adjust_cfa_offset (-4) + popl %ecx + cfi_adjust_cfa_offset (-4) + xchgl %eax, (%esp) # Get %eax contents end store function address. + ret $8 # Jump to function address. + cfi_endproc + .size _dl_runtime_resolve, .-_dl_runtime_resolve + + + .globl _dl_runtime_profile + .type _dl_runtime_profile, @function + cfi_startproc + .align 16 +_dl_runtime_profile: + cfi_adjust_cfa_offset (8) + pushl %esp + cfi_adjust_cfa_offset (4) + addl $8, (%esp) # Account for the pushed PLT data + pushl %ebp + cfi_adjust_cfa_offset (4) + pushl %eax # Preserve registers otherwise clobbered. + cfi_adjust_cfa_offset (4) + pushl %ecx + cfi_adjust_cfa_offset (4) + pushl %edx + cfi_adjust_cfa_offset (4) + movl %esp, %ecx + subl $8, %esp + cfi_adjust_cfa_offset (8) + movl $-1, 4(%esp) + leal 4(%esp), %edx + movl %edx, (%esp) + pushl %ecx # Address of the register structure + cfi_adjust_cfa_offset (4) + movl 40(%esp), %ecx # Load return address + movl 36(%esp), %edx # Copy args pushed by PLT in register. Note + movl 32(%esp), %eax # that `fixup' takes its parameters in regs. + call _dl_profile_fixup # Call resolver. + cfi_adjust_cfa_offset (-8) + movl (%esp), %edx + testl %edx, %edx + jns 1f + popl %edx + cfi_adjust_cfa_offset (-4) + popl %edx # Get register content back. + cfi_adjust_cfa_offset (-4) + popl %ecx + cfi_adjust_cfa_offset (-4) + xchgl %eax, (%esp) # Get %eax contents end store function address. + ret $16 # Jump to function address. + + /* + +32 return address + +28 PLT1 + +24 PLT2 + +20 %esp + +16 %ebp + +12 %eax + +8 %ecx + +4 %edx + %esp free + */ + cfi_adjust_cfa_offset (12) +1: movl %ebx, (%esp) + cfi_rel_offset (3, 0) + movl %edx, %ebx # This is the frame buffer size + pushl %edi + cfi_adjust_cfa_offset (4) + cfi_rel_offset (7, 0) + pushl %esi + cfi_adjust_cfa_offset (4) + cfi_rel_offset (6, 0) + leal 44(%esp), %esi + movl %ebx, %ecx + movl %esp, %edi + subl %ebx, %edi + andl $0xfffffff0, %edi # Align stack + movl %esp, %ebx + cfi_def_cfa_register (3) + movl %edi, %esp + shrl $2, %ecx + rep + movsl + movl (%edi), %esi + cfi_restore (6) + movl 4(%edi), %edi + cfi_restore (7) + /* + %ebx+40 return address + %ebx+36 PLT1 + %ebx+32 PLT2 + %ebx+28 %esp + %ebx+24 %ebp + %ebx+20 %eax + %ebx+16 %ecx + %ebx+12 %edx + %ebx+8 %ebx + %ebx+4 free + %ebx free + %esp copied stack frame + */ + movl %eax, (%ebx) + movl 12(%ebx), %edx + movl 16(%ebx), %ecx + movl 20(%ebx), %eax + call *(%ebx) + movl %ebx, %esp + cfi_def_cfa_register (4) + movl 8(%esp), %ebx + cfi_restore (3) + /* + +40 return address + +36 PLT1 + +32 PLT2 + +28 %esp + +24 %ebp + +20 %eax + +16 %ecx + +12 %edx + +8 free + +4 free + %esp free + */ + subl $20, %esp + cfi_adjust_cfa_offset (20) + movl %eax, (%esp) + movl %edx, 4(%esp) + fstpt 8(%esp) + fstpt 20(%esp) + pushl %esp + cfi_adjust_cfa_offset (4) + leal 36(%esp), %ecx + movl 56(%esp), %eax + movl 60(%esp), %edx + call _dl_call_pltexit + movl (%esp), %eax + movl 4(%esp), %edx + fldt 20(%esp) + fldt 8(%esp) + addl $60, %esp + cfi_adjust_cfa_offset (-60) + ret + cfi_endproc + .size _dl_runtime_profile, .-_dl_runtime_profile |