diff options
author | Andreas Schwab <aschwab@redhat.com> | 2009-06-10 14:04:22 +0200 |
---|---|---|
committer | Andreas Schwab <aschwab@redhat.com> | 2009-06-10 14:04:22 +0200 |
commit | 0d02cb10e8dd8639b86450cf8e597cf5e2e09894 (patch) | |
tree | 0f2174db43a501b946f0600d1b91ae4117977b04 /sysdeps/i386 | |
parent | dfbbe67270efa9c03f9444d50d2f98a7a64622b4 (diff) | |
parent | 88ea382fda5af7717f85bb19837c9c99094f3df4 (diff) |
Merge commit 'origin/master' into fedora/master
Conflicts:
ChangeLog
sysdeps/unix/sysv/linux/i386/sysconf.c
sysdeps/x86_64/cacheinfo.c
version.h
Diffstat (limited to 'sysdeps/i386')
-rw-r--r-- | sysdeps/i386/____longjmp_chk.S | 45 | ||||
-rw-r--r-- | sysdeps/i386/__longjmp.S | 12 | ||||
-rw-r--r-- | sysdeps/i386/dl-irel.h | 45 | ||||
-rw-r--r-- | sysdeps/i386/dl-machine.h | 26 |
4 files changed, 126 insertions, 2 deletions
diff --git a/sysdeps/i386/____longjmp_chk.S b/sysdeps/i386/____longjmp_chk.S new file mode 100644 index 0000000000..6cd74968a2 --- /dev/null +++ b/sysdeps/i386/____longjmp_chk.S @@ -0,0 +1,45 @@ +/* Copyright (C) 2001,2004,2005,2006,2009 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. */ + + .section .rodata.str1.1,"aMS",@progbits,1 + .type longjmp_msg,@object +longjmp_msg: + .string "longjmp causes uninitialized stack frame" + .size longjmp_msg, .-longjmp_msg + + +#define __longjmp ____longjmp_chk + +#ifdef PIC +# define CALL_FAIL movl %ebx, %ecx; \ + cfi_register(%ebx,%ecx); \ + LOAD_PIC_REG (bx); \ + leal longjmp_msg@GOTOFF(%ebx), %eax; \ + call __GI___fortify_fail@PLT +#else +# define CALL_FAIL movl $longjmp_msg, %eax; \ + call __fortify_fail +#endif + +#define CHECK_ESP(reg) \ + cmpl reg, %esp; \ + jbe .Lok; \ + CALL_FAIL; \ +.Lok: + +#include "__longjmp.S" diff --git a/sysdeps/i386/__longjmp.S b/sysdeps/i386/__longjmp.S index 559d56b250..8b0732056a 100644 --- a/sysdeps/i386/__longjmp.S +++ b/sysdeps/i386/__longjmp.S @@ -1,5 +1,6 @@ /* longjmp for i386. - Copyright (C) 1995-1998,2000,2002,2005, 2006 Free Software Foundation, Inc. + Copyright (C) 1995-1998,2000,2002,2005,2006,2009 + 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 @@ -27,6 +28,7 @@ #define JBUF PARMS #define VAL JBUF+PTR_SIZE + .text ENTRY (BP_SYM (__longjmp)) ENTER @@ -40,6 +42,9 @@ ENTRY (BP_SYM (__longjmp)) movl (JB_SP*4)(%eax), %ecx PTR_DEMANGLE (%edx) PTR_DEMANGLE (%ecx) +# ifdef CHECK_ESP + CHECK_ESP (%ecx) +# endif cfi_def_cfa(%eax, 0) cfi_register(%eip, %edx) cfi_register(%esp, %ecx) @@ -63,6 +68,11 @@ ENTRY (BP_SYM (__longjmp)) movl JBUF(%esp), %ecx /* User's jmp_buf in %ecx. */ CHECK_BOUNDS_BOTH_WIDE (%ecx, JBUF(%esp), $JB_SIZE) +# ifdef CHECK_ESP + movl (JB_SP*4)(%ecx), %eax + CHECK_ESP (%eax) +# endif + movl VAL(%esp), %eax /* Second argument is return value. */ /* Save the return address now. */ movl (JB_PC*4)(%ecx), %edx diff --git a/sysdeps/i386/dl-irel.h b/sysdeps/i386/dl-irel.h new file mode 100644 index 0000000000..810a35050b --- /dev/null +++ b/sysdeps/i386/dl-irel.h @@ -0,0 +1,45 @@ +/* Machine-dependent ELF indirect relocation inline functions. + i386 version. + Copyright (C) 2009 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 _DL_IREL_H +#define _DL_IREL_H + +#include <stdio.h> +#include <unistd.h> + +#define ELF_MACHINE_IREL 1 + +static inline void +__attribute ((always_inline)) +elf_irel (const Elf32_Rel *reloc) +{ + Elf32_Addr *const reloc_addr = (void *) reloc->r_offset; + const unsigned long int r_type = ELF32_R_TYPE (reloc->r_info); + + if (__builtin_expect (r_type == R_386_IRELATIVE, 1)) + { + Elf64_Addr value = ((Elf32_Addr (*) (void)) (*reloc_addr)) (); + *reloc_addr = value; + } + else + __libc_fatal ("unexpected reloc type in static binary"); +} + +#endif /* dl-irel.h */ diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h index 0e15878d4e..a093d2b151 100644 --- a/sysdeps/i386/dl-machine.h +++ b/sysdeps/i386/dl-machine.h @@ -346,7 +346,8 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, if (sym != NULL && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, - 0)) + 0) + && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1)) value = ((Elf32_Addr (*) (void)) value) (); switch (r_type) @@ -471,6 +472,11 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, memcpy (reloc_addr_arg, (void *) value, MIN (sym->st_size, refsym->st_size)); break; + case R_386_IRELATIVE: + value = map->l_addr + *reloc_addr; + value = ((Elf32_Addr (*) (void)) value) (); + *reloc_addr = value; + break; default: _dl_reloc_bad_type (map, r_type, 0); break; @@ -500,6 +506,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, Elf32_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value; if (sym != NULL + && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1) && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)) value = ((Elf32_Addr (*) (void)) value) (); @@ -609,6 +616,11 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, MIN (sym->st_size, refsym->st_size)); break; # endif /* !RESOLVE_CONFLICT_FIND_MAP */ + case R_386_IRELATIVE: + value = map->l_addr + reloc->r_addend; + value = ((Elf32_Addr (*) (void)) value) (); + *reloc_addr = value; + break; default: /* We add these checks in the version to relocate ld.so only if we are still debugging. */ @@ -703,6 +715,12 @@ elf_machine_lazy_rel (struct link_map *map, # endif } } + else if (__builtin_expect (r_type == R_386_IRELATIVE, 0)) + { + Elf32_Addr value = map->l_addr + *reloc_addr; + value = ((Elf32_Addr (*) (void)) value) (); + *reloc_addr = value; + } else _dl_reloc_bad_type (map, r_type, 1); } @@ -726,6 +744,12 @@ elf_machine_lazy_rela (struct link_map *map, td->arg = (void*)reloc; td->entry = _dl_tlsdesc_resolve_rela; } + else if (__builtin_expect (r_type == R_386_IRELATIVE, 0)) + { + Elf32_Addr value = map->l_addr + reloc->r_addend; + value = ((Elf32_Addr (*) (void)) value) (); + *reloc_addr = value; + } else _dl_reloc_bad_type (map, r_type, 1); } |