2003-09-23  Ulrich Drepper  <drepper@redhat.com>

	* sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions [libc]
	(GLIBC_2.3.3): Add setcontext, getcontext, swapcontext, and
	makecontext.
	* sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h: Correct change
	for include Altivec support for PPC32.  It was not compatible.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/ucontext_i.h: Adjust
	offsets for ucontext_t change.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S: Adjust
	for ucontext_t change.  Add compatibility code.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S: Likewise.
	Patch by Paul Mackerras <paulus@samba.org>.

2003-02-25  Randolph Chung  <tausq@debian.org>

	* sysdeps/hppa/Makefile: Include compat code in build.
	* sysdeps/hppa/libgcc-compat.c: New file.
	* sysdeps/hppa/Dist: Add libgcc-compat.c.
	* sysdeps/hppa/Versions [GLIBC_2.2]: Add __clz_tab.
This commit is contained in:
Ulrich Drepper 2003-09-24 03:22:56 +00:00
parent 16a76cd23c
commit 54ee14b388
17 changed files with 294 additions and 37 deletions

View File

@ -1,3 +1,26 @@
2003-09-23 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions [libc]
(GLIBC_2.3.3): Add setcontext, getcontext, swapcontext, and
makecontext.
* sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h: Correct change
for include Altivec support for PPC32. It was not compatible.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/ucontext_i.h: Adjust
offsets for ucontext_t change.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S: Adjust
for ucontext_t change. Add compatibility code.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S: Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S: Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S: Likewise.
Patch by Paul Mackerras <paulus@samba.org>.
2003-02-25 Randolph Chung <tausq@debian.org>
* sysdeps/hppa/Makefile: Include compat code in build.
* sysdeps/hppa/libgcc-compat.c: New file.
* sysdeps/hppa/Dist: Add libgcc-compat.c.
* sysdeps/hppa/Versions [GLIBC_2.2]: Add __clz_tab.
2003-09-23 Roland McGrath <roland@redhat.com>
* elf/rtld.c (dl_main): In rtld_is_main case, reinitialize

View File

@ -1,3 +1,21 @@
2003-09-23 Jakub Jelinek <jakub@redhat.com>
* Makefile (tests): Only add tst-execstack if have-z-execstack is yes.
2003-09-23 Roland McGrath <roland@redhat.com>
* tst-execstack.c: New file.
* Makefile (tests): Add it.
($(objpfx)tst-execstack, $(objpfx)tst-execstack.out): New targets.
(LDFLAGS-tst-execstack): New variable.
* allocatestack.c (allocate_stack): Use GL(dl_stack_flags) to decide
whether to use PROT_EXEC for stack mmap.
(__make_stacks_executable): New function.
* pthreadP.h: Declare it.
* init.c (__pthread_initialize_minimal_internal): Set
GL(dl_make_stack_executable_hook) to that.
2003-09-22 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Adjust for latest

View File

@ -253,6 +253,9 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx4 tst-cancelx5 \
endif
ifeq ($(build-shared),yes)
tests += tst-atfork2 tst-tls3 tst-tls4 tst-tls5 tst-_res1
ifeq ($(have-z-execstack),yes)
tests += tst-execstack
endif
endif
modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \
@ -540,3 +543,7 @@ endif
endif
tst-exec4-ARGS = $(built-program-cmd)
$(objpfx)tst-execstack: $(libdl)
$(objpfx)tst-execstack.out: $(elf-objpfx)tst-execstack-mod.so
LDFLAGS-tst-execstack = -Wl,-z,noexecstack

View File

@ -351,11 +351,12 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
}
else
{
/* Allocate some anonymous memory. If possible use the
cache. */
/* Allocate some anonymous memory. If possible use the cache. */
size_t guardsize;
size_t reqsize;
void *mem;
const int prot = (PROT_READ | PROT_WRITE
| ((GL(dl_stack_flags) & PF_X) ? PROT_EXEC : 0));
#if COLORING_INCREMENT != 0
/* Add one more page for stack coloring. Don't do it for stacks
@ -392,7 +393,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
size += pagesize_m1 + 1;
#endif
mem = mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,
mem = mmap (NULL, size, prot,
MAP_PRIVATE | MAP_ANONYMOUS | ARCH_MAP_FLAGS, -1, 0);
if (__builtin_expect (mem == MAP_FAILED, 0))
@ -546,17 +547,16 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
char *oldguard = mem + (((size - pd->guardsize) / 2) & ~pagesize_m1);
if (oldguard < guard
&& mprotect (oldguard, guard - oldguard,
PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
&& mprotect (oldguard, guard - oldguard, prot) != 0)
goto mprot_error;
if (mprotect (guard + guardsize,
oldguard + pd->guardsize - guard - guardsize,
PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
prot) != 0)
goto mprot_error;
#else
if (mprotect ((char *) mem + guardsize, pd->guardsize - guardsize,
PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
prot) != 0)
goto mprot_error;
#endif
@ -616,6 +616,45 @@ __deallocate_stack (struct pthread *pd)
}
int
internal_function
__make_stacks_executable (void)
{
#ifdef NEED_SEPARATE_REGISTER_STACK
const size_t pagemask = ~(__getpagesize () - 1);
#endif
lll_lock (stack_cache_lock);
int err = 0;
list_t *runp;
list_for_each (runp, &stack_used)
{
struct pthread *const pd = list_entry (runp, struct pthread, list);
#ifdef NEED_SEPARATE_REGISTER_STACK
void *stack = (pd->stackblock
+ (((((pd->stackblock_size - pd->guardsize) / 2)
& pagemask) + pd->guardsize) & pagemask));
size_t len = pd->stackblock + pd->stackblock_size - stack;
#else
void *stack = pd->stackblock + pd->guardsize;
size_t len = pd->stackblock_size - pd->guardsize;
#endif
if (mprotect (stack, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
{
err = errno;
break;
}
}
lll_unlock (stack_cache_lock);
_dl_make_stack_executable ();
return err;
}
/* In case of a fork() call the memory allocation in the child will be
the same but only one thread is running. All stacks except that of
the one running thread are not used anymore. We have to recycle

View File

@ -283,6 +283,8 @@ __pthread_initialize_minimal_internal (void)
GL(dl_load_lock).mutex.__data.__count = 0;
while (rtld_lock_count-- > 0)
INTUSE (__pthread_mutex_lock) (&GL(dl_load_lock).mutex);
GL(dl_make_stack_executable_hook) = &__make_stacks_executable;
#endif
GL(dl_init_static_tls) = &__pthread_init_static_tls;

View File

@ -215,6 +215,9 @@ extern void __deallocate_stack (struct pthread *pd)
function also re-initializes the lock for the stack cache. */
extern void __reclaim_stacks (void) attribute_hidden;
/* Make all threads's stacks executable. */
int __make_stacks_executable (void) internal_function attribute_hidden;
/* longjmp handling. */
extern void __pthread_cleanup_upto (__jmp_buf target, char *targetframe);
#if defined NOT_IN_libc && defined IS_IN_libpthread

View File

@ -1,2 +1,3 @@
libgcc-compat.c
dl-symaddr.c
dl-fptr.c

View File

@ -31,3 +31,14 @@ CFLAGS-rtld.c += -mdisable-fpregs
dl-routines += dl-symaddr dl-fptr
rtld-routines += dl-symaddr dl-fptr
endif
ifeq ($(subdir),csu)
ifeq (yes,$(build-shared))
# Compatibility
ifeq (yes,$(have-protected))
CPPFLAGS-libgcc-compat.c = -DHAVE_DOT_HIDDEN
endif
sysdep_routines += libgcc-compat
shared-only-routines += libgcc-compat
endif
endif

View File

@ -5,3 +5,8 @@ ld {
_dl_function_address;
}
}
libc {
GLIBC_2.2 {
__clz_tab;
}
}

View File

@ -0,0 +1,43 @@
/* pre-.hidden libgcc compatibility
Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Randolph Chung
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 <stdint.h>
#include <shlib-compat.h>
#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_2_6)
symbol_version (__clz_tab_internal, __clz_tab, GLIBC_2.2);
typedef unsigned int UQItype __attribute__ ((mode (QI)));
const UQItype __clz_tab_internal[] =
{
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
};
#endif

View File

@ -22,5 +22,6 @@ libc {
}
GLIBC_2.3.3 {
posix_fadvise64; posix_fallocate64;
setcontext; getcontext; swapcontext; makecontext;
}
}

View File

@ -18,12 +18,20 @@
02111-1307 USA. */
#include <sysdep.h>
#include <shlib-compat.h>
#define __ASSEMBLY__
#include <asm/ptrace.h>
#include "ucontext_i.h"
ENTRY(__getcontext)
/*
* Since we are not attempting to save the altivec registers,
* there is no need to get the register storage space
* aligned on a 16-byte boundary.
*/
addi r3,r3,_UC_REG_SPACE
stw r3,_UC_REGS_PTR - _UC_REG_SPACE(r3)
stw r0,_UC_GREGS+(PT_R0*4)(r3)
stw r1,_UC_GREGS+(PT_R1*4)(r3)
mflr r0
@ -112,7 +120,7 @@ ENTRY(__getcontext)
stfd fp31,_UC_FREGS+(31*8)(r3)
stfd fp0,_UC_FREGS+(32*8)(r3)
addi r5,r3,_UC_SIGMASK
addi r5,r3,_UC_SIGMASK - _UC_REG_SPACE
li r4,0
li r3,SIG_BLOCK
bl JUMPTARGET(sigprocmask)
@ -123,4 +131,18 @@ ENTRY(__getcontext)
blr
PSEUDO_END(__getcontext)
weak_alias(__getcontext, getcontext)
versioned_symbol (libc, __getcontext, getcontext, GLIBC_2_3_3)
#if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_3_3)
#define _ERRNO_H 1
#include <bits/errno.h>
ENTRY (__getcontext_stub)
li r3,ENOSYS
b JUMPTARGET(__syscall_error)
END (__getcontext_stub)
compat_symbol (libc, __getcontext_stub, getcontext, GLIBC_2_1)
#endif

View File

@ -18,6 +18,7 @@
02111-1307 USA. */
#include <sysdep.h>
#include <shlib-compat.h>
#define __ASSEMBLY__
#include <asm/ptrace.h>
@ -25,22 +26,24 @@
ENTRY(__makecontext)
/* Set up the first 7 args to the function in its registers */
stw r6,_UC_GREGS+(PT_R3*4)(r3)
stw r7,_UC_GREGS+(PT_R4*4)(r3)
stw r8,_UC_GREGS+(PT_R5*4)(r3)
stw r9,_UC_GREGS+(PT_R6*4)(r3)
stw r10,_UC_GREGS+(PT_R7*4)(r3)
addi r11,r3,_UC_REG_SPACE
stw r11,_UC_REGS_PTR(r3)
stw r6,_UC_GREGS+(PT_R3*4)(r11)
stw r7,_UC_GREGS+(PT_R4*4)(r11)
stw r8,_UC_GREGS+(PT_R5*4)(r11)
stw r9,_UC_GREGS+(PT_R6*4)(r11)
stw r10,_UC_GREGS+(PT_R7*4)(r11)
lwz r8,8(r1)
lwz r9,12(r1)
stw r8,_UC_GREGS+(PT_R8*4)(r3)
stw r9,_UC_GREGS+(PT_R9*4)(r3)
stw r8,_UC_GREGS+(PT_R8*4)(r11)
stw r9,_UC_GREGS+(PT_R9*4)(r11)
/* Set the NIP to the start of the function */
stw r4,_UC_GREGS+(PT_NIP*4)(r3)
stw r4,_UC_GREGS+(PT_NIP*4)(r11)
/* Set the function's r31 to ucp->uc_link for the exitcode below. */
lwz r7,_UC_LINK(r3)
stw r7,_UC_GREGS+(PT_R31*4)(r3)
stw r7,_UC_GREGS+(PT_R31*4)(r11)
/* Set the function's LR to point to the exitcode below. */
#ifdef PIC
@ -53,7 +56,7 @@ ENTRY(__makecontext)
lis r6,L(exitcode)@ha
addi r6,r6,L(exitcode)@l
#endif
stw r6,_UC_GREGS+(PT_LNK*4)(r3)
stw r6,_UC_GREGS+(PT_LNK*4)(r11)
/*
* Set up the stack frame for the function.
@ -71,7 +74,7 @@ ENTRY(__makecontext)
cmpwi r5,8
blt 2f /* less than 8 args is easy */
lwz r10,16(r1)
stw r10,_UC_GREGS+(PT_R10*4)(r3)
stw r10,_UC_GREGS+(PT_R10*4)(r11)
beq 2f /* if exactly 8 args */
subi r9,r5,3
subi r5,r5,8
@ -83,7 +86,7 @@ ENTRY(__makecontext)
3: lwzu r10,4(r6)
stwu r10,4(r8)
bdnz 3b
2: stw r7,_UC_GREGS+(PT_R1*4)(r3)
2: stw r7,_UC_GREGS+(PT_R1*4)(r11)
li r6,0
stw r6,0(r7)
@ -102,4 +105,19 @@ L(exitcode):
b 4b
END(__makecontext)
weak_alias(__makecontext, makecontext)
versioned_symbol (libc, __makecontext, makecontext, GLIBC_2_3_3)
#if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_3_3)
#define _ERRNO_H 1
#include <bits/errno.h>
ENTRY (__makecontext_stub)
li r3,ENOSYS
b JUMPTARGET(__syscall_error)
END (__makecontext_stub)
compat_symbol (libc, __makecontext_stub, makecontext, GLIBC_2_1)
#endif

View File

@ -18,6 +18,7 @@
02111-1307 USA. */
#include <sysdep.h>
#include <shlib-compat.h>
#define __ASSEMBLY__
#include <asm/ptrace.h>
@ -28,7 +29,7 @@ ENTRY(__setcontext)
stwu r1,-16(r1)
stw r0,20(r1)
stw r31,12(r1)
mr r31,r3
lwz r31,_UC_REGS_PTR(r3)
/*
* If this ucontext refers to the point where we were interrupted
@ -144,6 +145,20 @@ L(do_sigret):
sc
/* NOTREACHED */
PSEUDO_END(__setcontext)
PSEUDO_END (__setcontext)
weak_alias(__setcontext, setcontext)
versioned_symbol (libc, __setcontext, setcontext, GLIBC_2_3_3)
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_3)
#define _ERRNO_H 1
#include <bits/errno.h>
ENTRY (__setcontext_stub)
li r3,ENOSYS
b JUMPTARGET(__syscall_error)
END (__setcontext_stub)
compat_symbol (libc, __setcontext_stub, setcontext, GLIBC_2_0)
#endif

View File

@ -18,6 +18,7 @@
02111-1307 USA. */
#include <sysdep.h>
#include <shlib-compat.h>
#define __ASSEMBLY__
#include <asm/ptrace.h>
@ -25,6 +26,8 @@
ENTRY(__swapcontext)
/* Save the current context */
addi r3,r3,_UC_REG_SPACE
stw r3,_UC_REGS_PTR - _UC_REG_SPACE(r3)
stw r0,_UC_GREGS+(PT_R0*4)(r3)
stw r1,_UC_GREGS+(PT_R1*4)(r3)
mflr r0
@ -115,7 +118,7 @@ ENTRY(__swapcontext)
stfd fp31,_UC_FREGS+(31*8)(r3)
stfd fp0,_UC_FREGS+(32*8)(r3)
addi r5,r3,_UC_SIGMASK
addi r5,r3,_UC_SIGMASK - _UC_REG_SPACE
addi r4,r4,_UC_SIGMASK
li r3,SIG_SETMASK
bl JUMPTARGET(sigprocmask)
@ -133,6 +136,8 @@ ENTRY(__swapcontext)
* r0, xer, ctr. We don't restore r2 since it will be used as
* the TLS pointer.
*/
mr r4,r31
lwz r31,_UC_REGS_PTR(r31)
lwz r0,_UC_GREGS+(PT_MSR*4)(r31)
cmpwi r0,0
bne L(do_sigret)
@ -223,11 +228,25 @@ L(error_exit):
blr
L(do_sigret):
addi r1,r31,-0xd0
addi r1,r4,-0xd0
li r0,SYS_ify(rt_sigreturn)
sc
/* NOTREACHED */
PSEUDO_END(__swapcontext)
weak_alias(__swapcontext, swapcontext)
versioned_symbol (libc, __swapcontext, swapcontext, GLIBC_2_3_3)
#if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_3_3)
#define _ERRNO_H 1
#include <bits/errno.h>
ENTRY (__swapcontext_stub)
li r3,ENOSYS
b JUMPTARGET(__syscall_error)
END (__swapcontext_stub)
compat_symbol (libc, __swapcontext_stub, swapcontext, GLIBC_2_1)
#endif

View File

@ -24,7 +24,11 @@
#define _UC_LINK 4
#define _UC_STACK_SP 8
#define _UC_STACK_SIZE 16
#define _UC_SIGMASK 64
#define _UC_GREGS 192
#define _UC_FREGS 384
#define _UC_VREGS 656
#define _UC_REGS_PTR 48
#define _UC_SIGMASK 52
#define _UC_REG_SPACE 180
/* offsets within mcontext_t */
#define _UC_GREGS 0
#define _UC_FREGS 192
#define _UC_VREGS 464

View File

@ -74,14 +74,40 @@ typedef struct ucontext
struct ucontext *uc_link;
stack_t uc_stack;
#if __WORDSIZE == 32
/* These fields are for backwards compatibility. */
/*
* These fields are set up this way to maximize source and
* binary compatibility with code written for the old
* ucontext_t definition, which didn't include space for the
* registers.
*
* Different versions of the kernel have stored the registers on
* signal delivery at different offsets from the ucontext struct.
* Programs should thus use the uc_mcontext.uc_regs pointer to
* find where the registers are actually stored. The registers
* will be stored within the ucontext_t struct but not necessarily
* at a fixed address. As a side-effect, this lets us achieve
* 16-byte alignment for the register storage space if the
* Altivec registers are to be saved, without requiring 16-byte
* alignment on the whole ucontext_t.
*
* The uc_mcontext.regs field is included for source compatibility
* with programs written against the older ucontext_t definition,
* and its name should therefore not change. The uc_pad field
* is for binary compatibility with programs compiled against the
* old ucontext_t; it ensures that uc_mcontext.regs and uc_sigmask
* are at the same offset as previously.
*/
int uc_pad[7];
mcontext_t *uc_regs;
unsigned int uc_oldsigmask[2];
int uc_pad2;
#endif
union uc_regs_ptr {
struct pt_regs *regs;
mcontext_t *uc_regs;
} uc_mcontext;
sigset_t uc_sigmask;
char uc_reg_space[sizeof(mcontext_t) + 12]; /* last for extensibility */
#else /* 64-bit */
sigset_t uc_sigmask;
mcontext_t uc_mcontext; /* last for extensibility */
#endif
} ucontext_t;
#endif /* sys/ucontext.h */