[MIPS] Extend Signal Mapping to include RT Signals.

Both MIPS and ARM use signals 32 to 64 for real-time signals.
ARM signals 32 to 64 can't be masked due to the signal
mask being limited to 32 bits. MIPS signals 32 to 64 can be
masked, and Lib-Portable correctly supports this feature.

Fixes LTP tests rt_sigaction01 and ptrace05.

Fixed a few signal problems; Ex last Real Time Signal

1.  The signal handler for signal number 64, the last real
    time signal, wasn't being intercepted. Now catching
    signal number 64.

2.  sigaction() to only change *oldact when return
    value is zero.

3.  Fixed rt_sigqueue_portable() to set errno when
    returning a -1.

4.  Fixed a few cases where signal 0 was being added
    to the table of signal handlers for signal remapping.
    Harmless but a bit silly.

Change-Id: I1a71113d7ce4b60f3a587dae4e243dc88dd6d6bc
Signed-off-by: Pete Delaney <piet.delaney@imgtec.com>
Signed-off-by: Chris Dearman <chris.dearman@imgtec.com>
Signed-off-by: Paul Lind <paul.lind@imgtec.com>
diff --git a/ndk/sources/android/libportable/arch-mips/signal.c b/ndk/sources/android/libportable/arch-mips/signal.c
index 59d27ca..95ee8bc 100644
--- a/ndk/sources/android/libportable/arch-mips/signal.c
+++ b/ndk/sources/android/libportable/arch-mips/signal.c
@@ -94,6 +94,40 @@
     case SIGPWR_PORTABLE:       name = "SIGPWR_PORTABLE:30";            break;
     case SIGSYS_PORTABLE:       name = "SIGSYS_PORTABLE:31";            break;
     case SIGRTMIN_PORTABLE:     name = "SIGRTMIN_PORTABLE:32";          break;
+
+    case SIGRT_1_PORTABLE:      name = "SIGRT_1_PORTABLE:33";           break;
+    case SIGRT_2_PORTABLE:      name = "SIGRT_2_PORTABLE:34";           break;
+    case SIGRT_3_PORTABLE:      name = "SIGRT_3_PORTABLE:35";           break;
+    case SIGRT_4_PORTABLE:      name = "SIGRT_4_PORTABLE:36";           break;
+    case SIGRT_5_PORTABLE:      name = "SIGRT_5_PORTABLE:37";           break;
+    case SIGRT_6_PORTABLE:      name = "SIGRT_6_PORTABLE:38";           break;
+    case SIGRT_7_PORTABLE:      name = "SIGRT_7_PORTABLE:39";           break;
+    case SIGRT_8_PORTABLE:      name = "SIGRT_8_PORTABLE:40";           break;
+    case SIGRT_9_PORTABLE:      name = "SIGRT_9_PORTABLE:41";           break;
+    case SIGRT_10_PORTABLE:     name = "SIGRT_10_PORTABLE:42";          break;
+    case SIGRT_11_PORTABLE:     name = "SIGRT_11_PORTABLE:43";          break;
+    case SIGRT_12_PORTABLE:     name = "SIGRT_12_PORTABLE:44";          break;
+    case SIGRT_13_PORTABLE:     name = "SIGRT_13_PORTABLE:45";          break;
+    case SIGRT_14_PORTABLE:     name = "SIGRT_14_PORTABLE:46";          break;
+    case SIGRT_15_PORTABLE:     name = "SIGRT_15_PORTABLE:47";          break;
+    case SIGRT_16_PORTABLE:     name = "SIGRT_16_PORTABLE:48";          break;
+    case SIGRT_17_PORTABLE:     name = "SIGRT_17_PORTABLE:49";          break;
+    case SIGRT_18_PORTABLE:     name = "SIGRT_18_PORTABLE:50";          break;
+    case SIGRT_19_PORTABLE:     name = "SIGRT_19_PORTABLE:51";          break;
+    case SIGRT_20_PORTABLE:     name = "SIGRT_20_PORTABLE:52";          break;
+    case SIGRT_21_PORTABLE:     name = "SIGRT_21_PORTABLE:53";          break;
+    case SIGRT_22_PORTABLE:     name = "SIGRT_22_PORTABLE:54";          break;
+    case SIGRT_23_PORTABLE:     name = "SIGRT_23_PORTABLE:55";          break;
+    case SIGRT_24_PORTABLE:     name = "SIGRT_24_PORTABLE:56";          break;
+    case SIGRT_25_PORTABLE:     name = "SIGRT_25_PORTABLE:57";          break;
+    case SIGRT_26_PORTABLE:     name = "SIGRT_26_PORTABLE:58";          break;
+    case SIGRT_27_PORTABLE:     name = "SIGRT_27_PORTABLE:59";          break;
+    case SIGRT_28_PORTABLE:     name = "SIGRT_28_PORTABLE:60";          break;
+    case SIGRT_29_PORTABLE:     name = "SIGRT_29_PORTABLE:61";          break;
+    case SIGRT_30_PORTABLE:     name = "SIGRT_30_PORTABLE:62";          break;
+    case SIGRT_31_PORTABLE:     name = "SIGRT_31_PORTABLE:63";          break;
+    case SIGRTMAX_PORTABLE:     name = "SIGRTMAX_PORTABLE:64";          break;
+
     default:                    name = "<<UNKNOWN>>";                   break;
     }
     return name;
@@ -138,6 +172,42 @@
     case SIGXFSZ:       name = "SIGXFSZ:31";    break;
 
     case SIGRTMIN:      name = "SIGRTMIN:32";   break;
+    case SIGRT_1:       name = "SIGRT_1:33";    break;
+    case SIGRT_2:       name = "SIGRT_2:34";    break;
+    case SIGRT_3:       name = "SIGRT_3:35";    break;
+    case SIGRT_4:       name = "SIGRT_4:36";    break;
+    case SIGRT_5:       name = "SIGRT_5:37";    break;
+    case SIGRT_6:       name = "SIGRT_6:38";    break;
+    case SIGRT_7:       name = "SIGRT_7:39";    break;
+    case SIGRT_8:       name = "SIGRT_8:40";    break;
+    case SIGRT_9:       name = "SIGRT_9:41";    break;
+    case SIGRT_10:      name = "SIGRT_10:42";   break;
+    case SIGRT_11:      name = "SIGRT_11:43";   break;
+    case SIGRT_12:      name = "SIGRT_12:44";   break;
+    case SIGRT_13:      name = "SIGRT_13:45";   break;
+    case SIGRT_14:      name = "SIGRT_14:46";   break;
+    case SIGRT_15:      name = "SIGRT_15:47";   break;
+    case SIGRT_16:      name = "SIGRT_16:48";   break;
+    case SIGRT_17:      name = "SIGRT_17:49";   break;
+    case SIGRT_18:      name = "SIGRT_18:50";   break;
+    case SIGRT_19:      name = "SIGRT_19:51";   break;
+    case SIGRT_20:      name = "SIGRT_20:52";   break;
+    case SIGRT_21:      name = "SIGRT_21:53";   break;
+    case SIGRT_22:      name = "SIGRT_22:54";   break;
+    case SIGRT_23:      name = "SIGRT_23:55";   break;
+    case SIGRT_24:      name = "SIGRT_24:56";   break;
+    case SIGRT_25:      name = "SIGRT_25:57";   break;
+    case SIGRT_26:      name = "SIGRT_26:58";   break;
+    case SIGRT_27:      name = "SIGRT_27:59";   break;
+    case SIGRT_28:      name = "SIGRT_28:60";   break;
+    case SIGRT_29:      name = "SIGRT_29:61";   break;
+    case SIGRT_30:      name = "SIGRT_30:62";   break;
+    case SIGRT_31:      name = "SIGRT_31:63";   break;
+    case SIGRT_32:      name = "SIGRT_32:64";   break;
+
+    /* NOTE: SIGRT_33...SIGRTMAX-1 Not printed */
+
+    case SIGRTMAX:      name = "SIGRTMAX:128";  break;
     default:            name = "<<UNKNOWN>>";   break;
     }
     return name;
@@ -204,8 +274,8 @@
     case SIGCHLD_PORTABLE:              /* 17 --> 18 */
         return SIGCHLD;
 
-    case SIGCONT_PORTABLE:
-        return SIGCONT;                 /* 18 --> 25 */
+    case SIGCONT_PORTABLE:              /* 18 --> 25 */
+        return SIGCONT;
 
     case SIGSTOP_PORTABLE:              /* 19 --> 23 */
         return SIGSTOP;
@@ -245,9 +315,14 @@
 
     case SIGSYS_PORTABLE:               /* 31 --> 12 */
         return SIGSYS;
-
-    case SIGRTMIN_PORTABLE:             /* 32 */
-        return SIGRTMIN;
+    /*
+     * Mapping lower 32 Real Time signals to identical Native signal numbers.
+     * NOTE: SIGRTMAX_PORTABLE == 64 but SIGRTMAX == 128.
+     */
+    case SIGRTMIN_PORTABLE...SIGRTMAX_PORTABLE:         /* 32 ... 64 */
+        ASSERT(SIGRTMIN_PORTABLE == SIGRTMIN);
+        ASSERT(SIGRTMAX_PORTABLE <= SIGRTMAX);
+        return portable_signum;
 
     default:
         ALOGE("%s: switch default: NOTE portable_signum:%d Not supported. Just a Test?",
@@ -381,8 +456,31 @@
     case SIGSYS:                        /* 31 <-- 12 */
         return SIGSYS_PORTABLE;
 
-    case SIGRTMIN:                      /* 32 */
-        return SIGRTMIN_PORTABLE;
+    /*
+     * Mapping lower 32 Real Time signals to identical Portable signal numbers.
+     * NOTE: SIGRTMAX_PORTABLE == 64 but SIGRTMAX == 128.
+     */
+    case SIGRTMIN...SIGRTMAX_PORTABLE:              /* 32 ... 64 */
+        ASSERT(SIGRTMIN == SIGRTMIN_PORTABLE);
+        ASSERT(SIGRTMAX >= SIGRTMAX_PORTABLE);
+        return mips_signum;
+
+   /*
+    * Mapping upper 63 Native Real Time signals to the last Portable signal number.
+    * Shouldn't even be possible to be using these signals.
+    */
+    case (SIGRTMAX_PORTABLE+1)...SIGRTMAX:          /* 65 ... 128 */
+        ASSERT(SIGRTMIN == SIGRTMIN_PORTABLE);
+        ASSERT(SIGRTMAX >= SIGRTMAX_PORTABLE);
+
+        ALOGE("%s: mips_signum:%d Can't be mapped to a unique portable signal;", __func__,
+                   mips_signum);
+
+        ALOGE("%s: Mapping highest 63 Real Time Signals to the largest RT Portable SigNo.",
+                __func__);
+
+        return SIGRTMAX_PORTABLE;
+
 
     default:
         ALOGE("%s: switch default: mips_signum:%d Not supported! return(0);", __func__,
@@ -455,7 +553,7 @@
  * to have our own handler to map the MIPS signal number to a
  * portable signal number.
  */
-sig3handler_portable_t mips_portable_sighandler[NSIG_PORTABLE] = { NULL };
+static sig3handler_portable_t mips_portable_sighandler[NSIG_PORTABLE + 1] = { NULL };
 
 static void mips_sigaction_handler(int mips_signum, siginfo_t *sip, void *ucp)
 {
@@ -475,10 +573,20 @@
     portable_signame = map_portable_signum_to_name(portable_signum);
     portable_sighandler = mips_portable_sighandler[portable_signum];
 
+    if (invalid_pointer(portable_sighandler)) {
+        /*
+         * If a portable/ARM application tries to set signals in the signal mask > 32
+         * it results in a signal_handler being set to -1:SIG_ERR. Calling a function
+         * at location -1 doesn't produce very informative Android backtraces on MIPS.
+         */
+        ALOGE("%s: invalid_pointer(portable_sighandler:%p); Likely about to Trap or Bus Error!",
+                __func__,          portable_sighandler);
+
+        ALOGE("%s: HINT: Likely best to use gdbserver and look at sigaction arguments.", __func__);
+    }
     ASSERT(portable_sighandler != NULL);
     ASSERT(portable_sighandler != (sig3handler_portable_t) SIG_DFL);
     ASSERT(portable_sighandler != (sig3handler_portable_t) SIG_IGN);
-    ASSERT(portable_sighandler != (sig3handler_portable_t) SIG_ERR);
 
     if (sip == NULL) {
         portable_sip = NULL;
@@ -524,20 +632,29 @@
     switch((int) portable_handler) {
     case (int) SIG_DFL:
     case (int) SIG_IGN:
-    case (int) SIG_ERR:
         mips_handler = portable_handler;
         break;
 
-    default:
+    default:    /* NOTE: Includes SIG_ERR:-1 */
+        if (invalid_pointer(portable_handler)) {
+            /*
+             * Calling sigaction() with a bogus signal handler doesn't fail,
+             * so we let the portable cases fail later as the native case would.
+             */
+            ALOGE("%s: invalid_pointer(portable_handler:%p)!", __func__, portable_handler);
+            ALOGE("%s: HINT: Likely to cause a BUS Error ....", __func__);
+            ALOGE("%s: HINT: ... when the signal handler is called!", __func__);
+        }
+
         /*
          * Signal Mapping can be disabled in the rare case of the clone
          * flags not being compatble for VM and file descriptors.
          */
         if (signal_handler_mapping_enabled) {
             if (sigaction)
-                mips_handler = (sighandler_t) mips_sighandler;
-            else
                 mips_handler = (sighandler_t) mips_sigaction_handler;
+            else
+                mips_handler = (sighandler_t) mips_sighandler;
         } else {
             mips_handler = portable_handler;        /* Don't MAP */
         }
@@ -982,7 +1099,7 @@
         rv = 0;
         goto done;
     }
-    if (portable_signum >= 0 && portable_signum < NSIG_PORTABLE)
+    if (portable_signum > 0 && portable_signum <= NSIG_PORTABLE)
         prev_portable_handler = mips_portable_sighandler[portable_signum];
     else
         prev_portable_handler = NULL;
@@ -1006,21 +1123,26 @@
             /*
              * Providing the three argument version of a signal handler.
              */
-            if (portable_signum >= 0 && portable_signum < NSIG_PORTABLE) {
-                mips_portable_sighandler[portable_signum] =
-                                (sig3handler_portable_t) act->sa_sigaction_portable;
-
-                mips_act.sa_sigaction = mips_sigaction_handler;
-            }
-            else {
-                mips_act.sa_sigaction = act->sa_sigaction_portable;
+            portable_handler = (sighandler_portable_t) act->sa_sigaction_portable;
+            if ((portable_signum <= 0) || (portable_signum > NSIG_PORTABLE)) {
+                /*
+                 * Let the kernel generate the proper return value and set errno.
+                 */
+                mips_act.sa_sigaction = (sig3handler_t) portable_handler;
+            } else {
+                mips_handler = sighandler_pton(portable_handler, 1);
+                if (mips_handler != portable_handler) {
+                    mips_portable_sighandler[portable_signum] =
+                                                       (sig3handler_portable_t) portable_handler;
+                }
+                mips_act.sa_sigaction = (sig3handler_t) mips_handler;
             }
         } else {
             /*
              * Providing the classic single argument version of a signal handler.
              */
             portable_handler = act->sa_handler_portable;
-            if ((portable_signum < 0) || (portable_signum > NSIG_PORTABLE)) {
+            if ((portable_signum <= 0) || (portable_signum > NSIG_PORTABLE)) {
                 /*
                  * Let the kernel generate the proper return value and set errno.
                  */
@@ -1045,7 +1167,7 @@
         rv = rt_fn(mips_signum, mips_act_ptr, &mips_oldact, sizeof(sigset_t));
     }
 
-    if (oldact) {
+    if (rv == 0 && oldact) {
         if (mips_oldact.sa_sigaction == (__sigaction_handler_portable_t) mips_sigaction_handler ||
             mips_oldact.sa_sigaction == (__sigaction_handler_portable_t) mips_sighandler) {
 
diff --git a/ndk/sources/android/libportable/common/include/asm/signal_portable.h b/ndk/sources/android/libportable/common/include/asm/signal_portable.h
index 32de562..a9608cc 100644
--- a/ndk/sources/android/libportable/common/include/asm/signal_portable.h
+++ b/ndk/sources/android/libportable/common/include/asm/signal_portable.h
@@ -15,7 +15,7 @@
 
 struct siginfo;                         /* TODO: Change to siginfo_portable */
 
-#define NSIG_PORTABLE 32
+#define NSIG_PORTABLE 64
 typedef unsigned long sigset_portable_t;
 
 #define SIGHUP_PORTABLE 1
@@ -54,9 +54,95 @@
 #define SIGSYS_PORTABLE 31
 #define SIGUNUSED_PORTABLE 31
 
-#define SIGRTMIN_PORTABLE 32
-#define SIGRTMAX_PORTABLE _NSIG_PORTABLE
 #define SIGSWI_PORTABLE 32
+#define SIGRTMIN_PORTABLE 32
+
+#define SIGRT_1_PORTABLE (SIGRTMIN_PORTABLE + 1)
+#define SIGRT_2_PORTABLE (SIGRTMIN_PORTABLE + 2)
+#define SIGRT_3_PORTABLE (SIGRTMIN_PORTABLE + 3)
+#define SIGRT_4_PORTABLE (SIGRTMIN_PORTABLE + 4)
+#define SIGRT_5_PORTABLE (SIGRTMIN_PORTABLE + 5)
+#define SIGRT_5_PORTABLE (SIGRTMIN_PORTABLE + 5)
+#define SIGRT_6_PORTABLE (SIGRTMIN_PORTABLE + 6)
+#define SIGRT_7_PORTABLE (SIGRTMIN_PORTABLE + 7)
+#define SIGRT_8_PORTABLE (SIGRTMIN_PORTABLE + 8)
+#define SIGRT_9_PORTABLE (SIGRTMIN_PORTABLE + 9)
+#define SIGRT_10_PORTABLE (SIGRTMIN_PORTABLE + 10)
+#define SIGRT_11_PORTABLE (SIGRTMIN_PORTABLE + 11)
+#define SIGRT_12_PORTABLE (SIGRTMIN_PORTABLE + 12)
+#define SIGRT_13_PORTABLE (SIGRTMIN_PORTABLE + 13)
+#define SIGRT_14_PORTABLE (SIGRTMIN_PORTABLE + 14)
+#define SIGRT_15_PORTABLE (SIGRTMIN_PORTABLE + 15)
+#define SIGRT_15_PORTABLE (SIGRTMIN_PORTABLE + 15)
+#define SIGRT_16_PORTABLE (SIGRTMIN_PORTABLE + 16)
+#define SIGRT_17_PORTABLE (SIGRTMIN_PORTABLE + 17)
+#define SIGRT_18_PORTABLE (SIGRTMIN_PORTABLE + 18)
+#define SIGRT_19_PORTABLE (SIGRTMIN_PORTABLE + 19)
+#define SIGRT_20_PORTABLE (SIGRTMIN_PORTABLE + 20)
+#define SIGRT_20_PORTABLE (SIGRTMIN_PORTABLE + 20)
+#define SIGRT_21_PORTABLE (SIGRTMIN_PORTABLE + 21)
+#define SIGRT_22_PORTABLE (SIGRTMIN_PORTABLE + 22)
+#define SIGRT_23_PORTABLE (SIGRTMIN_PORTABLE + 23)
+#define SIGRT_24_PORTABLE (SIGRTMIN_PORTABLE + 24)
+#define SIGRT_25_PORTABLE (SIGRTMIN_PORTABLE + 25)
+#define SIGRT_25_PORTABLE (SIGRTMIN_PORTABLE + 25)
+#define SIGRT_26_PORTABLE (SIGRTMIN_PORTABLE + 26)
+#define SIGRT_27_PORTABLE (SIGRTMIN_PORTABLE + 27)
+#define SIGRT_28_PORTABLE (SIGRTMIN_PORTABLE + 28)
+#define SIGRT_29_PORTABLE (SIGRTMIN_PORTABLE + 29)
+#define SIGRT_30_PORTABLE (SIGRTMIN_PORTABLE + 30)
+#define SIGRT_31_PORTABLE (SIGRTMIN_PORTABLE + 31)
+#define SIGRT_32_PORTABLE (SIGRTMIN_PORTABLE + 32)
+
+#define SIGRTMAX_PORTABLE NSIG_PORTABLE
+
+/*
+ * Define MIPS/Native Real Time Signal Names for debugging.
+ * NOTE:
+ *    Currently only defining the 32 RT signals that the
+ *    lib-portable application can interact with. MIPS has
+ *    an additional 63 signals.
+ */
+#define SIGRT_1 (SIGRTMIN + 1)
+#define SIGRT_2 (SIGRTMIN + 2)
+#define SIGRT_3 (SIGRTMIN + 3)
+#define SIGRT_4 (SIGRTMIN + 4)
+#define SIGRT_5 (SIGRTMIN + 5)
+#define SIGRT_5 (SIGRTMIN + 5)
+#define SIGRT_6 (SIGRTMIN + 6)
+#define SIGRT_7 (SIGRTMIN + 7)
+#define SIGRT_8 (SIGRTMIN + 8)
+#define SIGRT_9 (SIGRTMIN + 9)
+#define SIGRT_10 (SIGRTMIN + 10)
+#define SIGRT_11 (SIGRTMIN + 11)
+#define SIGRT_12 (SIGRTMIN + 12)
+#define SIGRT_13 (SIGRTMIN + 13)
+#define SIGRT_14 (SIGRTMIN + 14)
+#define SIGRT_15 (SIGRTMIN + 15)
+#define SIGRT_15 (SIGRTMIN + 15)
+#define SIGRT_16 (SIGRTMIN + 16)
+#define SIGRT_17 (SIGRTMIN + 17)
+#define SIGRT_18 (SIGRTMIN + 18)
+#define SIGRT_19 (SIGRTMIN + 19)
+#define SIGRT_20 (SIGRTMIN + 20)
+#define SIGRT_20 (SIGRTMIN + 20)
+#define SIGRT_21 (SIGRTMIN + 21)
+#define SIGRT_22 (SIGRTMIN + 22)
+#define SIGRT_23 (SIGRTMIN + 23)
+#define SIGRT_24 (SIGRTMIN + 24)
+#define SIGRT_25 (SIGRTMIN + 25)
+#define SIGRT_25 (SIGRTMIN + 25)
+#define SIGRT_26 (SIGRTMIN + 26)
+#define SIGRT_27 (SIGRTMIN + 27)
+#define SIGRT_28 (SIGRTMIN + 28)
+#define SIGRT_29 (SIGRTMIN + 29)
+#define SIGRT_30 (SIGRTMIN + 30)
+#define SIGRT_31 (SIGRTMIN + 31)
+#define SIGRT_32 (SIGRTMIN + 32)
+/*
+ * NOTE: Native signals SIGRT_33 ... SIGRTMAX
+ * can't be used by a lib-portable application.
+ */
 
 #define SA_NOCLDSTOP_PORTABLE   0x00000001
 #define SA_NOCLDWAIT_PORTABLE   0x00000002