diff options
author | njn <njn@a5019735-40e9-0310-863c-91ae7b9d1cf9> | 2009-05-18 02:12:08 +0000 |
---|---|---|
committer | njn <njn@a5019735-40e9-0310-863c-91ae7b9d1cf9> | 2009-05-18 02:12:08 +0000 |
commit | cda2f0fbda4c4b2644babc830244be8aed95de1d (patch) | |
tree | c78eca73df999f28d009f547b4b6f99ec990d1f8 /include | |
parent | 7f08c73f29b0bd8f23c1fc6d1e88ab44e2352160 (diff) | |
download | valgrind-cda2f0fbda4c4b2644babc830244be8aed95de1d.tar.gz |
Merged non-Darwin-specific parts of r9397,r9423,r9490, 9461, 9462 from the
DARWIN branch. A big ugly DARWIN/trunk sync commit, mostly to do with
changing the representation of SysRes and vki_sigset_t. Functionality of
the trunk shouldn't be changed by it.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@9876 a5019735-40e9-0310-863c-91ae7b9d1cf9
Diffstat (limited to 'include')
-rw-r--r-- | include/pub_tool_basics.h | 90 | ||||
-rw-r--r-- | include/pub_tool_libcfile.h | 4 | ||||
-rw-r--r-- | include/vki/vki-amd64-linux.h | 8 | ||||
-rw-r--r-- | include/vki/vki-ppc32-linux.h | 12 | ||||
-rw-r--r-- | include/vki/vki-ppc64-linux.h | 8 | ||||
-rw-r--r-- | include/vki/vki-x86-linux.h | 12 |
6 files changed, 111 insertions, 23 deletions
diff --git a/include/pub_tool_basics.h b/include/pub_tool_basics.h index 9bff837fc..89d66f5a6 100644 --- a/include/pub_tool_basics.h +++ b/include/pub_tool_basics.h @@ -135,32 +135,88 @@ typedef UInt ThreadId; /* An abstraction of syscall return values. Linux: - When .isError == False, - res holds the return value, and err is zero. - When .isError == True, - err holds the error code, and res is zero. + When _isError == False, + _val holds the return value. + When _isError == True, + _err holds the error code. AIX: - res is the POSIX result of the syscall. - err is the corresponding errno value. - isError === err==0 + _res is the POSIX result of the syscall. + _err is the corresponding errno value. + _isError === _err==0 - Unlike on Linux, it is possible for 'err' to be nonzero (thus an - error has occurred), nevertheless 'res' is also nonzero. AIX - userspace does not appear to consistently inspect 'err' to + Unlike on Linux, it is possible for _err to be nonzero (thus an + error has occurred), nevertheless _res is also nonzero. AIX + userspace does not appear to consistently inspect _err to determine whether or not an error has occurred. For example, - sys_open() will return -1 for 'val' if a file cannot be opened, - as well as the relevant errno value in 'err', but AIX userspace - then consults 'val' to figure out if the syscall failed, rather - than looking at 'err'. Hence we need to represent them both. + sys_open() will return -1 for _val if a file cannot be opened, + as well as the relevant errno value in _err, but AIX userspace + then consults _val to figure out if the syscall failed, rather + than looking at _err. Hence we need to represent them both. + + Darwin: + Interpretation depends on _mode: + MACH, MDEP: + these can never 'fail' (apparently). The result of the + syscall is a single host word, _wLO. + UNIX: + Can record a double-word error or a double-word result: + When _mode is SysRes_UNIX_OK, _wHI:_wLO holds the result. + When _mode is SysRes_UNIX_ERR, _wHI:_wLO holds the error code. + Probably the high word of an error is always ignored by + userspace, but we have to record it, so that we can correctly + update both EDX and EAX (in guest state) given a SysRes, if + we're required to. */ +#if defined(VGO_linux) typedef struct { - UWord res; - UWord err; - Bool isError; + UWord _val; + Bool _isError; } SysRes; +#elif defined(VGO_aix5) +typedef + struct { + UWord _res; + UWord _err; + Bool _isError; + } + SysRes; +#else +# error "Unknown OS" +#endif + + +/* ---- And now some basic accessor functions for it. ---- */ + +#if defined(VGO_linux) + +static inline Bool sr_isError ( SysRes sr ) { + return sr._isError; +} +static inline UWord sr_Res ( SysRes sr ) { + return sr._isError ? 0 : sr._val; +} +static inline UWord sr_ResHI ( SysRes sr ) { + return 0; +} +static inline UWord sr_Err ( SysRes sr ) { + return sr._isError ? sr._val : 0; +} +static inline Bool sr_EQ ( SysRes sr1, SysRes sr2 ) { + return sr1._val == sr2._val + && ((sr1._isError && sr2._isError) + || (!sr1._isError && !sr2._isError)); +} + +#elif defined(VGO_aix5) +# error "need to define SysRes accessors on AIX5 (copy from 3.4.1 sources)" + + +#else +# error "Unknown OS" +#endif /* --------------------------------------------------------------------- diff --git a/include/pub_tool_libcfile.h b/include/pub_tool_libcfile.h index f870109f3..63fb0b39a 100644 --- a/include/pub_tool_libcfile.h +++ b/include/pub_tool_libcfile.h @@ -70,7 +70,7 @@ extern Int VG_(write) ( Int fd, const void* buf, Int count); extern Int VG_(pipe) ( Int fd[2] ); extern OffT VG_(lseek) ( Int fd, OffT offset, Int whence ); -extern SysRes VG_(stat) ( Char* file_name, struct vg_stat* buf ); +extern SysRes VG_(stat) ( const Char* file_name, struct vg_stat* buf ); extern Int VG_(fstat) ( Int fd, struct vg_stat* buf ); extern SysRes VG_(dup) ( Int oldfd ); extern SysRes VG_(dup2) ( Int oldfd, Int newfd ); @@ -78,7 +78,7 @@ extern Int VG_(rename) ( Char* old_name, Char* new_name ); extern Int VG_(unlink) ( Char* file_name ); extern Int VG_(readlink)( Char* path, Char* buf, UInt bufsize ); -extern Int VG_(getdents)( UInt fd, struct vki_dirent *dirp, UInt count ); +extern Int VG_(getdents)( Int fd, struct vki_dirent *dirp, UInt count ); /* Copy the working directory at startup into buf[0 .. size-1], or return False if buf is too small. */ diff --git a/include/vki/vki-amd64-linux.h b/include/vki/vki-amd64-linux.h index 50e7dcbc3..bc5c45512 100644 --- a/include/vki/vki-amd64-linux.h +++ b/include/vki/vki-amd64-linux.h @@ -143,7 +143,7 @@ typedef __vki_restorefn_t __user *__vki_sigrestore_t; #define VKI_SIG_DFL ((__vki_sighandler_t)0) /* default signal handling */ #define VKI_SIG_IGN ((__vki_sighandler_t)1) /* ignore signal */ -struct vki_sigaction { +struct vki_sigaction_base { // [[Nb: a 'k' prefix is added to "sa_handler" because // bits/sigaction.h (which gets dragged in somehow via signal.h) // #defines it as something else. Since that is done for glibc's @@ -154,6 +154,12 @@ struct vki_sigaction { vki_sigset_t sa_mask; /* mask last for extensibility */ }; +/* On Linux we use the same type for passing sigactions to + and from the kernel. Hence: */ +typedef struct vki_sigaction_base vki_sigaction_toK_t; +typedef struct vki_sigaction_base vki_sigaction_fromK_t; + + typedef struct vki_sigaltstack { void __user *ss_sp; int ss_flags; diff --git a/include/vki/vki-ppc32-linux.h b/include/vki/vki-ppc32-linux.h index 074a8f84e..69932c04c 100644 --- a/include/vki/vki-ppc32-linux.h +++ b/include/vki/vki-ppc32-linux.h @@ -154,6 +154,10 @@ typedef struct { #define VKI_SS_ONSTACK 1 #define VKI_SS_DISABLE 2 +/* These are 'legacy' sigactions in which the size of sa_mask is fixed + (cannot be expanded at any future point) because it is sandwiched + between two other fields. + (there is identical kludgery in vki-x86-linux.h) */ struct vki_old_sigaction { // [[Nb: a 'k' prefix is added to "sa_handler" because // bits/sigaction.h (which gets dragged in somehow via signal.h) @@ -165,7 +169,7 @@ struct vki_old_sigaction { __vki_sigrestore_t sa_restorer; }; -struct vki_sigaction { +struct vki_sigaction_base { // [[See comment about extra 'k' above]] __vki_sighandler_t ksa_handler; unsigned long sa_flags; @@ -173,6 +177,12 @@ struct vki_sigaction { vki_sigset_t sa_mask; /* mask last for extensibility */ }; +/* On Linux we use the same type for passing sigactions to + and from the kernel. Hence: */ +typedef struct vki_sigaction_base vki_sigaction_toK_t; +typedef struct vki_sigaction_base vki_sigaction_fromK_t; + + typedef struct vki_sigaltstack { void __user *ss_sp; int ss_flags; diff --git a/include/vki/vki-ppc64-linux.h b/include/vki/vki-ppc64-linux.h index 063fc55a4..610a16361 100644 --- a/include/vki/vki-ppc64-linux.h +++ b/include/vki/vki-ppc64-linux.h @@ -164,13 +164,19 @@ struct vki_old_sigaction { __vki_sigrestore_t sa_restorer; }; -struct vki_sigaction { +struct vki_sigaction_base { __vki_sighandler_t ksa_handler; unsigned long sa_flags; __vki_sigrestore_t sa_restorer; vki_sigset_t sa_mask; /* mask last for extensibility */ }; +/* On Linux we use the same type for passing sigactions to + and from the kernel. Hence: */ +typedef struct vki_sigaction_base vki_sigaction_toK_t; +typedef struct vki_sigaction_base vki_sigaction_fromK_t; + + typedef struct vki_sigaltstack { void __user *ss_sp; int ss_flags; diff --git a/include/vki/vki-x86-linux.h b/include/vki/vki-x86-linux.h index 13a4e4e96..08aed502f 100644 --- a/include/vki/vki-x86-linux.h +++ b/include/vki/vki-x86-linux.h @@ -149,6 +149,10 @@ typedef struct { #define VKI_SS_ONSTACK 1 #define VKI_SS_DISABLE 2 +/* These are 'legacy' sigactions in which the size of sa_mask is fixed + (cannot be expanded at any future point) because it is sandwiched + between two other fields. + (there is identical kludgery in vki-ppc32-linux.h) */ struct vki_old_sigaction { // [[Nb: a 'k' prefix is added to "sa_handler" because // bits/sigaction.h (which gets dragged in somehow via signal.h) @@ -160,7 +164,7 @@ struct vki_old_sigaction { __vki_sigrestore_t sa_restorer; }; -struct vki_sigaction { +struct vki_sigaction_base { // [[See comment about extra 'k' above]] __vki_sighandler_t ksa_handler; unsigned long sa_flags; @@ -168,6 +172,12 @@ struct vki_sigaction { vki_sigset_t sa_mask; /* mask last for extensibility */ }; +/* On Linux we use the same type for passing sigactions to + and from the kernel. Hence: */ +typedef struct vki_sigaction_base vki_sigaction_toK_t; +typedef struct vki_sigaction_base vki_sigaction_fromK_t; + + typedef struct vki_sigaltstack { void __user *ss_sp; int ss_flags; |