]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix MIPS n32 cancellation in static libc (bug 15506).
authorJoseph Myers <joseph@codesourcery.com>
Tue, 21 May 2013 20:27:45 +0000 (20:27 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Tue, 21 May 2013 20:27:45 +0000 (20:27 +0000)
NEWS
ports/ChangeLog.mips
ports/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h
ports/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h
ports/sysdeps/unix/sysv/linux/mips/mips64/nptl/sysdep-cancel.h

diff --git a/NEWS b/NEWS
index 68a55ea5bfabfe6eea25f21a32bb74e627a68f73..970c53b614bf40eb2a80dacf465ee3d7ad0ffa75 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -18,7 +18,7 @@ Version 2.18
   15304, 15305, 15307, 15309, 15327, 15330, 15335, 15336, 15337, 15339,
   15342, 15346, 15359, 15361, 15366, 15380, 15394, 15395, 15405, 15406,
   15409, 15416, 15418, 15419, 15423, 15424, 15426, 15429, 15442, 15448,
-  15480, 15485, 15488, 15490, 15493, 15497.
+  15480, 15485, 15488, 15490, 15493, 15497, 15506.
 
 * CVE-2013-0242 Buffer overrun in regexp matcher has been fixed (Bugzilla
   #15078).
index 24411276b28944bb43bacdd675474efd0f0bb7b0..df91f5afdec300b924fe475683f3c94f90f2b14a 100644 (file)
@@ -1,3 +1,20 @@
+2013-05-21  Joseph Myers  <joseph@codesourcery.com>
+
+       [BZ #15506]
+       * sysdeps/unix/sysv/linux/mips/mips64/nptl/sysdep-cancel.h
+       [!__PIC__] (PSEUDO): Undefine and redefine.
+       (PSEUDO_END): Undefine and redefine unconditionally.
+       [!__PIC__] (STK_PAD): Define to 0.
+       [!__PIC__] (STKOFF_GP): Do not define.
+       [!__PIC__] (STKSPACE): Define to (STKOFF_SVMSK + SZREG).
+       (PSEUDO_JMP): Define depending on [__PIC__].
+       (CENABLE): Use PSEUDO_JMP in all definitions.
+       (CDISABLE): Likewise.
+       * sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h
+       (SYSCALL_ERROR_LABEL): Define unconditionally.
+       * sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h
+       (SYSCALL_ERROR_LABEL): Define unconditionally.
+
 2013-05-19  Joseph Myers  <joseph@codesourcery.com>
 
        * sysdeps/mips/mips32/libm-test-ulps: Update names of sincos
index 452c2c70ebeb1c9f4b4a8e14c256916f640b574e..b2a9a957964f3d98a1e5f651f6f9b70440f8bb47 100644 (file)
@@ -39,9 +39,7 @@
 
 /* We don't want the label for the error handler to be visible in the symbol
    table when we define it here.  */
-#ifdef __PIC__
 # define SYSCALL_ERROR_LABEL 99b
-#endif
 
 #else   /* ! __ASSEMBLER__ */
 
index d16ed6941c3b1915e0547dce7f267e2f61ce573e..844a7e880c1e9d62cea6dd5a040f9d5b59912885 100644 (file)
@@ -39,9 +39,7 @@
 
 /* We don't want the label for the error handler to be visible in the symbol
    table when we define it here.  */
-#ifdef __PIC__
 # define SYSCALL_ERROR_LABEL 99b
-#endif
 
 #else   /* ! __ASSEMBLER__ */
 
index 6565225662b742bc9ff6a0f5e8bb5d1cf417330d..157cc3825940ed99ca514f1cae5f7b92d58aee16 100644 (file)
     cfi_same_value (gp);                                                     \
     RESTORESTK;                                                                      \
   L(pseudo_end):
-
+#else
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)                                    \
+      .align 2;                                                                      \
+  L(pseudo_start):                                                           \
+      cfi_startproc;                                                         \
+      cfi_adjust_cfa_offset (STKSPACE);                                              \
+  99: RESTORESTK;                                                            \
+      j __syscall_error;                                                     \
+  .type __##syscall_name##_nocancel, @function;                                      \
+  .globl __##syscall_name##_nocancel;                                        \
+  __##syscall_name##_nocancel:                                               \
+    SAVESTK;                                                                 \
+    li v0, SYS_ify(syscall_name);                                            \
+    syscall;                                                                 \
+    bne a3, zero, SYSCALL_ERROR_LABEL;                                       \
+    RESTORESTK;                                                                      \
+    ret;                                                                     \
+    cfi_endproc;                                                             \
+  .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;           \
+  ENTRY (name)                                                               \
+    SAVESTK;                                                                 \
+    SINGLE_THREAD_P(v1);                                                     \
+    bne zero, v1, L(pseudo_cancel);                                          \
+    .set noreorder;                                                          \
+    li v0, SYS_ify(syscall_name);                                            \
+    syscall;                                                                 \
+    .set reorder;                                                            \
+    bne a3, zero, SYSCALL_ERROR_LABEL;                                       \
+    RESTORESTK;                                                                      \
+    ret;                                                                     \
+  L(pseudo_cancel):                                                          \
+    cfi_adjust_cfa_offset (STKSPACE);                                        \
+    REG_S ra, STKOFF_RA(sp);                                                 \
+    cfi_rel_offset (ra, STKOFF_RA);                                          \
+    PUSHARGS_##args;                   /* save syscall args */               \
+    CENABLE;                                                                 \
+    REG_S v0, STKOFF_SVMSK(sp);                /* save mask */                       \
+    POPARGS_##args;                    /* restore syscall args */            \
+    .set noreorder;                                                          \
+    li v0, SYS_ify (syscall_name);                                           \
+    syscall;                                                                 \
+    .set reorder;                                                            \
+    REG_S v0, STKOFF_SC_V0(sp);                /* save syscall result */             \
+    REG_S a3, STKOFF_SC_ERR(sp);       /* save syscall error flag */         \
+    REG_L a0, STKOFF_SVMSK(sp);                /* pass mask as arg1 */               \
+    CDISABLE;                                                                \
+    REG_L a3, STKOFF_SC_ERR(sp);       /* restore syscall error flag */      \
+    REG_L ra, STKOFF_RA(sp);           /* restore return address */          \
+    REG_L v0, STKOFF_SC_V0(sp);                /* restore syscall result */          \
+    bne a3, zero, SYSCALL_ERROR_LABEL;                                       \
+    RESTORESTK;                                                                      \
+  L(pseudo_end):
+#endif
 
 # undef PSEUDO_END
 # define PSEUDO_END(sym) cfi_endproc; .end sym; .size sym,.-sym
 
-#endif
-
 # define PUSHARGS_0    /* nothing to do */
 # define PUSHARGS_1    PUSHARGS_0 REG_S a0, STKOFF_A0(sp); cfi_rel_offset (a0, STKOFF_A0);
 # define PUSHARGS_2    PUSHARGS_1 REG_S a1, STKOFF_A1(sp); cfi_rel_offset (a1, STKOFF_A1);
 
 /* Save an even number of slots.  Should be 0 if an even number of slots
    are used below, or SZREG if an odd number are used.  */
-# define STK_PAD       SZREG
+# ifdef __PIC__
+#  define STK_PAD      SZREG
+# else
+#  define STK_PAD      0
+# endif
 
 /* Place values that we are more likely to use later in this sequence, i.e.
    closer to the SP at function entry.  If you do that, the are more
 # define STKOFF_SC_V0  (STKOFF_RA + SZREG)     /* Used if MT.  */
 # define STKOFF_SC_ERR (STKOFF_SC_V0 + SZREG)  /* Used if MT.  */
 # define STKOFF_SVMSK  (STKOFF_SC_ERR + SZREG) /* Used if MT.  */
-# define STKOFF_GP     (STKOFF_SVMSK + SZREG)  /* Always used.  */
 
-# define STKSPACE      (STKOFF_GP + SZREG)
+# ifdef __PIC__
+#  define STKOFF_GP    (STKOFF_SVMSK + SZREG)  /* Always used.  */
+#  define STKSPACE     (STKOFF_GP + SZREG)
+# else
+#  define STKSPACE     (STKOFF_SVMSK + SZREG)
+# endif
+
 # define SAVESTK       PTR_SUBU sp, STKSPACE; cfi_adjust_cfa_offset(STKSPACE)
 # define RESTORESTK    PTR_ADDU sp, STKSPACE; cfi_adjust_cfa_offset(-STKSPACE)
 
+# ifdef __PIC__
+#  define PSEUDO_JMP(sym) PTR_LA t9, sym; jalr t9
+# else
+#  define PSEUDO_JMP(sym) jal sym
+# endif
+
 # ifdef IS_IN_libpthread
-#  define CENABLE      PTR_LA t9, __pthread_enable_asynccancel; jalr t9
-#  define CDISABLE     PTR_LA t9, __pthread_disable_asynccancel; jalr t9
+#  define CENABLE      PSEUDO_JMP (__pthread_enable_asynccancel)
+#  define CDISABLE     PSEUDO_JMP (__pthread_disable_asynccancel)
 # elif defined IS_IN_librt
-#  define CENABLE      PTR_LA t9, __librt_enable_asynccancel; jalr t9
-#  define CDISABLE     PTR_LA t9, __librt_disable_asynccancel; jalr t9
+#  define CENABLE      PSEUDO_JMP (__librt_enable_asynccancel)
+#  define CDISABLE     PSEUDO_JMP (__librt_disable_asynccancel)
 # else
-#  define CENABLE      PTR_LA t9, __libc_enable_asynccancel; jalr t9
-#  define CDISABLE     PTR_LA t9, __libc_disable_asynccancel; jalr t9
+#  define CENABLE      PSEUDO_JMP (__libc_enable_asynccancel)
+#  define CDISABLE     PSEUDO_JMP (__libc_disable_asynccancel)
 # endif
 
 # ifndef __ASSEMBLER__