summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhunt <hunt>2007-09-27 17:43:03 +0000
committerhunt <hunt>2007-09-27 17:43:03 +0000
commit3cd0e15acc565ac8b02f99e3750118c93fd6324c (patch)
treeb83ad42ea72da44d20ebf87712299ca7b622faab
parent47e0dd932cad3716b167e043678b52e06f32a2f8 (diff)
downloadsystemtap-steved-3cd0e15acc565ac8b02f99e3750118c93fd6324c.tar.gz
systemtap-steved-3cd0e15acc565ac8b02f99e3750118c93fd6324c.tar.xz
systemtap-steved-3cd0e15acc565ac8b02f99e3750118c93fd6324c.zip
2007-09-27 Martin Hunt <hunt@redhat.com>
* aux_syscalls.stp (_stp_lookup_str, _stp_lookup_or_str): New functions to efficiently and safely read arrays of values and return a string. (_signal_name): Reimplement using _stp_lookup_str(). (_semctl_cmd): Ditto. (__fork_flags): Ditto. (_mmap_flags): Ditto. (_mprotect_prot_str): Ditto. (_shmat_flags_str): Ditto. (_at_flag_str): Ditto. (get_mmap_args): Complete rewrite for safety and correctness.
-rw-r--r--tapset/ChangeLog14
-rw-r--r--tapset/aux_syscalls.stp540
2 files changed, 268 insertions, 286 deletions
diff --git a/tapset/ChangeLog b/tapset/ChangeLog
index 65abd7d5..59a73895 100644
--- a/tapset/ChangeLog
+++ b/tapset/ChangeLog
@@ -1,3 +1,17 @@
+2007-09-27 Martin Hunt <hunt@redhat.com>
+
+ * aux_syscalls.stp (_stp_lookup_str, _stp_lookup_or_str):
+ New functions to efficiently and safely read arrays of values
+ and return a string.
+ (_signal_name): Reimplement using _stp_lookup_str().
+ (_semctl_cmd): Ditto.
+ (__fork_flags): Ditto.
+ (_mmap_flags): Ditto.
+ (_mprotect_prot_str): Ditto.
+ (_shmat_flags_str): Ditto.
+ (_at_flag_str): Ditto.
+ (get_mmap_args): Complete rewrite for safety and correctness.
+
2007-09-27 Wenji Huang <wenji.huang@oracle.com>
* rpc.stp (clones_from_clnt, tasks_from_clnt): Fix for kernel >= 2.6.22.
diff --git a/tapset/aux_syscalls.stp b/tapset/aux_syscalls.stp
index 25984d57..cb47464f 100644
--- a/tapset/aux_syscalls.stp
+++ b/tapset/aux_syscalls.stp
@@ -382,103 +382,6 @@ function _struct_sockaddr_u:string(uaddr:long, len:long)
}
%}
-function _signal_name:string(sig:long)
-%{ /* pure */
- int sig = THIS->sig;
- char *res = 0;
-
- switch(sig) {
- case 0:
- res = "NO_SIGNAL";
- break;
- case SIGHUP:
- res = "SIGHUP";
- break;
- case SIGINT:
- res = "SIGINT";
- break;
- case SIGQUIT:
- res = "SIGQUIT";
- break;
- case SIGILL:
- res = "SIGILL";
- break;
- case SIGTRAP:
- res = "SIGTRAP";
- break;
- case SIGABRT:
- res = "SIGABRT";
- break;
- case SIGBUS:
- res = "SIGBUS";
- break;
- case SIGFPE:
- res = "SIGFPE";
- break;
- case SIGKILL:
- res = "SIGKILL";
- break;
- case SIGUSR1:
- res = "SIGUSR1";
- break;
- case SIGSEGV:
- res = "SIGSEGV";
- break;
- case SIGPIPE:
- res = "SIGPIPE";
- break;
- case SIGUSR2:
- res = "SIGUSR2";
- break;
- case SIGALRM:
- res = "SIGALRM";
- break;
- case SIGTERM:
- res = "SIGTERM";
- break;
- case SIGCHLD:
- res = "SIGCHLD";
- break;
- case SIGCONT:
- res = "SIGCONT";
- break;
- case SIGSTOP:
- res = "SIGSTOP";
- break;
- case SIGTSTP:
- res = "SIGTSTP";
- break;
- case SIGTTIN:
- res = "SIGTTIN";
- break;
- case SIGTTOU:
- res = "SIGTTOU";
- break;
- case SIGURG:
- res = "SIGURG";
- break;
- case SIGPROF:
- res = "SIGPROF";
- break;
- case SIGWINCH:
- res = "SIGWINCH";
- break;
- case SIGVTALRM:
- res = "SIGVTALRM";
- break;
- case SIGIO:
- res = "SIGIO/SIGPOLL";
- break;
- case SIGPWR:
- res = "SIGPWR";
- break;
- }
- if (res)
- strlcpy (THIS->__retvalue, res, MAXSTRINGLEN);
- else
- snprintf(THIS->__retvalue, MAXSTRINGLEN, "%d", sig);
-%}
-
function _struct_rlimit_u:string(uaddr:long)
%{ /* pure */
struct rlimit rl;
@@ -510,57 +413,6 @@ function _fildes_u:string (uaddr:long)
}
%}
-function _semctl_cmd:string(cmd:long)
-%{ /* pure */
- int cmd = THIS->cmd;
- char *res = 0;
-
- switch(cmd) {
- case IPC_INFO:
- res = "IPC_INFO";
- break;
- case SEM_INFO:
- res = "SEM_INFO";
- break;
- case SEM_STAT:
- res = "SEM_STAT";
- break;
- case GETALL:
- res = "GETALL";
- break;
- case GETVAL:
- res = "GETVAL";
- break;
- case GETPID:
- res = "GETPID";
- break;
- case GETNCNT:
- res = "GETNCNT";
- break;
- case GETZCNT:
- res = "GETZCNT";
- break;
- case IPC_STAT:
- res = "IPC_STAT";
- break;
- case SETVAL:
- res = "SETVAL";
- break;
- case SETALL:
- res = "SETALL";
- break;
- case IPC_RMID:
- res = "IPC_RMID";
- break;
- case IPC_SET:
- res = "IPC_SET";
- break;
- }
- if (res)
- strlcpy (THIS->__retvalue, res, MAXSTRINGLEN);
- else
- snprintf(THIS->__retvalue, MAXSTRINGLEN, "%d", cmd);
-%}
function __sem_flags:string(semflg:long)
%{ /* pure */
@@ -575,49 +427,6 @@ function __sem_flags:string(semflg:long)
str[strlen(str)-1] = 0;
%}
-function __fork_flags:string(flags:long)
-%{ /* pure */
- int len;
- long flags = THIS->flags;
- char *str = THIS->__retvalue;
- if (flags & CLONE_VM)
- strlcat(str,"CLONE_VM|", MAXSTRINGLEN);
- if (flags & CLONE_FS)
- strlcat(str,"CLONE_FS|", MAXSTRINGLEN);
- if (flags & CLONE_FILES)
- strlcat(str, "CLONE_FILES|", MAXSTRINGLEN);
- if (flags & CLONE_SIGHAND)
- strlcat(str, "CLONE_SIGHAND|", MAXSTRINGLEN);
- if (flags & CLONE_PTRACE)
- strlcat(str, "CLONE_PTRACE|", MAXSTRINGLEN);
- if (flags & CLONE_VFORK)
- strlcat(str, "CLONE_VFORK|", MAXSTRINGLEN);
- if (flags & CLONE_PARENT)
- strlcat(str, "CLONE_PARENT|", MAXSTRINGLEN);
- if (flags & CLONE_THREAD)
- strlcat(str, "CLONE_THREAD|", MAXSTRINGLEN);
- if (flags & CLONE_NEWNS)
- strlcat(str,"CLONE_NEWNS|", MAXSTRINGLEN);
- if (flags & CLONE_SYSVSEM)
- strlcat(str, "CLONE_SYSVSEM|", MAXSTRINGLEN);
- if (flags & CLONE_SETTLS)
- strlcat(str, "CLONE_SETTLS|", MAXSTRINGLEN);
- if (flags & CLONE_PARENT_SETTID)
- strlcat(str, "CLONE_PARENT_SETTID|", MAXSTRINGLEN);
- if (flags & CLONE_CHILD_CLEARTID)
- strlcat(str, "CLONE_CHILD_CLEARTID|", MAXSTRINGLEN);
- if (flags & CLONE_DETACHED)
- strlcat(str, "CLONE_DETACHED|", MAXSTRINGLEN);
- if (flags & CLONE_UNTRACED)
- strlcat(str, "CLONE_UNTRACED|", MAXSTRINGLEN);
- if (flags & CLONE_CHILD_SETTID)
- strlcat(str, "CLONE_CHILD_SETTID|", MAXSTRINGLEN);
- if (flags & CLONE_STOPPED)
- strlcat(str, "CLONE_STOPPED|", MAXSTRINGLEN);
- len = strlen(str);
- if (len)
- str[strlen(str)-1] = 0;
-%}
/* This function copies an argv from userspace. */
function __get_argv:string(a:long, first:long)
@@ -1360,38 +1169,12 @@ function _statfs_f_type_str(f) {
return sprintf("UNKNOWN VALUE: %d", f)
}
-function _mmap_flags(flags) {
- if (flags & 1) msg="MAP_SHARED|"
- if (flags & 2) msg="MAP_PRIVATE|".msg
- if (flags & 0x10) msg="MAP_FIXED|".msg
- if (flags & 0x20) msg="MAP_ANONYMOUS|".msg
- if (flags & 0x100) msg="MAP_GROWSDOWN|".msg
- if (flags & 0x800) msg="MAP_DENYWRITE|".msg
- if (flags & 0x1000) msg="MAP_EXECUTABLE|".msg
- if (flags & 0x2000) msg="MAP_LOCKED|".msg
- if (flags & 0x4000) msg="MAP_NORESERVE|".msg
- if (flags & 0x8000) msg="MAP_POPULATE|".msg
- if (flags & 0x10000) msg="MAP_NONBLOCK|".msg
- return substr(msg,0,strlen(msg)-1)
-}
-
function _mremap_flags(flags) {
if (flags & 1) msg="MREMAP_MAYMOVE|"
if (flags & 2) msg="MREMAP_FIXED|".msg
return substr(msg,0,strlen(msg)-1)
}
-function _mprotect_prot_str(prot) {
- if (prot) {
- if(prot & 1) ps="PROT_READ|"
- if(prot & 2) ps="PROT_WRITE|".ps
- if(prot & 4) ps="PROT_EXEC|".ps
- if(prot & 8) ps="PROT_SEM |".ps
- return substr(ps,0,strlen(ps)-1)
- }
- return "PROT_NONE"
-}
-
function _madvice_advice_str(behavior) {
if(behavior==0x00000000) return "MADV_NORMAL"
if(behavior==0x00000001) return "MADV_RANDOM"
@@ -1723,68 +1506,6 @@ function __int32:long(val:long) %{ /* pure */
THIS->__retvalue = (int32_t)THIS->val;
%}
-function _shmat_flags_str(f) {
- if(f & 010000) bs="SHM_RDONLY|".bs
- if(f & 020000) bs="SHM_RND|".bs
- if(f & 040000) bs="SHM_REMAP|".bs
- if(f & 0100000) bs="SHM_EXEC|".bs
- return substr(bs,0,strlen(bs)-1)
-}
-
-function get_mmap_args:string (args:long)
-%{
- struct mmap_arg_struct {
- unsigned long addr;
- unsigned long len;
- unsigned long prot;
- unsigned long flags;
- unsigned long fd;
- unsigned long offset;
- }a;
-
- char proto[60];
- char flags[256];
-
- if(_stp_copy_from_user((char *)&a,
- (char *)THIS->args, sizeof(a))== 0){
-
- /* _mprotect_prot_str */
- proto[0] = '\0';
- if(a.prot){
- if(a.prot & 1) strcat (proto, "PROT_READ|");
- if(a.prot & 2) strcat (proto, "PROT_WRITE|");
- if(a.prot & 4) strcat (proto, "PROT_EXEC|");
- } else {
- strcat (proto, "PROT_NONE");
- }
- if (proto[0] != '\0') proto[strlen(proto)-1] = '\0';
-
- /* _mmap_flags */
- flags[0]='\0';
- if (a.flags & 1) strcat (flags, "MAP_SHARED|");
- if (a.flags & 2) strcat (flags, "MAP_PRIVATE|");
- if (a.flags & 0x10) strcat (flags, "MAP_FIXED|");
- if (a.flags & 0x20) strcat (flags, "MAP_ANONYMOUS|");
- if (a.flags & 0x100) strcat (flags, "MAP_GROWSDOWN|");
- if (a.flags & 0x800) strcat (flags, "MAP_DENYWRITE|");
- if (a.flags & 0x1000) strcat (flags, "MAP_EXECUTABLE|");
- if (a.flags & 0x2000) strcat (flags, "MAP_LOCKED|");
- if (a.flags & 0x4000) strcat (flags, "MAP_NORESERVE|");
- if (a.flags & 0x8000) strcat (flags, "MAP_POPULATE|");
- if (a.flags & 0x10000) strcat (flags, "MAP_NONBLOCK|");
- if (flags[0] != '\0') flags[strlen(flags)-1] = '\0';
-
- sprintf(THIS->__retvalue,"0x%lx, %ld, %s, %s, %ld, %ld",
- a.addr,
- a.len,
- proto,
- flags,
- a.fd,
- a.offset);
- }else{
- strlcpy (THIS->__retvalue, "UNKNOWN", MAXSTRINGLEN);
- }
-%}
# For utimensat and futimesat, the directory fd can have a special value
function _dfd_str(d) {
@@ -1792,13 +1513,6 @@ function _dfd_str(d) {
return sprint(d)
}
-function _at_flag_str(f) {
- if (f == 0x100) return "AT_SYMLINK_NOFOLLOW"
- if (f == 0x200) return "AT_REMOVEDIR"
- if (f == 0x400) return "AT_SYMLINK_FOLLOW"
- return sprintf("0x%x", f)
-}
-
function _adjtimex_return_str(ret) {
if (ret == 0)
val = "OK"
@@ -1819,3 +1533,257 @@ function _adjtimex_return_str(ret) {
return returnstr(1)
}
+%{
+/*
+* Simple lookup functions for mapping values to names
+* using embedded C. Use these functions to create safe,
+* consistent lookups.
+*/
+
+/* Convenient macro to add defines to an array */
+#define V(a) {a,#a}
+
+typedef struct {
+ long val;
+ char *name;
+} _stp_val_array;
+
+void _stp_lookup_str(const _stp_val_array * const array, long val, char *ptr, int len)
+{
+ int i = 0;
+ while (array[i].name) {
+ if (array[i].val == val) {
+ strlcat (ptr, array[i].name, len);
+ return;
+ }
+ i++;
+ }
+ snprintf(ptr, len, "%ld", val);
+}
+void _stp_lookup_or_str(const _stp_val_array * const array, long val, char *ptr, int len)
+{
+ int i = 0, flag = 0;
+ while (array[i].name) {
+ if (array[i].val & val) {
+ if (flag)
+ strlcat(ptr, "|", len);
+ strlcat(ptr, array[i].name, len);
+ flag = 1;
+ }
+ i++;
+ }
+ if (flag == 0) {
+ int slen = strlen(ptr);
+ _stp_snprintf(ptr + slen, len - slen, "0x%lx", val);
+ }
+}
+%}
+
+%{
+const _stp_val_array const _stp_signal_list[] = {
+ {0, "SIG_0"},
+ V(SIGHUP),
+ V(SIGINT),
+ V(SIGQUIT),
+ V(SIGILL),
+ V(SIGTRAP),
+ V(SIGABRT),
+ V(SIGBUS),
+ V(SIGFPE),
+ V(SIGKILL),
+ V(SIGUSR1),
+ V(SIGSEGV),
+ V(SIGPIPE),
+ V(SIGUSR2),
+ V(SIGALRM),
+ V(SIGTERM),
+ V(SIGCHLD),
+ V(SIGCONT),
+ V(SIGSTOP),
+ V(SIGTSTP),
+ V(SIGTTIN),
+ V(SIGTTOU),
+ V(SIGURG),
+ V(SIGPROF),
+ V(SIGWINCH),
+ V(SIGVTALRM),
+ {SIGIO,"SIGIO/SIGPOLL"},
+ V(SIGPWR),
+ {0, NULL}
+};
+%}
+
+function _signal_name:string(sig:long)
+%{ /* pure */
+ _stp_lookup_str(_stp_signal_list, THIS->sig, THIS->__retvalue, MAXSTRINGLEN);
+%}
+
+%{
+const _stp_val_array const _stp_semctl_list[] = {
+ V(IPC_INFO),
+ V(SEM_INFO),
+ V(SEM_STAT),
+ V(GETALL),
+ V(GETVAL),
+ V(GETPID),
+ V(GETNCNT),
+ V(GETZCNT),
+ V(IPC_STAT),
+ V(SETVAL),
+ V(SETALL),
+ V(IPC_RMID),
+ V(IPC_SET),
+ {0, NULL}
+};
+%}
+
+function _semctl_cmd:string(cmd:long)
+%{ /* pure */
+ _stp_lookup_str(_stp_semctl_list, THIS->cmd, THIS->__retvalue, MAXSTRINGLEN);
+%}
+
+%{
+const _stp_val_array const _stp_fork_list[] = {
+ V(CLONE_VM),
+ V(CLONE_FS),
+ V(CLONE_FILES),
+ V(CLONE_SIGHAND),
+ V(CLONE_PTRACE),
+ V(CLONE_VFORK),
+ V(CLONE_PARENT),
+ V(CLONE_THREAD),
+ V(CLONE_NEWNS),
+ V(CLONE_SYSVSEM),
+ V(CLONE_SETTLS),
+ V(CLONE_PARENT_SETTID),
+ V(CLONE_CHILD_CLEARTID),
+ V(CLONE_DETACHED),
+ V(CLONE_UNTRACED),
+ V(CLONE_CHILD_SETTID),
+ V(CLONE_STOPPED),
+ {0, NULL}
+};
+%}
+
+function __fork_flags:string(flags:long)
+%{ /* pure */
+ _stp_lookup_or_str(_stp_fork_list, THIS->flags, THIS->__retvalue, MAXSTRINGLEN);
+%}
+
+%{
+const _stp_val_array const _stp_atflag_list[] = {
+#ifdef AT_SYMLINK_NOFOLLOW
+ V(AT_SYMLINK_NOFOLLOW),
+#endif
+#ifdef AT_REMOVEDIR
+ V(AT_REMOVEDIR),
+#endif
+#ifdef AT_SYMLINK_FOLLOW
+ V(AT_SYMLINK_FOLLOW),
+#endif
+ {0, NULL}
+};
+%}
+
+function _at_flag_str:string(f:long)
+%{ /* pure */
+ _stp_lookup_str(_stp_atflag_list, THIS->f, THIS->__retvalue, MAXSTRINGLEN);
+%}
+
+
+%{
+#include <linux/shm.h>
+const _stp_val_array const _stp_shmat_list[] = {
+ V(SHM_RDONLY),
+ V(SHM_RND),
+ V(SHM_REMAP),
+ V(SHM_EXEC),
+ {0, NULL}
+};
+%}
+
+function _shmat_flags_str:string(f:long)
+%{ /* pure */
+ _stp_lookup_or_str(_stp_shmat_list, THIS->f, THIS->__retvalue, MAXSTRINGLEN);
+%}
+
+
+%{
+const _stp_val_array const _stp_mprotect_list[] = {
+ V(PROT_READ),
+ V(PROT_WRITE),
+ V(PROT_EXEC),
+ V(PROT_SEM),
+ {0, NULL}
+};
+%}
+
+function _mprotect_prot_str:string(prot:long)
+%{ /* pure */
+ if (THIS->prot)
+ _stp_lookup_or_str(_stp_mprotect_list, THIS->prot, THIS->__retvalue, MAXSTRINGLEN);
+ else
+ strlcpy (THIS->__retvalue, "PROT_NONE", MAXSTRINGLEN);
+%}
+
+%{
+const _stp_val_array const _stp_mmap_list[] = {
+ V(MAP_SHARED),
+ V(MAP_PRIVATE),
+ V(MAP_FIXED),
+ V(MAP_ANONYMOUS),
+ V(MAP_GROWSDOWN),
+ V(MAP_DENYWRITE),
+ V(MAP_EXECUTABLE),
+ V(MAP_LOCKED),
+ V(MAP_NORESERVE),
+ V(MAP_POPULATE),
+ V(MAP_NONBLOCK),
+ {0, NULL}
+};
+%}
+
+function _mmap_flags:string(flags:long)
+%{ /* pure */
+ _stp_lookup_or_str(_stp_mmap_list, THIS->flags, THIS->__retvalue, MAXSTRINGLEN);
+%}
+
+# old mmap functions passed in a struct like this.
+#
+function get_mmap_args:string (args:long)
+%{
+#if defined (__x86_64__) || defined (__ia64__)
+ struct mmap_arg_struct {
+ unsigned int addr;
+ unsigned int len;
+ unsigned int prot;
+ unsigned int flags;
+ int fd;
+ unsigned int offset;
+ } a;
+#else
+ struct mmap_arg_struct {
+ unsigned long addr;
+ unsigned long len;
+ unsigned long prot;
+ unsigned long flags;
+ long fd;
+ unsigned long offset;
+ } a;
+#endif
+
+ if(_stp_copy_from_user((char *)&a,(char *)(unsigned long)THIS->args, sizeof(a))== 0) {
+ int len;
+ _stp_snprintf(THIS->__retvalue, MAXSTRINGLEN, "0x%lx, %ld, ", (long)a.addr, (long)a.len);
+ if (a.prot)
+ _stp_lookup_or_str(_stp_mprotect_list, a.prot, THIS->__retvalue, MAXSTRINGLEN);
+ else
+ strlcat (THIS->__retvalue, "PROT_NONE", MAXSTRINGLEN);
+ strlcat (THIS->__retvalue, ", ", MAXSTRINGLEN);
+ _stp_lookup_or_str(_stp_mmap_list, a.flags, THIS->__retvalue, MAXSTRINGLEN);
+ strlcat (THIS->__retvalue, ", ", MAXSTRINGLEN);
+ len = strlen(THIS->__retvalue);
+ _stp_snprintf(THIS->__retvalue + len, MAXSTRINGLEN - len, "%ld, %ld", (long)a.fd, (long)a.offset);
+ } else
+ strlcpy (THIS->__retvalue, "UNKNOWN", MAXSTRINGLEN);
+%}