[MIPS] Add Support errno, Added Logging, sorted Android.mk files.

Change-Id: Ibeeab51feb77be07ea8ccacf2f448bb5135d7373
Signed-off-by: Chris Dearman <chris@mips.com>
Signed-off-by: Pete Delaney   <piet@mips.com>
diff --git a/ndk/sources/android/libportable/Android.mk b/ndk/sources/android/libportable/Android.mk
index 86b097c..3cc203a 100644
--- a/ndk/sources/android/libportable/Android.mk
+++ b/ndk/sources/android/libportable/Android.mk
@@ -30,43 +30,45 @@
 
 ifeq ($(TARGET_ARCH),mips)
 libportable_arch_src_files += \
+			arch-mips/errno.c \
+			arch-mips/epoll.c \
+			arch-mips/fcntl.c \
 			arch-mips/ioctl.c \
 			arch-mips/mmap.c \
-			arch-mips/resource.c \
-			arch-mips/stat.c \
-			arch-mips/statfs.c \
 			arch-mips/open.c \
 			arch-mips/poll.c \
+			arch-mips/resource.c \
 			arch-mips/socket.c \
 			arch-mips/sockopt.c \
-			arch-mips/fcntl.c \
-			arch-mips/epoll.c \
-			arch-mips/errno.c
+			arch-mips/stat.c \
+			arch-mips/statfs.c
 endif
 
 ifeq ($(TARGET_ARCH),arm)
 libportable_arch_src_files += \
-			arch-arm/stat.c \
+			arch-arm/epoll.c \
+			arch-arm/errno.c \
 			arch-arm/socket.c \
 			arch-arm/sockopt.c \
-			arch-arm/epoll.c \
-			arch-arm/errno.c
+			arch-arm/stat.c
 endif
 
 ifeq ($(TARGET_ARCH),x86)
 libportable_arch_src_files += \
+			arch-x86/epoll.c \
+			arch-x86/errno.c \
+			arch-x86/fcntl.c \
 			arch-x86/ioctl.c \
-			arch-x86/stat.c \
 			arch-x86/open.c \
 			arch-x86/socket.c \
 			arch-x86/sockopt.c \
-			arch-x86/fcntl.c \
-			arch-x86/epoll.c \
-			arch-x86/errno.c
+			arch-x86/stat.c
 endif
 
 LOCAL_SRC_FILES := \
         $(libportable_common_src_files) \
         $(libportable_arch_src_files)
 
+LOCAL_SHARED_LIBRARIES += liblog
+
 include $(BUILD_SHARED_LIBRARY)
diff --git a/ndk/sources/android/libportable/arch-mips/errno.c b/ndk/sources/android/libportable/arch-mips/errno.c
index 7372c67..b862902 100644
--- a/ndk/sources/android/libportable/arch-mips/errno.c
+++ b/ndk/sources/android/libportable/arch-mips/errno.c
@@ -14,16 +14,20 @@
  * limitations under the License.
  */
 
+#include <pthread.h>
 #include <errno.h>
 #include <errno_portable.h>
 
+#define PORTABLE_TAG "errno_portable"
+#include <log_portable.h>
+
 #if ENAMETOOLONG==ENAMETOOLONG_PORTABLE
 #error Bad build environment
 #endif
 
-static inline int mips_change_errno(int mips_errno)
+__hidden int ntop_errno(int native_errno)
 {
-    switch (mips_errno) {
+    switch (native_errno) {
       case ENAMETOOLONG: return ENAMETOOLONG_PORTABLE;
       case ENOLCK: return ENOLCK_PORTABLE;
       case ENOSYS: return ENOSYS_PORTABLE;
@@ -121,14 +125,231 @@
       case EOWNERDEAD: return EOWNERDEAD_PORTABLE;
       case ENOTRECOVERABLE: return ENOTRECOVERABLE_PORTABLE;
     }
-    return mips_errno;
+    return native_errno;
 }
 
-extern volatile int*   __errno(void);
+static inline int pton_errno(int portable_errno)
+{
+    switch (portable_errno) {
+      case ENAMETOOLONG_PORTABLE: return ENAMETOOLONG;
+      case ENOLCK_PORTABLE: return ENOLCK;
+      case ENOSYS_PORTABLE: return ENOSYS;
+      case ENOTEMPTY_PORTABLE: return ENOTEMPTY;
+      case ELOOP_PORTABLE: return ELOOP;
+      case EWOULDBLOCK_PORTABLE: return EWOULDBLOCK;
+      case ENOMSG_PORTABLE: return ENOMSG;
+      case EIDRM_PORTABLE: return EIDRM;
+      case ECHRNG_PORTABLE: return ECHRNG;
+      case EL2NSYNC_PORTABLE: return EL2NSYNC;
+      case EL3HLT_PORTABLE: return EL3HLT;
+      case EL3RST_PORTABLE: return EL3RST;
+      case ELNRNG_PORTABLE: return ELNRNG;
+      case EUNATCH_PORTABLE: return EUNATCH;
+      case ENOCSI_PORTABLE: return ENOCSI;
+      case EL2HLT_PORTABLE: return EL2HLT;
+      case EBADE_PORTABLE: return EBADE;
+      case EBADR_PORTABLE: return EBADR;
+      case EXFULL_PORTABLE: return EXFULL;
+      case ENOANO_PORTABLE: return ENOANO;
+      case EBADRQC_PORTABLE: return EBADRQC;
+      case EBADSLT_PORTABLE: return EBADSLT;
+      case EDEADLOCK_PORTABLE: return EDEADLOCK;
+      case EBFONT_PORTABLE: return EBFONT;
+      case ENOSTR_PORTABLE: return ENOSTR;
+      case ENODATA_PORTABLE: return ENODATA;
+      case ETIME_PORTABLE: return ETIME;
+      case ENOSR_PORTABLE: return ENOSR;
+      case ENONET_PORTABLE: return ENONET;
+      case ENOPKG_PORTABLE: return ENOPKG;
+      case EREMOTE_PORTABLE: return EREMOTE;
+      case ENOLINK_PORTABLE: return ENOLINK;
+      case EADV_PORTABLE: return EADV;
+      case ESRMNT_PORTABLE: return ESRMNT;
+      case ECOMM_PORTABLE: return ECOMM;
+      case EPROTO_PORTABLE: return EPROTO;
+      case EMULTIHOP_PORTABLE: return EMULTIHOP;
+      case EDOTDOT_PORTABLE: return EDOTDOT;
+      case EBADMSG_PORTABLE: return EBADMSG;
+      case EOVERFLOW_PORTABLE: return EOVERFLOW;
+      case ENOTUNIQ_PORTABLE: return ENOTUNIQ;
+      case EBADFD_PORTABLE: return EBADFD;
+      case EREMCHG_PORTABLE: return EREMCHG;
+      case ELIBACC_PORTABLE: return ELIBACC;
+      case ELIBBAD_PORTABLE: return ELIBBAD;
+      case ELIBSCN_PORTABLE: return ELIBSCN;
+      case ELIBMAX_PORTABLE: return ELIBMAX;
+      case ELIBEXEC_PORTABLE: return ELIBEXEC;
+      case EILSEQ_PORTABLE: return EILSEQ;
+      case ERESTART_PORTABLE: return ERESTART;
+      case ESTRPIPE_PORTABLE: return ESTRPIPE;
+      case EUSERS_PORTABLE: return EUSERS;
+      case ENOTSOCK_PORTABLE: return ENOTSOCK;
+      case EDESTADDRREQ_PORTABLE: return EDESTADDRREQ;
+      case EMSGSIZE_PORTABLE: return EMSGSIZE;
+      case EPROTOTYPE_PORTABLE: return EPROTOTYPE;
+      case ENOPROTOOPT_PORTABLE: return ENOPROTOOPT;
+      case EPROTONOSUPPORT_PORTABLE: return EPROTONOSUPPORT;
+      case ESOCKTNOSUPPORT_PORTABLE: return ESOCKTNOSUPPORT;
+      case EOPNOTSUPP_PORTABLE: return EOPNOTSUPP;
+      case EPFNOSUPPORT_PORTABLE: return EPFNOSUPPORT;
+      case EAFNOSUPPORT_PORTABLE: return EAFNOSUPPORT;
+      case EADDRINUSE_PORTABLE: return EADDRINUSE;
+      case EADDRNOTAVAIL_PORTABLE: return EADDRNOTAVAIL;
+      case ENETDOWN_PORTABLE: return ENETDOWN;
+      case ENETUNREACH_PORTABLE: return ENETUNREACH;
+      case ENETRESET_PORTABLE: return ENETRESET;
+      case ECONNABORTED_PORTABLE: return ECONNABORTED;
+      case ECONNRESET_PORTABLE: return ECONNRESET;
+      case ENOBUFS_PORTABLE: return ENOBUFS;
+      case EISCONN_PORTABLE: return EISCONN;
+      case ENOTCONN_PORTABLE: return ENOTCONN;
+      case ESHUTDOWN_PORTABLE: return ESHUTDOWN;
+      case ETOOMANYREFS_PORTABLE: return ETOOMANYREFS;
+      case ETIMEDOUT_PORTABLE: return ETIMEDOUT;
+      case ECONNREFUSED_PORTABLE: return ECONNREFUSED;
+      case EHOSTDOWN_PORTABLE: return EHOSTDOWN;
+      case EHOSTUNREACH_PORTABLE: return EHOSTUNREACH;
+      case EALREADY_PORTABLE: return EALREADY;
+      case EINPROGRESS_PORTABLE: return EINPROGRESS;
+      case ESTALE_PORTABLE: return ESTALE;
+      case EUCLEAN_PORTABLE: return EUCLEAN;
+      case ENOTNAM_PORTABLE: return ENOTNAM;
+      case ENAVAIL_PORTABLE: return ENAVAIL;
+      case EISNAM_PORTABLE: return EISNAM;
+      case EREMOTEIO_PORTABLE: return EREMOTEIO;
+      case EDQUOT_PORTABLE: return EDQUOT;
+      case ENOMEDIUM_PORTABLE: return ENOMEDIUM;
+      case EMEDIUMTYPE_PORTABLE: return EMEDIUMTYPE;
+      case ECANCELED_PORTABLE: return ECANCELED;
+      case ENOKEY_PORTABLE: return ENOKEY;
+      case EKEYEXPIRED_PORTABLE: return EKEYEXPIRED;
+      case EKEYREVOKED_PORTABLE: return EKEYREVOKED;
+      case EKEYREJECTED_PORTABLE: return EKEYREJECTED;
+      case EOWNERDEAD_PORTABLE: return EOWNERDEAD;
+      case ENOTRECOVERABLE_PORTABLE: return ENOTRECOVERABLE;
+    }
+    return portable_errno;
+}
+
+/* Key for the thread-specific portable errno */
+static pthread_key_t errno_key;
+
+/* Once-only initialisation of the key */
+static pthread_once_t errno_key_once = PTHREAD_ONCE_INIT;
+
+/* Free the thread-specific portable errno */
+static void errno_key_destroy(void *buf)
+{
+    if (buf)
+        free(buf);
+}
+
+/* Allocate the key */
+static void errno_key_create(void)
+{
+    pthread_key_create(&errno_key, errno_key_destroy);
+}
+
+struct errno_state {
+    int pshadow;                /* copy of last portable errno */
+    int perrno;                 /* portable errno that may be modified by app */
+};
+
+/* Return the thread-specific portable errno */
+static struct errno_state *errno_key_data(void)
+{
+    struct errno_state *data;
+    static struct errno_state errno_state;
+
+    pthread_once(&errno_key_once, errno_key_create);
+    data = (struct errno_state *)pthread_getspecific(errno_key);
+    if (data == NULL) {
+        data = malloc(sizeof(struct errno_state));
+        pthread_setspecific(errno_key, data);
+    }
+    if (data == NULL)
+        data = &errno_state;
+    return data;
+}
+
+/*
+ * Attempt to return a thread specific location containnig the portable errno.
+ * This can be assigned to without affecting the native errno. If the key
+ * allocation fails fall back to using the native errno location.
+ */
 volatile int* __errno_portable()
 {
-  /* Note that writing to static_errno will not affect the underlying system. */
-  static int static_errno;
-  static_errno = mips_change_errno(*__errno());
-  return &static_errno;
+    struct errno_state *p;
+    int save_errno;
+
+    /* pthread_* calls may modify errno so use a copy */
+    save_errno = errno;
+
+    p = errno_key_data();
+
+    ALOGV("%s(): { save_errno:%d p=%p->{pshadow:%d perrno:%d}", __func__,
+                   save_errno,   p,  p->pshadow,p->perrno);
+
+    if (save_errno == 0 && p->pshadow != p->perrno) {
+        /*
+         * portable errno has changed but native hasn't
+         * - copy portable error back to native
+         */
+        p->pshadow = p->perrno;
+        save_errno = pton_errno(p->perrno);
+    }
+    else if (save_errno != 0 && p->pshadow == p->perrno) {
+        /*
+         * native errno has changed but portable hasn't
+         * - copy native error to portable
+         */
+        p->pshadow = p->perrno = ntop_errno(save_errno);
+        save_errno = 0;
+    }
+    else if (save_errno != 0 && p->pshadow != p->perrno) {
+        /*
+         * both native and portable errno values have changed
+         * so give priority to native errno
+         * - copy native error to portable
+         */
+        p->pshadow = p->perrno = ntop_errno(save_errno);
+        save_errno = 0;
+    }
+
+    ALOGV("%s: new save_errno=%d p=%p->{pshadow=%d perrno=%d}", __func__,
+                   save_errno,   p,  p->pshadow,p->perrno);
+
+    errno = save_errno;
+
+    ALOGV("%s: return &p->perrno:%p; }", __func__, &p->perrno);
+
+    /* return pointer to the modifiable portable errno value */
+    return &p->perrno;
+}
+
+
+/* set portable errno */
+void __set_errno_portable(int portable_errno)
+{
+    struct errno_state *p;
+    int save_errno;
+
+    /* pthread_* calls may modify errno so use a copy */
+    save_errno = errno;
+
+    p = errno_key_data();
+
+    ALOGV("%s(): { save_errno:%d p=%p->{pshadow:%d perrno:%d}", __func__,
+                   save_errno,   p,  p->pshadow,p->perrno);
+
+    p->pshadow = p->perrno = portable_errno;
+
+    save_errno = pton_errno(portable_errno);
+
+    ALOGV("%s: new save_errno=%d p=%p->{pshadow=%d perrno=%d}", __func__,
+                   save_errno,   p,  p->pshadow,p->perrno);
+
+    errno = save_errno;
+
+    ALOGV("%s: return; }", __func__);
 }
diff --git a/ndk/sources/android/libportable/common/include/errno_portable.h b/ndk/sources/android/libportable/common/include/errno_portable.h
index c2f6523..07b8731 100644
--- a/ndk/sources/android/libportable/common/include/errno_portable.h
+++ b/ndk/sources/android/libportable/common/include/errno_portable.h
@@ -17,7 +17,14 @@
 #ifndef _ERRNO_PORTABLE_H_
 #define _ERRNO_PORTABLE_H_
 
-/* Derived from development/ndk/platforms/android-3/include/asm-generic/errno.h */
+#include <portability.h>
+
+/*
+ * Derived from development/ndk/platforms/android-3/include/asm-generic/errno.h
+ * NOTE:
+ *   Base errno #defines from 1...35 are ARCH independent and not defined;
+ *   they are defined in ./asm-generic/errno-base.h
+ */
 #define EDEADLK_PORTABLE 35
 #define ENAMETOOLONG_PORTABLE 36
 #define ENOLCK_PORTABLE 37
@@ -120,4 +127,6 @@
 #define EOWNERDEAD_PORTABLE 130
 #define ENOTRECOVERABLE_PORTABLE 131
 
+extern __hidden int ntop_errno(int native_errno);
+
 #endif /* _ERRNO_PORTABLE_H */
diff --git a/ndk/sources/android/libportable/common/include/log_portable.h b/ndk/sources/android/libportable/common/include/log_portable.h
new file mode 100644
index 0000000..59a44f9
--- /dev/null
+++ b/ndk/sources/android/libportable/common/include/log_portable.h
@@ -0,0 +1,75 @@
+/*
+ * ALOG Levels: F - Fatal, E - Error, W - Warning, I - Info, D - Debug, V - Verbose
+ *
+ * Using them to work within the Android logcat logging mechanism:
+ *
+ *    % logcat '*:v'                    [To display Verbose Logging]
+ *    % logcat 'fcntl_portable:v'       [To display just this fcntl logging]
+ *
+ * NOTE: This assumes you only use the portable TAG; which is the default.
+ *       For debugging LTP it's been helpful to include the LTP program being tested.
+ *
+ * Logging routines also support ALOG*_IF() and ASSERT(); For details See:
+ *
+ *       ${ANDROID_TOP}/system/core/include/cutils/log.h
+ * and
+ *        http://developer.android.com/tools/debugging/debugging-log.html
+ *
+ * ALOGV is turned off by release builds: Use the #define below with LOG_NDEBUG=0 to enable.
+ *
+ * Strace works fine with ALOG out if a large max string size is used via the -s option; Ex:
+ *
+ *      strace -s 132 ./sigaction01
+ *
+ *          writev(3, [{"\2", 1},
+ *                 {"./sigaction01`signal_portable\0", 30},
+ *                      {"sigaction_portable(portable_signum:10:'SIGUSR1_PORTABLE:10', act:0x7fe47a08, oldact:0x0) {\0", 91}], 3) = 122
+ *                      {"map_portable_sigset_to_mips(portable_sigset:0x7fe47a0c, mips_sigset:0x7fe479b8) {\0", 82}], 3) = 113
+ *                      ...
+ */
+
+/*
+ * Remove the // below to have debug code visible in logcat output by default.
+ * It's Also possible via libportable/Android.mk:
+ *    LOCAL_CFLAGS += -DLOG_NDEBUG=0
+ */
+// # define LOG_NDEBUG 0
+
+
+
+// #define EXTENDED_LOGGING
+#ifdef EXTENDED_LOGGING
+/*
+ * Inline function to put the current LTP program and this library into the logcat prefix; Ex:
+ *
+ *    V/./sigaction01`signal_portable(605): sigaction_portable(portable_signum:10:'SIGUSR1_PORTABLE:10', act:0x7fe47a08, oldact:0x0) {
+ *      -----------------------------
+ *
+ * Disabled by default, enable by removing the // above. Useful when debugging more than one program; Ex: LTP has thousands.
+ */
+#define MAX_TAG_LEN 128
+static char my_portable_tag[MAX_TAG_LEN + 1];
+
+static inline char *portable_tag() {
+    extern char *__progname;
+
+    if (my_portable_tag[0] == '\000') {
+
+        strncat(&my_portable_tag[0], __progname, MAX_TAG_LEN);
+        strncat(&my_portable_tag[0], ".", MAX_TAG_LEN - strlen(my_portable_tag));
+        strncat(&my_portable_tag[0], PORTABLE_TAG, MAX_TAG_LEN - strlen(my_portable_tag));
+    }
+    return(my_portable_tag);
+}
+#define LOG_TAG  portable_tag()
+#else /* !EXTENDED_LOGGING */
+#define LOG_TAG PORTABLE_TAG
+#endif
+
+# include <cutils/log.h>
+
+# define PERROR(str)  { ALOGE("%s: PERROR('%s'): errno:%d:'%s'", __func__, str, errno, strerror(errno)); }
+
+# define ASSERT(cond) ALOG_ASSERT(cond, "assertion failed:(%s), file: %s, line: %d:%s",  \
+                                 #cond, __FILE__, __LINE__, __func__);
+
diff --git a/ndk/sources/android/libportable/common/include/portability.h b/ndk/sources/android/libportable/common/include/portability.h
new file mode 100644
index 0000000..4293d9d
--- /dev/null
+++ b/ndk/sources/android/libportable/common/include/portability.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _PORTABILITY_H_
+#define _PORTABILITY_H_
+
+/*
+ * Common portability helper routines
+ */
+
+/*
+ * Check a portable pointer before we access it
+ * Well behaved programs should not be passing bad pointers
+ * to the kernel but this routine can be used to check a pointer
+ * if we need to use it before calling the kernel
+ *
+ * It does not catch every possible case but it is sufficient for LTP
+ */
+inline static int invalid_pointer(void *p)
+{
+    return p == NULL
+        || p == (void *)-1
+#ifdef __mips__
+        || (int)p < 0
+#endif
+        ;
+}
+
+/*
+ * Hidden functions are exposed while linking the libportable shared object
+ * but are not exposed thereafter.
+ */
+#define __hidden __attribute__((visibility("hidden")))
+
+#endif /* _PORTABILITY_H_ */