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 /tapset/aux_syscalls.stp | |
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.
Diffstat (limited to 'tapset/aux_syscalls.stp')
-rw-r--r-- | tapset/aux_syscalls.stp | 138 |
1 files changed, 98 insertions, 40 deletions
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); + } %} |