diff options
Diffstat (limited to 'tapset')
-rw-r--r-- | tapset/ChangeLog | 21 | ||||
-rw-r--r-- | tapset/context.stp | 4 | ||||
-rw-r--r-- | tapset/i686/registers.stp | 69 | ||||
-rw-r--r-- | tapset/ioblock.stp | 2 | ||||
-rw-r--r-- | tapset/scsi.stp | 5 | ||||
-rw-r--r-- | tapset/tcp.stp | 65 | ||||
-rw-r--r-- | tapset/x86_64/registers.stp | 99 |
7 files changed, 215 insertions, 50 deletions
diff --git a/tapset/ChangeLog b/tapset/ChangeLog index dae8b452..70d75b83 100644 --- a/tapset/ChangeLog +++ b/tapset/ChangeLog @@ -1,3 +1,24 @@ +2008-05-08 Ananth N Mavinakayanahalli <ananth@in.ibm.com> + + PR 5231 + * ioblock.stp (ioblock.end): Set bytes_done depending on kernel + version. + +2008-04-29 Frank Ch. Eigler <fche@elastic.org> + + PR 6466 + * tcp.stp (tcp_sockstate_str, tcp_sockopt_str): Initialize + number->string lookup tables here, instead of "probe begin(-1)" + block that can be elided/warned. + +2008-04-16 Wenji Huang <wenji.huang@oracle.com> + + * scsi.stp (scsi.iodispatching): Correct for 2.6.25 kernel. + +2008-04-15 Martin Hunt <hunt@monkey> + + * context.stp (print_backtrace, backtrace): Use MAXTRACE. + 2008-03-21 Eugene Teo <eugeneteo@kernel.sg> PR 5528 diff --git a/tapset/context.stp b/tapset/context.stp index 4aa75158..dc560316 100644 --- a/tapset/context.stp +++ b/tapset/context.stp @@ -15,7 +15,7 @@ function print_regs () %{ function print_backtrace () %{ if (CONTEXT->regs) { - _stp_stack_print(CONTEXT->regs, 1, CONTEXT->pi); + _stp_stack_print(CONTEXT->regs, 1, CONTEXT->pi, MAXTRACE); } else { _stp_printf("Systemtap probe: %s\n", CONTEXT->probe_point); } @@ -23,7 +23,7 @@ function print_backtrace () %{ function backtrace:string () %{ /* pure */ if (CONTEXT->regs) - _stp_stack_snprint (THIS->__retvalue, MAXSTRINGLEN, CONTEXT->regs, 0, CONTEXT->pi); + _stp_stack_snprint (THIS->__retvalue, MAXSTRINGLEN, CONTEXT->regs, 0, CONTEXT->pi, MAXTRACE); else strlcpy (THIS->__retvalue, "", MAXSTRINGLEN); %} diff --git a/tapset/i686/registers.stp b/tapset/i686/registers.stp index 85aa7a7f..db532f7a 100644 --- a/tapset/i686/registers.stp +++ b/tapset/i686/registers.stp @@ -1,9 +1,70 @@ -/* Return the named register value as a signed value. */ -function register:long (name:string) %{ /* pure */ - THIS->__retvalue = (int64_t) - _stp_get_reg32_by_name(THIS->name, CONTEXT->regs); +global _reg_offsets, _stp_regs_registered + +function _stp_register_regs() { + /* Same order as pt_regs */ + _reg_offsets["ebx"] = 0 _reg_offsets["bx"] = 0 + _reg_offsets["ecx"] = 4 _reg_offsets["cx"] = 4 + _reg_offsets["edx"] = 8 _reg_offsets["dx"] = 8 + _reg_offsets["esi"] = 12 _reg_offsets["si"] = 12 + _reg_offsets["edi"] = 16 _reg_offsets["di"] = 16 + _reg_offsets["ebp"] = 20 _reg_offsets["bp"] = 20 + _reg_offsets["eax"] = 24 _reg_offsets["ax"] = 24 + _reg_offsets["xds"] = 28 _reg_offsets["ds"] = 28 + _reg_offsets["xes"] = 32 _reg_offsets["es"] = 32 + _reg_offsets["xfs"] = 36 _reg_offsets["fs"] = 36 + _reg_offsets["orig_eax"] = 40 _reg_offsets["orig_ax"] = 40 + _reg_offsets["eip"] = 44 _reg_offsets["ip"] = 44 + _reg_offsets["xcs"] = 48 _reg_offsets["cs"] = 48 + _reg_offsets["eflags"] = 52 _reg_offsets["flags"] = 52 + _reg_offsets["esp"] = 56 _reg_offsets["sp"] = 56 sp_offset = 56 + _reg_offsets["xss"] = 60 _reg_offsets["ss"] = 60 ss_offset = 60 + + _stp_regs_registered = 1 +} + +function _stp_get_register_by_offset:long (offset:long) %{ + long value; + memcpy(&value, ((char *)CONTEXT->regs) + THIS->offset, sizeof(value)); + THIS->__retvalue = value; +%} + +function _stp_probing_kernel:long () %{ + THIS->__retvalue = !user_mode(CONTEXT->regs); +%} + +/* + * esp and ss aren't saved on a breakpoint in kernel mode, so + * the pre-trap stack pointer is ®s->sp. + */ +function _stp_kernel_sp:long (sp_offset:long) %{ + THIS->__retvalue = ((long) CONTEXT->regs) + THIS->sp_offset; +%} + +/* Assume ss register hasn't changed since we took the trap. */ +function _stp_kernel_ss:long () %{ + unsigned short ss; + asm volatile("movw %%ss, %0" : : "m" (ss)); + THIS->__retvalue = ss; %} +/* Return the named register value as a signed value. */ +function register:long (name:string) { + if (!_stp_regs_registered) + _stp_register_regs() + offset = _reg_offsets[name] + if (offset == 0 && !(name in _reg_offsets)) { + error("Unknown register: " . name) + return 0 + } + if (_stp_probing_kernel()) { + if (offset == sp_offset) + return _stp_kernel_sp(sp_offset) + else if (offset == ss_offset) + return _stp_kernel_ss() + } + return _stp_get_register_by_offset(offset) +} + /* * Return the named register value as an unsigned value. Specifically, * don't sign-extend the register value when promoting it to 64 bits. diff --git a/tapset/ioblock.stp b/tapset/ioblock.stp index 94781c04..14ce3f6b 100644 --- a/tapset/ioblock.stp +++ b/tapset/ioblock.stp @@ -167,7 +167,7 @@ probe ioblock.end = kernel.function("bio_endio") devname = __bio_devname($bio) ino = __bio_ino($bio) - bytes_done = $bytes_done + bytes_done = %( kernel_vr < "2.6.24" %? $bytes_done %: $bio->bi_size %) error = $error sector = $bio->bi_sector diff --git a/tapset/scsi.stp b/tapset/scsi.stp index c9103cd6..7787b6d6 100644 --- a/tapset/scsi.stp +++ b/tapset/scsi.stp @@ -43,8 +43,13 @@ probe scsi.iodispatching dev_id = $cmd->device->id device_state = $cmd->device->sdev_state data_direction = $cmd->sc_data_direction +%( kernel_v >= "2.6.25" %? + request_buffer = $cmd->sdb->table->sgl + request_bufflen = $cmd->sdb->length +%: request_buffer = $cmd->request_buffer request_bufflen = $cmd->request_bufflen +%) req_addr = $cmd->request } diff --git a/tapset/tcp.stp b/tapset/tcp.stp index 3c3bd23b..7fa48000 100644 --- a/tapset/tcp.stp +++ b/tapset/tcp.stp @@ -71,7 +71,23 @@ function tcp_ts_get_info_state:long(sock:long) CATCH_DEREF_FAULT(); %} +global sockstate[13], sockstate_init_p function tcp_sockstate_str:string (state:long) { + if (! sockstate_init_p) { + sockstate_init_p = 1 + sockstate[1] = "TCP_ESTABLISHED" + sockstate[2] = "TCP_SYN_SENT" + sockstate[3] = "TCP_SYN_RECV" + sockstate[4] = "TCP_FIN_WAIT1" + sockstate[5] = "TCP_FIN_WAIT2" + sockstate[6] = "TCP_TIME_WAIT" + sockstate[7] = "TCP_CLOSE" + sockstate[8] = "TCP_CLOSE_WAIT" + sockstate[9] = "TCP_LAST_ACK" + sockstate[10] = "TCP_LISTEN" + sockstate[11] = "TCP_CLOSING" + sockstate[12] = "TCP_MAX_STATES" + } return (state in sockstate ? sockstate[state] : "UNDEF") } @@ -105,7 +121,25 @@ function tcp_ts_get_info_rcv_mss:long(sock:long) CATCH_DEREF_FAULT(); %} +global sockopt[15], sockopt_init_p function tcp_sockopt_str:string (optname:long) { + if (!sockopt_init_p) { + sockopt_init_p=1 + sockopt[1] = "TCP_NODELAY" + sockopt[2] = "TCP_MAXSEG" + sockopt[3] = "TCP_CORK" + sockopt[4] = "TCP_KEEPIDLE" + sockopt[5] = "TCP_KEEPINTVL" + sockopt[6] = "TCP_KEEPCNT" + sockopt[7] = "TCP_SYNCNT" + sockopt[8] = "TCP_LINGER2" + sockopt[9] = "TCP_DEFER_ACCEPT" + sockopt[10] = "TCP_WINDOW_CLAMP" + sockopt[11] = "TCP_INFO" + sockopt[12] = "TCP_QUICKACK" + sockopt[13] = "TCP_CONGESTION" + sockopt[14] = "TCP_MD5SIG" + } return (optname in sockopt ? sockopt[optname] : "UNDEF") } @@ -257,34 +291,3 @@ probe tcp.setsockopt.return = kernel.function("tcp_setsockopt").return { ret = $return } -global sockopt[15], sockstate[13] - -probe begin(-1) { - sockopt[1] = "TCP_NODELAY" - sockopt[2] = "TCP_MAXSEG" - sockopt[3] = "TCP_CORK" - sockopt[4] = "TCP_KEEPIDLE" - sockopt[5] = "TCP_KEEPINTVL" - sockopt[6] = "TCP_KEEPCNT" - sockopt[7] = "TCP_SYNCNT" - sockopt[8] = "TCP_LINGER2" - sockopt[9] = "TCP_DEFER_ACCEPT" - sockopt[10] = "TCP_WINDOW_CLAMP" - sockopt[11] = "TCP_INFO" - sockopt[12] = "TCP_QUICKACK" - sockopt[13] = "TCP_CONGESTION" - sockopt[14] = "TCP_MD5SIG" - - sockstate[1] = "TCP_ESTABLISHED" - sockstate[2] = "TCP_SYN_SENT" - sockstate[3] = "TCP_SYN_RECV" - sockstate[4] = "TCP_FIN_WAIT1" - sockstate[5] = "TCP_FIN_WAIT2" - sockstate[6] = "TCP_TIME_WAIT" - sockstate[7] = "TCP_CLOSE" - sockstate[8] = "TCP_CLOSE_WAIT" - sockstate[9] = "TCP_LAST_ACK" - sockstate[10] = "TCP_LISTEN" - sockstate[11] = "TCP_CLOSING" - sockstate[12] = "TCP_MAX_STATES" -} diff --git a/tapset/x86_64/registers.stp b/tapset/x86_64/registers.stp index 45acddd1..a5aba55a 100644 --- a/tapset/x86_64/registers.stp +++ b/tapset/x86_64/registers.stp @@ -1,18 +1,93 @@ -/* Return the named register value as a signed value. */ -function register:long (name:string) %{ /* pure */ - int reg32 = 0; - THIS->__retvalue = (int64_t) _stp_get_reg64_by_name(THIS->name, - CONTEXT->regs, ®32); - if (reg32) - THIS->__retvalue = _stp_sign_extend32(THIS->__retvalue); +global _reg_offsets, _r32_offsets, _stp_regs_registered + +function _stp_register_regs() { + /* Same order as pt_regs */ + _reg_offsets["r15"] = 0 + _reg_offsets["r14"] = 8 + _reg_offsets["r13"] = 16 + _reg_offsets["r12"] = 24 + _reg_offsets["rbp"] = 32 _reg_offsets["bp"] = 32 + _reg_offsets["rbx"] = 40 _reg_offsets["bx"] = 40 + _reg_offsets["r11"] = 48 + _reg_offsets["r10"] = 56 + _reg_offsets["r9"] = 64 + _reg_offsets["r8"] = 72 + _reg_offsets["rax"] = 80 _reg_offsets["ax"] = 80 + _reg_offsets["rcx"] = 88 _reg_offsets["cx"] = 88 + _reg_offsets["rdx"] = 96 _reg_offsets["dx"] = 96 + _reg_offsets["rsi"] = 104 _reg_offsets["si"] = 104 + _reg_offsets["rdi"] = 112 _reg_offsets["di"] = 112 + _reg_offsets["orig_rax"] = 120 _reg_offsets["orig_ax"] = 120 + _reg_offsets["rip"] = 128 _reg_offsets["ip"] = 128 + _reg_offsets["xcs"] = 136 _reg_offsets["cs"] = 136 + _reg_offsets["eflags"] = 144 _reg_offsets["flags"] = 144 + _reg_offsets["rsp"] = 152 _reg_offsets["sp"] = 152 + _reg_offsets["xss"] = 160 _reg_offsets["ss"] = 160 + + _r32_offsets["ebp"] = 32 + _r32_offsets["ebx"] = 40 + _r32_offsets["eax"] = 80 + _r32_offsets["ecx"] = 88 + _r32_offsets["edx"] = 96 + _r32_offsets["esi"] = 104 + _r32_offsets["edi"] = 112 + _r32_offsets["orig_eax"] = 120 + _r32_offsets["eip"] = 128 + _r32_offsets["esp"] = 152 + + _stp_regs_registered = 1 +} + +function _stp_get_register_by_offset:long (offset:long) %{ + long value; + memcpy(&value, ((char *)CONTEXT->regs) + THIS->offset, sizeof(value)); + THIS->__retvalue = value; %} -/* Return the named register value as an unsigned value. */ -function u_register:long (name:string) %{ - THIS->__retvalue = (int64_t) _stp_get_reg64_by_name(THIS->name, - CONTEXT->regs, NULL); +/* + * _stp_sign_extend32() is callable from a script function. + * __stp_sign_extend32() (in regs.c) is callable from a C function. + */ +function _stp_sign_extend32:long (value:long) %{ + THIS->__retvalue = __stp_sign_extend32(THIS->value); %} +function _stp_register:long (name:string, sign_extend:long) { + reg32 = 0 + if (!_stp_regs_registered) + _stp_register_regs() + offset = _reg_offsets[name] + if (offset == 0 && !(name in _reg_offsets)) { + offset = _r32_offsets[name] + if (offset == 0 && !(name in _r32_offsets)) { + error("Unknown register: " . name) + return 0 + } + reg32 = 1 + } + value = _stp_get_register_by_offset(offset) + if (reg32) { + if (sign_extend) + value = _stp_sign_extend32(value) + else + value &= 0xffffffff + } + return value +} + +/* Return the named register value as a signed value. */ +function register:long (name:string) { + return _stp_register(name, 1) +} + +/* + * Return the named register value as an unsigned value. Specifically, + * don't sign-extend the register value when promoting it to 64 bits. + */ +function u_register:long (name:string) { + return _stp_register(name, 0) +} + /* * Return the value of function arg #argnum (1=first arg). * If truncate=1, mask off the top 32 bits. @@ -68,7 +143,7 @@ function _stp_arg:long (argnum:long, sign_extend:long, truncate:long) %{ } if (THIS->truncate || argsz == sizeof(int)) { if (THIS->sign_extend) - THIS->__retvalue = (int64_t) _stp_sign_extend32(val); + THIS->__retvalue = (int64_t) __stp_sign_extend32(val); else /* High bits may be garbage. */ THIS->__retvalue = (int64_t) (val & 0xffffffff); |