From patchwork Wed Sep 25 09:06:37 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Will Newton X-Patchwork-Id: 20557 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qe0-f72.google.com (mail-qe0-f72.google.com [209.85.128.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 8B0BF25E71 for ; Wed, 25 Sep 2013 09:06:43 +0000 (UTC) Received: by mail-qe0-f72.google.com with SMTP id 6sf5229401qea.11 for ; Wed, 25 Sep 2013 02:06:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:message-id:date:from:user-agent :mime-version:to:cc:subject:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe:content-type :content-transfer-encoding; bh=3GiONJuHRYDsns4I7dCYP5/rewvLo6hFfZYYecuipdk=; b=d62k/JvhQDWnuOxRrj9DgIIuWhMdDLfXBK2pA/3/l51As+nwnyxqCSuxvCFua2Jgdn kh6MNgVjCYcMYZbnpAJ4rbhePedub/G/ncZ4rzHwr/ZzhKpEQYMVh/aTWihx40OFCm9A IJSkG3G46rr23DFBXrVYfqBADqwi6Vn7BlK80o9QdCEzuPmqz8FioWVyc1JuKBkjkvjZ +ZQ2lERTp3G8z2mwU2kzLuJwgBLhD/s8D9+7m92kVKVNUZRnfV1VKRAPcYGne51HrGJt 1Axyh0GI6r58uBrN7F+1n4sVa4fcbRB6ohtoDMerVOhQYEi0zFyPXFUBPUc8CJ/4xO7f Ql/Q== X-Gm-Message-State: ALoCoQlp5npSS4UccSzSUDQLCNcVFTjFMdYT+Vs7PhxfkJKp9mC6cEykLHcZUO1ZaUoKeJOeDy6w X-Received: by 10.224.137.67 with SMTP id v3mr15304121qat.0.1380100003049; Wed, 25 Sep 2013 02:06:43 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.24.172 with SMTP id v12ls315464qef.91.gmail; Wed, 25 Sep 2013 02:06:42 -0700 (PDT) X-Received: by 10.52.157.134 with SMTP id wm6mr9677684vdb.26.1380100002782; Wed, 25 Sep 2013 02:06:42 -0700 (PDT) Received: from mail-vc0-f181.google.com (mail-vc0-f181.google.com [209.85.220.181]) by mx.google.com with ESMTPS id sc5si9515920vdc.152.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 25 Sep 2013 02:06:42 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.220.181 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.181; Received: by mail-vc0-f181.google.com with SMTP id hz10so4111344vcb.40 for ; Wed, 25 Sep 2013 02:06:42 -0700 (PDT) X-Received: by 10.220.88.13 with SMTP id y13mr12434377vcl.20.1380100002384; Wed, 25 Sep 2013 02:06:42 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.174.196 with SMTP id u4csp293225vcz; Wed, 25 Sep 2013 02:06:41 -0700 (PDT) X-Received: by 10.180.206.129 with SMTP id lo1mr21714528wic.15.1380100001198; Wed, 25 Sep 2013 02:06:41 -0700 (PDT) Received: from mail-wi0-f175.google.com (mail-wi0-f175.google.com [209.85.212.175]) by mx.google.com with ESMTPS id lu10si14387602wjb.74.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 25 Sep 2013 02:06:41 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.212.175 is neither permitted nor denied by best guess record for domain of will.newton@linaro.org) client-ip=209.85.212.175; Received: by mail-wi0-f175.google.com with SMTP id ez12so5072189wid.2 for ; Wed, 25 Sep 2013 02:06:40 -0700 (PDT) X-Received: by 10.194.23.196 with SMTP id o4mr434313wjf.62.1380100000468; Wed, 25 Sep 2013 02:06:40 -0700 (PDT) Received: from localhost.localdomain (cpc6-seac21-2-0-cust453.7-2.cable.virginmedia.com. [82.1.113.198]) by mx.google.com with ESMTPSA id q5sm15702895wiz.3.1969.12.31.16.00.00 (version=TLSv1 cipher=RC4-SHA bits=128/128); Wed, 25 Sep 2013 02:06:39 -0700 (PDT) Message-ID: <5242A79D.1030709@linaro.org> Date: Wed, 25 Sep 2013 10:06:37 +0100 From: Will Newton User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130805 Thunderbird/17.0.8 MIME-Version: 1.0 To: libc-ports@sourceware.org CC: patches@linaro.org Subject: [PATCH] ARM: Add pointer guard support. X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: will.newton@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.181 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Add support for pointer mangling in glibc internal structures in C and assembler code. Tested on armv7 with hard and soft thread pointers. ports/ChangeLog.arm: 2013-09-24 Will Newton * sysdeps/arm/__longjmp.S (__longjmp): Demangle fp, sp and lr when restoring register values. * sysdeps/arm/include/bits/setjmp.h (JMP_BUF_REGLIST): Remove sp and lr from list and replace fp with a4. * sysdeps/arm/jmpbuf-unwind.h (_jmpbuf_sp): New function. (_JMPBUF_UNWINDS_ADJ): Call _jmpbuf_sp. * sysdeps/arm/nptl/tcb-offsets.sym: Add POINTER_GUARD. * sysdeps/arm/nptl/tls.h (tcbhead_t): Remove private and add pointer_guard. (THREAD_GET_POINTER_GUARD): New macro. (THREAD_SET_POINTER_GUARD): New macro. (THREAD_COPY_POINTER_GUARD): New macro. * sysdeps/arm/setjmp.S (__sigsetjmp): Mangle fp, sp and lr before storing register values. * sysdeps/unix/sysv/linux/arm/sysdep.h (PTR_MANGLE): New macro. (PTR_DEMANGLE): Likewise. (PTR_MANGLE2): Likewise. (PTR_DEMANGLE2): Likewise. --- ports/sysdeps/arm/__longjmp.S | 14 ++++++++++++++ ports/sysdeps/arm/include/bits/setjmp.h | 5 +++-- ports/sysdeps/arm/jmpbuf-unwind.h | 13 ++++++++++++- ports/sysdeps/arm/nptl/tcb-offsets.sym | 2 ++ ports/sysdeps/arm/nptl/tls.h | 10 +++++++++- ports/sysdeps/arm/setjmp.S | 14 ++++++++++++++ ports/sysdeps/unix/sysv/linux/arm/sysdep.h | 22 +++++++++++++++++++--- 7 files changed, 73 insertions(+), 7 deletions(-) diff --git a/ports/sysdeps/arm/__longjmp.S b/ports/sysdeps/arm/__longjmp.S index a5edede..2b1f7f4 100644 --- a/ports/sysdeps/arm/__longjmp.S +++ b/ports/sysdeps/arm/__longjmp.S @@ -34,10 +34,24 @@ ENTRY (__longjmp) sfi_breg ip, \ ldr r4, [\B, #32] /* jmpbuf's sp */ cfi_undefined (r4) +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (r4, r4, a3, a4) +#endif CHECK_SP (r4) #endif sfi_sp sfi_breg ip, \ ldmia \B!, JMP_BUF_REGLIST +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (fp, a4, a3, a2) + ldr a4, [ip], #4 + PTR_DEMANGLE2 (sp, a4, a3) + ldr a4, [ip], #4 + PTR_DEMANGLE2 (lr, a4, a3) +#else + mov fp, a4 + ldr sp, [ip], #4 + ldr lr, [ip], #4 +#endif cfi_restore (v1) cfi_restore (v2) cfi_restore (v3) diff --git a/ports/sysdeps/arm/include/bits/setjmp.h b/ports/sysdeps/arm/include/bits/setjmp.h index 1559d7b..64505dc 100644 --- a/ports/sysdeps/arm/include/bits/setjmp.h +++ b/ports/sysdeps/arm/include/bits/setjmp.h @@ -26,8 +26,9 @@ #ifndef _ISOMAC /* Register list for a ldm/stm instruction to load/store - the general registers from a __jmp_buf. */ -# define JMP_BUF_REGLIST {v1-v6, sl, fp, sp, lr} + the general registers from a __jmp_buf. The a4 register + contains fp at this point. */ +# define JMP_BUF_REGLIST {a4, v1-v6, sl} /* Index of __jmp_buf where the sp register resides. */ # define __JMP_BUF_SP 8 diff --git a/ports/sysdeps/arm/jmpbuf-unwind.h b/ports/sysdeps/arm/jmpbuf-unwind.h index 0863540..1b0d020 100644 --- a/ports/sysdeps/arm/jmpbuf-unwind.h +++ b/ports/sysdeps/arm/jmpbuf-unwind.h @@ -17,6 +17,7 @@ #include #include +#include #include /* Test if longjmp to JMPBUF would unwind the frame @@ -27,8 +28,18 @@ #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[__JMP_BUF_SP]; +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (sp); +#endif + return sp; +} + #define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \ - ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_jmpbuf)[__JMP_BUF_SP] - (_adj)) + ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj)) /* We use the normal longjmp for unwinding. */ #define __libc_unwind_longjmp(buf, val) __libc_longjmp (buf, val) diff --git a/ports/sysdeps/arm/nptl/tcb-offsets.sym b/ports/sysdeps/arm/nptl/tcb-offsets.sym index 92cc441..06d792f 100644 --- a/ports/sysdeps/arm/nptl/tcb-offsets.sym +++ b/ports/sysdeps/arm/nptl/tcb-offsets.sym @@ -9,3 +9,5 @@ MULTIPLE_THREADS_OFFSET thread_offsetof (header.multiple_threads) PID_OFFSET thread_offsetof (pid) TID_OFFSET thread_offsetof (tid) + +POINTER_GUARD offsetof (tcbhead_t, pointer_guard) diff --git a/ports/sysdeps/arm/nptl/tls.h b/ports/sysdeps/arm/nptl/tls.h index da15027..e855507 100644 --- a/ports/sysdeps/arm/nptl/tls.h +++ b/ports/sysdeps/arm/nptl/tls.h @@ -56,7 +56,7 @@ typedef union dtv typedef struct { dtv_t *dtv; - void *private; + uintptr_t pointer_guard; } tcbhead_t; /* This is the size of the initial TCB. */ @@ -119,6 +119,14 @@ typedef struct #define THREAD_SETMEM_NC(descr, member, idx, value) \ descr->member[idx] = (value) +/* Get/set the pointer guard field in TCB head. */ +#define THREAD_GET_POINTER_GUARD() \ + (((tcbhead_t *) __builtin_thread_pointer ())->pointer_guard) +#define THREAD_SET_POINTER_GUARD(value) \ + (((tcbhead_t *) __builtin_thread_pointer ())->pointer_guard = (value)) +# define THREAD_COPY_POINTER_GUARD(descr) \ + (((tcbhead_t *) (descr + 1))->pointer_guard = THREAD_GET_POINTER_GUARD ()) + /* Get and set the global scope generation counter in struct pthread. */ #define THREAD_GSCOPE_FLAG_UNUSED 0 #define THREAD_GSCOPE_FLAG_USED 1 diff --git a/ports/sysdeps/arm/setjmp.S b/ports/sysdeps/arm/setjmp.S index a6c161d..b38b919 100644 --- a/ports/sysdeps/arm/setjmp.S +++ b/ports/sysdeps/arm/setjmp.S @@ -24,11 +24,25 @@ #include ENTRY (__sigsetjmp) +#ifdef PTR_MANGLE + PTR_MANGLE (a4, fp, a3, ip) +#else + mov a4, fp +#endif mov ip, r0 /* Save registers */ sfi_breg ip, \ stmia \B!, JMP_BUF_REGLIST +#ifdef PTR_MANGLE + PTR_MANGLE2 (a4, sp, a3) + str a4, [ip], #4 + PTR_MANGLE2 (a4, lr, a3) + str a4, [ip], #4 +#else + str sp, [ip], #4 + str lr, [ip], #4 +#endif #if !defined ARM_ASSUME_NO_IWMMXT || defined __SOFTFP__ # define NEED_HWCAP 1 diff --git a/ports/sysdeps/unix/sysv/linux/arm/sysdep.h b/ports/sysdeps/unix/sysv/linux/arm/sysdep.h index b195d8e..5991641 100644 --- a/ports/sysdeps/unix/sysv/linux/arm/sysdep.h +++ b/ports/sysdeps/unix/sysv/linux/arm/sysdep.h @@ -435,8 +435,24 @@ __local_syscall_error: \ #endif /* __ASSEMBLER__ */ -/* Pointer mangling is not yet supported for ARM. */ -#define PTR_MANGLE(var) (void) (var) -#define PTR_DEMANGLE(var) (void) (var) +/* 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(dst, src, guard, tmp) \ + mov tmp, r0; GET_TLS (guard); ldr guard, [r0, POINTER_GUARD]; \ + eor dst, src, guard; mov r0, tmp +# define PTR_MANGLE2(dst, src, guard) eor dst, src, guard +# define PTR_DEMANGLE(dst, src, guard, tmp) \ + PTR_MANGLE (dst, src, guard, tmp) +# define PTR_DEMANGLE2(dst, src, guard) PTR_MANGLE2 (dst, src, guard) +# 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/arm/sysdep.h */