From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11202 invoked by alias); 2 Jan 2006 15:48:38 -0000 Received: (qmail 11186 invoked by uid 22791); 2 Jan 2006 15:48:37 -0000 X-Spam-Check-By: sourceware.org Received: from sunsite.ms.mff.cuni.cz (HELO sunsite.mff.cuni.cz) (195.113.15.26) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 02 Jan 2006 15:48:35 +0000 Received: from sunsite.mff.cuni.cz (sunsite.mff.cuni.cz [127.0.0.1]) by sunsite.mff.cuni.cz (8.13.1/8.13.1) with ESMTP id k02FmTcg024171; Mon, 2 Jan 2006 16:48:29 +0100 Received: (from jakub@localhost) by sunsite.mff.cuni.cz (8.13.1/8.13.1/Submit) id k02FmTIb024170; Mon, 2 Jan 2006 16:48:29 +0100 Date: Mon, 02 Jan 2006 15:48:00 -0000 From: Jakub Jelinek To: Ulrich Drepper Cc: Glibc hackers Subject: [PATCH] sparc setjmp/longjmp mangling Message-ID: <20060102154829.GL4625@sunsite.mff.cuni.cz> Reply-To: Jakub Jelinek Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.1i Mailing-List: contact libc-hacker-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sourceware.org X-SW-Source: 2006-01/txt/msg00003.txt.bz2 Hi! Pointer mangling for sparc{32,64} and setjmp/longjmp mangling on sparc32. On sparc64, setjmp/longjmp are syscalls (well, actually just traps into kernel), so mangling isn't (easily) feasible there. 2006-01-02 Jakub Jelinek * sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h (PTR_MANGLE, PTR_MANGLE2, PTR_DEMANGLE, PTR_DEMANGLE2): Define. * sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h (PTR_MANGLE, PTR_MANGLE2, PTR_DEMANGLE, PTR_DEMANGLE2): Define. * sysdeps/unix/sysv/linux/sparc/bits/setjmp.h [__WORDSIZE == 64] (_JMPBUF_UNWINDS): Don't demangle uc_mcontext.mc_fp. * sysdeps/sparc/sparc32/setjmp.S (__sigsetjmp): Mangle %fp, %sp and %o7. * sysdeps/sparc/sparc32/__longjmp.S (__longjmp): Demangle %fp, %sp and %o7. nptl/ * sysdeps/sparc/tls.h (tcbhead_t): Add pointer_guard field. (THREAD_GET_POINTER_GUARD, THREAD_SET_POINTER_GUARD, THREAD_COPY_POINTER_GUARD): Define. * sysdeps/sparc/tcb-offsets.sym (POINTER_GUARD): Define. * sysdeps/sparc/sparc64/jmpbuf-unwind.h: Revert 2005-12-27 changes. --- libc/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h.jj 2004-10-05 03:05:02.000000000 -0400 +++ libc/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h 2006-01-02 06:45:25.000000000 -0500 @@ -1,4 +1,4 @@ -/* Copyright (C) 1997, 2002, 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 1997, 2002, 2003, 2004, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Miguel de Icaza , January 1997. @@ -214,4 +214,24 @@ SYSCALL_ERROR_HANDLER_ENTRY(__syscall_er #endif /* __ASSEMBLER__ */ +/* Pointer mangling support. */ +#if defined NOT_IN_libc && defined IS_IN_rtld +/* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ +#else +# ifdef __ASSEMBLER__ +# define PTR_MANGLE(dreg, reg, tmpreg) \ + ld [%g7 + POINTER_GUARD], tmpreg; \ + xor reg, tmpreg, dreg +# define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg) +# define PTR_MANGLE2(dreg, reg, tmpreg) \ + xor reg, tmpreg, dreg +# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg) +# else +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ()) +# define PTR_DEMANGLE(var) PTR_MANGLE (var) +# endif +#endif + #endif /* linux/sparc/sysdep.h */ --- libc/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h.jj 2005-06-06 08:36:17.000000000 -0400 +++ libc/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h 2006-01-02 06:45:25.000000000 -0500 @@ -240,4 +240,24 @@ SYSCALL_ERROR_HANDLER_ENTRY(__syscall_er register windows. So if you poke stack memory directly you add this. */ #define STACK_BIAS 2047 +/* Pointer mangling support. */ +#if defined NOT_IN_libc && defined IS_IN_rtld +/* We cannot use the thread descriptor because in ld.so we use setjmp + earlier than the descriptor is initialized. */ +#else +# ifdef __ASSEMBLER__ +# define PTR_MANGLE(dreg, reg, tmpreg) \ + ldx [%g7 + POINTER_GUARD], tmpreg; \ + xor reg, tmpreg, dreg +# define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg) +# define PTR_MANGLE2(dreg, reg, tmpreg) \ + xor reg, tmpreg, dreg +# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg) +# else +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ THREAD_GET_POINTER_GUARD ()) +# define PTR_DEMANGLE(var) PTR_MANGLE (var) +# endif +#endif + #endif /* linux/sparc64/sysdep.h */ --- libc/sysdeps/unix/sysv/linux/sparc/bits/setjmp.h.jj 2005-12-30 03:04:17.000000000 -0500 +++ libc/sysdeps/unix/sysv/linux/sparc/bits/setjmp.h 2006-01-02 06:45:25.000000000 -0500 @@ -1,4 +1,5 @@ -/* Copyright (C) 1997,1999,2000,2003, 2005 Free Software Foundation, Inc. +/* Copyright (C) 1997, 1999, 2000, 2003, 2005, 2006 + 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 @@ -60,7 +61,7 @@ typedef struct __sparc64_jmp_buf /* Test if longjmp to JMPBUF would unwind the frame containing a local variable at ADDRESS. */ #define _JMPBUF_UNWINDS(jmpbuf, address, demangle) \ - ((unsigned long int) (address) < demangle ((jmpbuf)->uc_mcontext.mc_fp)) + ((unsigned long int) (address) < (jmpbuf)->uc_mcontext.mc_fp) #else --- libc/sysdeps/sparc/sparc32/setjmp.S.jj 2002-12-31 15:37:25.000000000 -0500 +++ libc/sysdeps/sparc/sparc32/setjmp.S 2006-01-02 06:45:25.000000000 -0500 @@ -1,4 +1,5 @@ -/* Copyright (C) 1991, 93, 94, 96, 97, 98, 2002 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1993, 1994, 1996, 1997, 1998, 2002, 2006 + 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 @@ -39,9 +40,18 @@ ENTRY (__sigsetjmp) a tail-call for simplicity; it always returns zero. */ ta ST_FLUSH_WINDOWS +#ifdef PTR_MANGLE + PTR_MANGLE (%g1, %o7, %g4) + PTR_MANGLE2 (%g2, %sp, %g4) + PTR_MANGLE2 (%g3, %fp, %g4) + st %g1, [%o0 + (JB_PC * 4)] + st %g2, [%o0 + (JB_SP * 4)] + st %g3, [%o0 + (JB_FP * 4)] +#else st %o7, [%o0 + (JB_PC * 4)] st %sp, [%o0 + (JB_SP * 4)] st %fp, [%o0 + (JB_FP * 4)] +#endif mov %o7, %g1 call __sigjmp_save --- libc/sysdeps/sparc/sparc32/__longjmp.S.jj 2001-07-06 00:56:04.000000000 -0400 +++ libc/sysdeps/sparc/sparc32/__longjmp.S 2006-01-02 06:45:25.000000000 -0500 @@ -1,4 +1,5 @@ -/* Copyright (C) 1991, 93, 96, 97, 98, 99, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1993, 1996, 1997, 1998, 1999, 2000, 2006 + 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 @@ -30,6 +31,9 @@ ENTRY(__longjmp) use them while unwinding frames and their register windows. */ ld ENV(o0,JB_FP), %g3 /* Cache target FP in register %g3. */ +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (%g3, %g3, %g4) +#endif mov %o0, %g1 /* ENV in %g1 */ orcc %o1, %g0, %g2 /* VAL in %g2 */ be,a 0f /* Branch if zero; else skip delay slot. */ @@ -62,8 +66,15 @@ LOC(thread): * windows. */ ta ST_FLUSH_WINDOWS +#ifdef PTR_DEMANGLE + ld ENV(g1,JB_PC), %g5 /* Set return PC. */ + ld ENV(g1,JB_SP), %g1 /* Set saved SP on restore below. */ + PTR_DEMANGLE2 (%o7, %g5, %g4) + PTR_DEMANGLE2 (%fp, %g1, %g4) +#else ld ENV(g1,JB_PC), %o7 /* Set return PC. */ ld ENV(g1,JB_SP), %fp /* Set saved SP on restore below. */ +#endif sub %fp, 64, %sp /* Allocate a register frame. */ st %g3, RW_FP /* Set saved FP on restore below. */ retl @@ -71,10 +82,17 @@ LOC(thread): LOC(found): /* We have unwound register windows so %fp matches the target. */ +#ifdef PTR_DEMANGLE + PTR_DEMANGLE2 (%sp, %o0, %g4) +#else mov %o0, %sp /* OK, install new SP. */ +#endif LOC(sp_ok): ld ENV(g1,JB_PC), %o0 /* Extract target return PC. */ +#ifdef PTR_DEMANGLE + PTR_DEMANGLE2 (%o0, %o0, %g4) +#endif jmp %o0 + 8 /* Return there. */ mov %g2, %o0 /* Delay slot: set return value. */ --- libc/nptl/sysdeps/sparc/sparc64/jmpbuf-unwind.h.jj 2005-12-30 03:04:04.000000000 -0500 +++ libc/nptl/sysdeps/sparc/sparc64/jmpbuf-unwind.h 2006-01-02 06:45:25.000000000 -0500 @@ -1,4 +1,4 @@ -/* Copyright (C) 2005 Free Software Foundation, Inc. +/* Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by David S. Miller , 2005. @@ -20,23 +20,12 @@ #include #include #include -#include #define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \ _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj) -static inline uintptr_t __attribute__ ((unused)) -_jmpbuf_sp (__jmp_buf regs) -{ - uintptr_t sp = regs[0].uc_mcontext.mc_fp; -#ifdef PTR_DEMANGLE - PTR_DEMANGLE (sp); -#endif - return sp; -} - #define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \ - ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj)) + ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_jmpbuf)[0].uc_mcontext.mc_fp - (_adj)) /* We use the normal lobngjmp for unwinding. */ #define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val) --- libc/nptl/sysdeps/sparc/tcb-offsets.sym.jj 2004-12-21 08:33:31.000000000 -0500 +++ libc/nptl/sysdeps/sparc/tcb-offsets.sym 2006-01-02 06:45:25.000000000 -0500 @@ -2,5 +2,6 @@ #include MULTIPLE_THREADS_OFFSET offsetof (tcbhead_t, multiple_threads) +POINTER_GUARD offsetof (tcbhead_t, pointer_guard) PID offsetof (struct pthread, pid) TID offsetof (struct pthread, tid) --- libc/nptl/sysdeps/sparc/tls.h.jj 2005-08-23 06:00:43.000000000 -0400 +++ libc/nptl/sysdeps/sparc/tls.h 2006-01-02 10:26:11.000000000 -0500 @@ -1,5 +1,5 @@ /* Definitions for thread-local data handling. NPTL/sparc version. - Copyright (C) 2003, 2005 Free Software Foundation, Inc. + Copyright (C) 2003, 2005, 2006 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 @@ -48,6 +48,7 @@ typedef struct int multiple_threads; uintptr_t sysinfo; uintptr_t stack_guard; + uintptr_t pointer_guard; } tcbhead_t; #else /* __ASSEMBLER__ */ @@ -135,6 +136,14 @@ register struct pthread *__thread_self _ ((descr)->header.stack_guard \ = THREAD_GETMEM (THREAD_SELF, header.stack_guard)) +/* Get/set the stack guard field in TCB head. */ +#define THREAD_GET_POINTER_GUARD() \ + THREAD_GETMEM (THREAD_SELF, header.pointer_guard) +#define THREAD_SET_POINTER_GUARD(value) \ + THREAD_SETMEM (THREAD_SELF, header.pointer_guard, value) +# define THREAD_COPY_POINTER_GUARD(descr) \ + ((descr)->header.pointer_guard = THREAD_GET_POINTER_GUARD ()) + #endif /* !ASSEMBLER */ #endif /* tls.h */ Jakub