From patchwork Fri Sep 27 15:49:19 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Will Newton X-Patchwork-Id: 20669 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qe0-f70.google.com (mail-qe0-f70.google.com [209.85.128.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id C5B7324687 for ; Fri, 27 Sep 2013 15:49:54 +0000 (UTC) Received: by mail-qe0-f70.google.com with SMTP id b4sf2524019qen.9 for ; Fri, 27 Sep 2013 08:49:54 -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=/uPvnyXe4uFmUL+YRXg39HQiysO90zUdGewPDwwZFNk=; b=AUKqAIs+ndYBJ4YpZ6ky1CwqsuO+cSe0OXap6l3vdHDaPb7Xr9Y388TfKMbeU9aJ2v B+DbsgYQiveyojLATMqpcJWc5et08GRdWv29EHRTcDRXURtwL+ThoVBAjDzWJX4tHbZB 2fElO7UpFa8ZJgSUztTDhlS8y/0YzrIAk2A++KM/mqaceK++4bheQSBI2wYQpJxeqaas THrG0uIWXOIBkVoCzct88HBgu7cVjarYYPLwuLpfnzgj18j6d7jugWXw6vgeFOSYZ3Mg Ztnls/MuBgJqvGdiiPfowkf31BelLwUS3vVAPNLZld+hMCvluaYk1z8/fO7nZ/Nu5kPC z4oA== X-Gm-Message-State: ALoCoQnhsTlC3Fp/zjMmhtF6KxxV2rxk++It2+qgB2H+B+EJ0SpHrAtvKWLhpD39lBXlfJS63bJF X-Received: by 10.236.223.130 with SMTP id v2mr1363139yhp.34.1380296994044; Fri, 27 Sep 2013 08:49:54 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.82.49 with SMTP id f17ls1273714qey.33.gmail; Fri, 27 Sep 2013 08:49:53 -0700 (PDT) X-Received: by 10.58.108.74 with SMTP id hi10mr7034349veb.14.1380296993945; Fri, 27 Sep 2013 08:49:53 -0700 (PDT) Received: from mail-vb0-f54.google.com (mail-vb0-f54.google.com [209.85.212.54]) by mx.google.com with ESMTPS id tt2si1994322vcb.2.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 27 Sep 2013 08:49:53 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.212.54 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.212.54; Received: by mail-vb0-f54.google.com with SMTP id q14so1960437vbe.41 for ; Fri, 27 Sep 2013 08:49:23 -0700 (PDT) X-Received: by 10.59.9.138 with SMTP id ds10mr6980724ved.5.1380296963836; Fri, 27 Sep 2013 08:49:23 -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 u4csp436098vcz; Fri, 27 Sep 2013 08:49:23 -0700 (PDT) X-Received: by 10.194.78.78 with SMTP id z14mr6366394wjw.32.1380296962475; Fri, 27 Sep 2013 08:49:22 -0700 (PDT) Received: from mail-wg0-f42.google.com (mail-wg0-f42.google.com [74.125.82.42]) by mx.google.com with ESMTPS id o20si3123891wij.54.1969.12.31.16.00.00 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 27 Sep 2013 08:49:22 -0700 (PDT) Received-SPF: neutral (google.com: 74.125.82.42 is neither permitted nor denied by best guess record for domain of will.newton@linaro.org) client-ip=74.125.82.42; Received: by mail-wg0-f42.google.com with SMTP id m15so976672wgh.5 for ; Fri, 27 Sep 2013 08:49:22 -0700 (PDT) X-Received: by 10.180.206.42 with SMTP id ll10mr3224701wic.50.1380296962024; Fri, 27 Sep 2013 08:49:22 -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 dq11sm39720163wid.3.1969.12.31.16.00.00 (version=TLSv1 cipher=RC4-SHA bits=128/128); Fri, 27 Sep 2013 08:49:21 -0700 (PDT) Message-ID: <5245A8FF.4000602@linaro.org> Date: Fri, 27 Sep 2013 16:49:19 +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 v2] 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.212.54 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. ports/ChangeLog.arm: 2013-09-27 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/setjmp.S (__sigsetjmp): Mangle fp, sp and lr before storing register values. * sysdeps/arm/sysdep.h (LDST_GLOBAL): New macro. * 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/setjmp.S | 14 +++++++++++ ports/sysdeps/arm/sysdep.h | 11 +++++++++ ports/sysdeps/unix/sysv/linux/arm/sysdep.h | 39 +++++++++++++++++++++++++++--- 6 files changed, 90 insertions(+), 6 deletions(-) Changes in v2: - Use a global instead of a thread local variable to store the guard value - The bit I don't like in this version of the patch is the test for !IS_IN_nscd, but without it I get undefined references to __pointer_chk_guard_local. 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/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/arm/sysdep.h b/ports/sysdeps/arm/sysdep.h index 5501597..60d26fd 100644 --- a/ports/sysdeps/arm/sysdep.h +++ b/ports/sysdeps/arm/sysdep.h @@ -171,6 +171,17 @@ 99: OP R, [pc, T] # endif +# define LDST_GLOBAL(OP, R, T, EXPR) \ + ldr T, 99f; \ + ldr R, 100f; \ +98: add T, T, pc; \ + ldr T, [T, R]; \ + .subsection 2; \ +99: .word _GLOBAL_OFFSET_TABLE_ - 98b - PC_OFS; \ +100: .word EXPR##(GOT); \ + .previous; \ + OP R, [T] + /* Cope with negative memory offsets, which thumb can't encode. Use NEGOFF_ADJ_BASE to (conditionally) alter the base register, and then NEGOFF_OFF1 to use 0 for thumb and the offset for arm, diff --git a/ports/sysdeps/unix/sysv/linux/arm/sysdep.h b/ports/sysdeps/unix/sysv/linux/arm/sysdep.h index b195d8e..7ef8374 100644 --- a/ports/sysdeps/unix/sysv/linux/arm/sysdep.h +++ b/ports/sysdeps/unix/sysv/linux/arm/sysdep.h @@ -435,8 +435,41 @@ __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) || (!defined SHARED && !defined IS_IN_nscd) +# ifdef __ASSEMBLER__ +# define PTR_MANGLE(dst, src, guard, tmp) \ + LDST_PCREL(ldr, guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard_local)); \ + PTR_MANGLE2(dst, src, guard) +# 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 +extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) +# define PTR_DEMANGLE(var) PTR_MANGLE (var) +# endif +#else +# ifdef __ASSEMBLER__ +# define PTR_MANGLE(dst, src, guard, tmp) \ + LDST_GLOBAL(ldr, guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard)); \ + PTR_MANGLE2(dst, src, guard) +# 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 +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) +# define PTR_DEMANGLE(var) PTR_MANGLE (var) +# endif +#endif #endif /* linux/arm/sysdep.h */