/usr/share/systemtap/tapset/linux/utrace.stp is in systemtap-common 2.3-1ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | /* utrace-only subset of register accessors */
%{
#include "syscall.h"
%}
function _utrace_syscall_nr:long () %{ /* pure */ /* myproc-unprivileged */
if (! CONTEXT->uregs || ! CONTEXT->user_mode_p) {
CONTEXT->last_error = "invalid call without context registers";
} else {
STAP_RETVALUE = syscall_get_nr(current, CONTEXT->uregs);
}
%}
function _utrace_syscall_arg:long (n:long) %{ /* pure */ /* myproc-unprivileged */
unsigned long arg = 0;
if (! CONTEXT->uregs || ! CONTEXT->user_mode_p) {
CONTEXT->last_error = "invalid call without context registers";
} else {
syscall_get_arguments(current, CONTEXT->uregs, (int)STAP_ARG_n, 1, &arg);
}
STAP_RETVALUE = arg;
%}
function _utrace_syscall_return:long () %{ /* pure */ /* myproc-unprivileged */
/*
* Here's the reason for the "unsigned long" cast. Since all
* values inside systemtap are 64-bit numbers, return values were
* getting sign extended. This caused return values to not match
* up with the same values passes as arguments.
*/
if (! CONTEXT->uregs || ! CONTEXT->user_mode_p) {
CONTEXT->last_error = "invalid call without context registers";
} else {
STAP_RETVALUE = (unsigned long)syscall_get_return_value(current,
CONTEXT->uregs);
}
%}
|