aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authornjn <njn@a5019735-40e9-0310-863c-91ae7b9d1cf9>2009-05-18 02:12:08 +0000
committernjn <njn@a5019735-40e9-0310-863c-91ae7b9d1cf9>2009-05-18 02:12:08 +0000
commitcda2f0fbda4c4b2644babc830244be8aed95de1d (patch)
treec78eca73df999f28d009f547b4b6f99ec990d1f8 /include
parent7f08c73f29b0bd8f23c1fc6d1e88ab44e2352160 (diff)
downloadvalgrind-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.h90
-rw-r--r--include/pub_tool_libcfile.h4
-rw-r--r--include/vki/vki-amd64-linux.h8
-rw-r--r--include/vki/vki-ppc32-linux.h12
-rw-r--r--include/vki/vki-ppc64-linux.h8
-rw-r--r--include/vki/vki-x86-linux.h12
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;