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

This commit is contained in:
Andrew Hsieh
2012-10-05 02:12:51 -07:00
committed by Gerrit Code Review
5 changed files with 377 additions and 22 deletions

View File

@@ -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)

View File

@@ -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__);
}

View File

@@ -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 */

View File

@@ -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__);

View 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_ */