Merge "[MIPS] Add Support errno, Added Logging, sorted Android.mk files."
This commit is contained in:
@@ -30,43 +30,45 @@ LOCAL_CFLAGS := -I $(LOCAL_PATH)/common/include
|
||||
|
||||
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)
|
||||
|
||||
@@ -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 @@ static inline int mips_change_errno(int mips_errno)
|
||||
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__);
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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__);
|
||||
|
||||
48
ndk/sources/android/libportable/common/include/portability.h
Normal file
48
ndk/sources/android/libportable/common/include/portability.h
Normal file
@@ -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_ */
|
||||
Reference in New Issue
Block a user