diff options
Diffstat (limited to 'tapset')
-rw-r--r-- | tapset/kretprobe.stp | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/tapset/kretprobe.stp b/tapset/kretprobe.stp new file mode 100644 index 00000000..3742708f --- /dev/null +++ b/tapset/kretprobe.stp @@ -0,0 +1,56 @@ +// kretprobe data tapset +// Copyright (C) 2009 Red Hat Inc. +// +// This file is part of systemtap, and is free software. You can +// redistribute it and/or modify it under the terms of the GNU General +// Public License (GPL); either version 2, or (at your option) any +// later version. + + +// This is an internally-used tapset for sharing data between kretprobe +// entry / return handlers. See the function +// dwarf_var_expanding_visitor::gen_kretprobe_saved_return +// for details. +// +// Note, invalid calls are silently ignored... + +%{ +static void * +_kretprobe_data(struct kretprobe_instance *pi, size_t offset, size_t length) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) + size_t end = offset + length; + if (end > offset && pi && end <= pi->rp->data_size) + return &pi->data[offset]; +#endif + return NULL; +} +%} + +function _get_kretprobe_long:long(i:long) %{ /* pure */ + size_t offset = THIS->i * sizeof(int64_t); + const int64_t *data = _kretprobe_data(CONTEXT->pi, offset, sizeof(int64_t)); + THIS->__retvalue = data ? *data : 0; +%} + +function _set_kretprobe_long(i:long, value:long) %{ /* impure */ + size_t offset = THIS->i * sizeof(int64_t); + int64_t *data = _kretprobe_data(CONTEXT->pi, offset, sizeof(int64_t)); + if (data) + *data = THIS->value; +%} + +function _get_kretprobe_string:string(i:long) %{ /* pure */ + size_t offset = CONTEXT->pi_longs * sizeof(int64_t) + + THIS->i * MAXSTRINGLEN; + const char *data = _kretprobe_data(CONTEXT->pi, offset, MAXSTRINGLEN); + strlcpy(THIS->__retvalue, data ?: "", MAXSTRINGLEN); +%} + +function _set_kretprobe_string(i:long, value:string) %{ /* impure */ + size_t offset = CONTEXT->pi_longs * sizeof(int64_t) + + THIS->i * MAXSTRINGLEN; + char *data = _kretprobe_data(CONTEXT->pi, offset, MAXSTRINGLEN); + if (data) + strlcpy(data, THIS->value, MAXSTRINGLEN); +%} |