diff options
author | Mark Wielaard <mwielaard@redhat.com> | 2008-10-07 12:12:57 +0200 |
---|---|---|
committer | Mark Wielaard <mwielaard@redhat.com> | 2008-10-07 12:12:57 +0200 |
commit | 53ed08414957de1e90c8332f7d5a71a384de039e (patch) | |
tree | 2130c2ada907a439fc6a5cd2dc9a52de71676b49 | |
parent | 11b554d5bbf00a810df8eff6718630ee5ad0c3b1 (diff) | |
download | systemtap-steved-53ed08414957de1e90c8332f7d5a71a384de039e.tar.gz systemtap-steved-53ed08414957de1e90c8332f7d5a71a384de039e.tar.xz systemtap-steved-53ed08414957de1e90c8332f7d5a71a384de039e.zip |
Transform struct sigaction32 to struct sigaction for rt_sigaction32 syscall.
-rw-r--r-- | tapset/ChangeLog | 7 | ||||
-rw-r--r-- | tapset/aux_syscalls.stp | 138 | ||||
-rw-r--r-- | tapset/syscalls2.stp | 3 |
3 files changed, 107 insertions, 41 deletions
diff --git a/tapset/ChangeLog b/tapset/ChangeLog index b3f09767..d4a69462 100644 --- a/tapset/ChangeLog +++ b/tapset/ChangeLog @@ -1,3 +1,10 @@ +2008-10-07 Mark Wielaard <mjw@redhat.com> + + * aux_syscalls.stp (_stp_sigaction_str): New embedded C function. + (_struct_sigaction_u): Call _stp_sigaction_str. + (_struct_sigaction32_u): New function. + * syscalls2.stp (syscall.rt_sigaction32): Call _struct_sigaction32_u. + 2008-09-23 Zhaolei <zhaolei@cn.fujitsu.com> * socket.stp (socket.aio_read/write): Fix version-checking method. diff --git a/tapset/aux_syscalls.stp b/tapset/aux_syscalls.stp index a748a132..603d2158 100644 --- a/tapset/aux_syscalls.stp +++ b/tapset/aux_syscalls.stp @@ -1729,48 +1729,106 @@ function _sighandler_str:string(uaddr:long) _stp_lookup_str(_stp_sa_handler_list, (long)THIS->uaddr, THIS->__retvalue, MAXSTRINGLEN); %} -function _struct_sigaction_u:string(uaddr:long) -%{ /* pure */ - static const _stp_val_array const _stp_sa_handler_list[] = { - {0, "SIG_DFL"}, - {1, "SIG_IGN"}, - {0, NULL} - }; - static const _stp_val_array const _stp_sa_flags_list[] = { - V(SA_NOCLDSTOP), - V(SA_NOCLDWAIT), - V(SA_RESETHAND), - V(SA_ONSTACK), - V(SA_RESTART), - V(SA_NODEFER), - V(SA_SIGINFO), - V(SA_RESTORER), - {0, NULL} - }; - - struct sigaction act; - char *ptr = (char *)(unsigned long)THIS->uaddr; - - if (ptr == NULL) - strlcpy (THIS->__retvalue, "NULL", MAXSTRINGLEN); - else { - if(_stp_copy_from_user((char*)&act,ptr,sizeof(struct sigaction)) == 0) { - int len; - _stp_lookup_str(_stp_sa_handler_list, (long)act.sa_handler, THIS->__retvalue, MAXSTRINGLEN); - if (act.sa_handler != SIG_IGN && act.sa_handler != SIG_DFL) { - strlcat (THIS->__retvalue, ", ", MAXSTRINGLEN); - _stp_lookup_or_str(_stp_sa_flags_list, act.sa_flags, THIS->__retvalue, MAXSTRINGLEN); - strlcat (THIS->__retvalue, ", ", MAXSTRINGLEN); +%{ +void _stp_sigaction_str(struct sigaction *act, char *ptr, int len) +{ + static const _stp_val_array const _stp_sa_handler_list[] = { + {0, "SIG_DFL"}, + {1, "SIG_IGN"}, + {0, NULL} + }; + + static const _stp_val_array const _stp_sa_flags_list[] = { + V(SA_NOCLDSTOP), + V(SA_NOCLDWAIT), + V(SA_RESETHAND), + V(SA_ONSTACK), + V(SA_RESTART), + V(SA_NODEFER), + V(SA_SIGINFO), + V(SA_RESTORER), + {0, NULL} + }; + + int slen; + _stp_lookup_str(_stp_sa_handler_list, (long)act->sa_handler, + ptr, len); + if (act->sa_handler != SIG_IGN && act->sa_handler != SIG_DFL) + { + strlcat (ptr, ", ", len); + _stp_lookup_or_str(_stp_sa_flags_list, act->sa_flags, ptr, len); + strlcat (ptr, ", ", len); #if !defined (__ia64__) - len = strlen(THIS->__retvalue); - _stp_snprintf(THIS->__retvalue + len, MAXSTRINGLEN - len, "0x%lx, [", (long)act.sa_restorer); + slen = strlen(ptr); + _stp_snprintf(ptr + slen, len - slen, + "0x%lx, [", (long)act->sa_restorer); #else - strlcat (THIS->__retvalue, "[", MAXSTRINGLEN); + strlcat (ptr, "[", len); #endif - _stp_sigset_str(&act.sa_mask, THIS->__retvalue, MAXSTRINGLEN); - strlcat (THIS->__retvalue, "]", MAXSTRINGLEN); - } - } else - strlcpy (THIS->__retvalue, "UNKNOWN", MAXSTRINGLEN); + _stp_sigset_str(&act->sa_mask, ptr, len); + strlcat (ptr, "]", len); + } +} +%} + +function _struct_sigaction_u:string(uaddr:long) +%{ /* pure */ + struct sigaction act; + char *ptr = (char *)(unsigned long)THIS->uaddr; + + if (ptr == NULL) + strlcpy (THIS->__retvalue, "NULL", MAXSTRINGLEN); + else + { + if(_stp_copy_from_user((char*)&act, ptr, + sizeof(struct sigaction)) == 0) + _stp_sigaction_str(&act, THIS->__retvalue, MAXSTRINGLEN); + else + strlcpy (THIS->__retvalue, "UNKNOWN", MAXSTRINGLEN); + } +%} + +function _struct_sigaction32_u:string(uaddr:long) +%{ /* pure */ +#include <linux/compat.h> + + // There seems to be no public cross arch header that defines this. + struct sigaction32 { + compat_uptr_t sa_handler; + unsigned int sa_flags; + unsigned int sa_restorer; /* Another 32 bit pointer */ + compat_sigset_t sa_mask; /* A 32 bit mask */ + }; + + struct sigaction32 act32; + char *ptr = (char *)(unsigned long)THIS->uaddr; + + if (ptr == NULL) + strlcpy (THIS->__retvalue, "NULL", MAXSTRINGLEN); + else + { + if(_stp_copy_from_user((char*)&act32, ptr, + sizeof(struct sigaction32)) == 0) + { + struct sigaction act; + act.sa_handler = (void *)compat_ptr(act32.sa_handler); + act.sa_flags = (unsigned long)act32.sa_flags; + act.sa_restorer = (void *)compat_ptr(act32.sa_restorer); + /* swap words around to get right endian order. */ + switch (_NSIG_WORDS) + { + case 4: act.sa_mask.sig[3] = act32.sa_mask.sig[6] + | (((long)act32.sa_mask.sig[7]) << 32); + case 3: act.sa_mask.sig[2] = act32.sa_mask.sig[4] + | (((long)act32.sa_mask.sig[5]) << 32); + case 2: act.sa_mask.sig[1] = act32.sa_mask.sig[2] + | (((long)act32.sa_mask.sig[3]) << 32); + case 1: act.sa_mask.sig[0] = act32.sa_mask.sig[0] + | (((long)act32.sa_mask.sig[1]) << 32); + } + _stp_sigaction_str(&act, THIS->__retvalue, MAXSTRINGLEN); } + else + strlcpy (THIS->__retvalue, "UNKNOWN", MAXSTRINGLEN); + } %} diff --git a/tapset/syscalls2.stp b/tapset/syscalls2.stp index 28691a66..174f6373 100644 --- a/tapset/syscalls2.stp +++ b/tapset/syscalls2.stp @@ -958,7 +958,8 @@ probe syscall.rt_sigaction32 = kernel.function("sys32_rt_sigaction") ?, act_uaddr = $act oact_uaddr = $oact sigsetsize = $sigsetsize - argstr = sprintf("%s, %p, %p, %d", _signal_name($sig), $act, $oact, $sigsetsize) + argstr = sprintf("%s, {%s}, %p, %d", _signal_name($sig), + _struct_sigaction32_u($act), $oact, $sigsetsize) } probe syscall.rt_sigaction32.return = kernel.function("sys32_rt_sigaction").return ?, kernel.function("compat_sys_rt_sigaction").return ? |