summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreteo <eteo>2008-03-21 14:35:25 +0000
committereteo <eteo>2008-03-21 14:35:25 +0000
commitef56478712cf797380b3057ddeca13dcec064656 (patch)
treed650d8a70668873fec72cc874245336ee74a0a79
parent4a99c075363ddf2e745f28c847cce7e4aa6cc9f7 (diff)
downloadsystemtap-steved-ef56478712cf797380b3057ddeca13dcec064656.tar.gz
systemtap-steved-ef56478712cf797380b3057ddeca13dcec064656.tar.xz
systemtap-steved-ef56478712cf797380b3057ddeca13dcec064656.zip
2008-03-21 Eugene Teo <eugeneteo@kernel.sg>
PR 5528 * tapset/conversions.stp (user_string_n, user_string_n2, user_string_n_warn, user_string_n_quoted, user_short, user_short_warn, user_int, user_int_warn, user_long, user_long_warn, user_char, user_char_warn): New user_* functions. * stapfuncs.5.in: Documented the new functions. * testsuite/systemtap.stress/conversions.stp: Test new functions. * testsuite/buildok/conversions.stp: Test new functions. * testsuite/buildok/conversions-embedded.stp: Test new functions.
-rw-r--r--ChangeLog12
-rw-r--r--stapfuncs.5.in54
-rw-r--r--tapset/ChangeLog8
-rw-r--r--tapset/conversions.stp130
-rw-r--r--testsuite/ChangeLog7
-rwxr-xr-xtestsuite/buildok/conversions-embedded.stp13
-rwxr-xr-xtestsuite/buildok/conversions.stp13
-rw-r--r--testsuite/systemtap.stress/conversions.stp12
8 files changed, 248 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index c7bb82c3..628ab4e2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2008-03-21 Eugene Teo <eugeneteo@kernel.sg>
+
+ PR 5528
+ * tapset/conversions.stp (user_string_n, user_string_n2,
+ user_string_n_warn, user_string_n_quoted, user_short, user_short_warn,
+ user_int, user_int_warn, user_long, user_long_warn, user_char,
+ user_char_warn): New user_* functions.
+ * stapfuncs.5.in: Documented the new functions.
+ * testsuite/systemtap.stress/conversions.stp: Test new functions.
+ * testsuite/buildok/conversions.stp: Test new functions.
+ * testsuite/buildok/conversions-embedded.stp: Test new functions.
+
2008-03-20 Frank Ch. Eigler <fche@elastic.org>
PR 5975.
diff --git a/stapfuncs.5.in b/stapfuncs.5.in
index 85a00b37..9bca845d 100644
--- a/stapfuncs.5.in
+++ b/stapfuncs.5.in
@@ -92,6 +92,60 @@ fault, return instead the err_msg value.
user_string_warn:string (addr:long)
Copy a string from user space at given address. If the access would
fault, signal a warning and return "<unknown>".
+.TP
+user_string_quoted:string (addr:long)
+Copy a string from user space at given address. Any ASCII characters
+that are not printable are replaced by the corresponding escape
+sequence in the returned string.
+.TP
+user_string_n:string (addr:long, n:long)
+Copy a string of n bytes from user space at given address. If the access
+would fault, return "<unknown>".
+.TP
+user_string_n2:string (addr:long, n:long, err_msg:string)
+Copy a string of n bytes from user space at given address. If the access
+would fault, return the err_msg value.
+.TP
+user_string_n_warn:string (addr:long, n:long)
+Copy a string of n bytes from user space at given address. If the access
+would fault, signal a warning and return "<unknown>".
+.TP
+user_string_n_quoted:string (addr:long, n:long)
+Copy a string of n bytes from user space at given address. Any ASCII
+characters that are not printable are replaced by the corresponding escape
+sequence in the returned string. If the access would fault, return "<unknown>".
+.TP
+user_short:long (addr:long)
+Copy a short from user space at given address. If the access would fault,
+return 0.
+.TP
+user_short_warn:long (addr:long)
+Copy a short from user space at given address. If the access would fault,
+signal a warning and return 0.
+.TP
+user_int:long (addr:long)
+Copy an int from user space at given address. If the access would fault,
+return 0.
+.TP
+user_int_warn:long (addr:long)
+Copy an int from user space at given address. If the access would fault,
+signal a warning and return 0.
+.TP
+user_long:long (addr:long)
+Copy a long from user space at given address. If the access would fault,
+return 0.
+.TP
+user_long_warn:long (addr:long)
+Copy a long from user space at given address. If the access would fault,
+signal a warning and return 0.
+.TP
+user_char:long (addr:long)
+Copy a char from user space at given address. If the access would fault,
+return 0.
+.TP
+user_char_warn:long (addr:long)
+Copy a char from user space at given address. If the access would fault,
+signal a warning and return 0.
.SS STRING
.TP
strlen:long (str:string)
diff --git a/tapset/ChangeLog b/tapset/ChangeLog
index da21a5ff..dae8b452 100644
--- a/tapset/ChangeLog
+++ b/tapset/ChangeLog
@@ -1,3 +1,11 @@
+2008-03-21 Eugene Teo <eugeneteo@kernel.sg>
+
+ PR 5528
+ * conversions.stp (user_string_n, user_string_n2, user_string_n_warn,
+ user_string_n_quoted, user_short, user_short_warn, user_int,
+ user_int_warn, user_long, user_long_warn, user_char, user_char_warn):
+ New user_* functions.
+
2008-03-20 Frank Ch. Eigler <fche@elastic.org>
PR 5956.
diff --git a/tapset/conversions.stp b/tapset/conversions.stp
index af993992..70725e9d 100644
--- a/tapset/conversions.stp
+++ b/tapset/conversions.stp
@@ -1,5 +1,5 @@
// conversions tapset
-// Copyright (C) 2005-2007 Red Hat Inc.
+// Copyright (C) 2005-2008 Red Hat Inc.
// Copyright (C) 2007 Intel Corporation.
//
// This file is part of systemtap, and is free software. You can
@@ -108,3 +108,131 @@ function user_string_quoted:string (addr:long) %{ /* pure */
_stp_text_str(THIS->__retvalue, (char *)(uintptr_t)THIS->addr,
MAXSTRINGLEN, 1, 1);
%}
+
+function user_string_n:string (addr:long, n:long) {
+ return user_string_n2(addr, n, "<unknown>")
+}
+
+function user_string_n2:string (addr:long, n:long, err_msg:string) %{ /* pure */
+ long len = THIS->n + 1;
+ len = (len > MAXSTRINGLEN) ? MAXSTRINGLEN : len;
+ if (_stp_strncpy_from_user(THIS->__retvalue,
+ (char __user *) (uintptr_t) THIS->addr,
+ len) < 0)
+ strlcpy(THIS->__retvalue, THIS->err_msg, MAXSTRINGLEN);
+%}
+
+function user_string_n_warn:string (addr:long, n:long) %{ /* pure */
+ long len = THIS->n + 1;
+ long rc;
+
+ len = (len > MAXSTRINGLEN) ? MAXSTRINGLEN : len;
+ rc = _stp_strncpy_from_user(THIS->__retvalue,
+ (char __user *) (uintptr_t) THIS->addr, len);
+ if (rc < 0) {
+ // NB: using error_buffer to get local space for the warning, but we're
+ // not aborting, so leave last_error alone.
+ snprintf (CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
+ "user string copy fault %ld at %p", rc,
+ (void *) (uintptr_t) THIS->addr);
+ _stp_warn(CONTEXT->error_buffer);
+ strlcpy (THIS->__retvalue, "<unknown>", MAXSTRINGLEN);
+ }
+%}
+
+function user_string_n_quoted:string (addr:long, n:long) %{ /* pure */
+ long len = THIS->n + 1;
+ if (THIS->addr == 0)
+ strlcpy(THIS->__retvalue, "NULL", MAXSTRINGLEN);
+ else
+ /* XXX: stp_text_str uses sleepy __get_user() => unsafe ?! */
+ _stp_text_str(THIS->__retvalue, (char *)(uintptr_t)THIS->addr,
+ len, 1, 1);
+%}
+
+// When userspace data is not accessible, the following functions return 0
+
+function user_short:long (addr:long) %{ /* pure */
+ if (!access_ok(VERIFY_READ, (short *) (intptr_t) THIS->addr, sizeof(short)))
+ goto fault;
+ if (__stp_get_user(THIS->__retvalue, (short *) (intptr_t) THIS->addr)) {
+fault:
+ THIS->__retvalue = 0;
+ }
+%}
+
+function user_short_warn:long (addr:long) %{ /* pure */
+ if (!access_ok(VERIFY_READ, (short *) (intptr_t) THIS->addr, sizeof(short)))
+ goto fault;
+ if (__stp_get_user(THIS->__retvalue, (short *) (intptr_t) THIS->addr)) {
+fault:
+ snprintf (CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
+ "user short copy fault %p", (void *) (uintptr_t) THIS->addr);
+ _stp_warn(CONTEXT->error_buffer);
+ THIS->__retvalue = 0;
+ }
+%}
+
+function user_int:long (addr:long) %{ /* pure */
+ if (!access_ok(VERIFY_READ, (int *) (intptr_t) THIS->addr, sizeof(int)))
+ goto fault;
+ if (__stp_get_user(THIS->__retvalue, (int *) (intptr_t) THIS->addr)) {
+fault:
+ THIS->__retvalue = 0;
+ }
+%}
+
+function user_int_warn:long (addr:long) %{ /* pure */
+ if (!access_ok(VERIFY_READ, (int *) (intptr_t) THIS->addr, sizeof(int)))
+ goto fault;
+ if (__stp_get_user(THIS->__retvalue, (int *) (intptr_t) THIS->addr)) {
+fault:
+ snprintf (CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
+ "user int copy fault %p", (void *) (uintptr_t) THIS->addr);
+ _stp_warn(CONTEXT->error_buffer);
+ THIS->__retvalue = 0;
+ }
+%}
+
+function user_long:long (addr:long) %{ /* pure */
+ if (!access_ok(VERIFY_READ, (long *) (intptr_t) THIS->addr, sizeof(long)))
+ goto fault;
+ if (__stp_get_user(THIS->__retvalue, (long *) (intptr_t) THIS->addr)) {
+fault:
+ THIS->__retvalue = 0;
+ }
+%}
+
+function user_long_warn:long (addr:long) %{ /* pure */
+ if (!access_ok(VERIFY_READ, (long *) (intptr_t) THIS->addr, sizeof(long)))
+ goto fault;
+ if (__stp_get_user(THIS->__retvalue, (long *) (intptr_t) THIS->addr)) {
+fault:
+ snprintf (CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
+ "user long copy fault %p", (void *) (uintptr_t) THIS->addr);
+ _stp_warn(CONTEXT->error_buffer);
+ THIS->__retvalue = 0;
+ }
+%}
+
+function user_char:long (addr:long) %{ /* pure */
+ if (!access_ok(VERIFY_READ, (char *) (intptr_t) THIS->addr, sizeof(char)))
+ goto fault;
+ if (__stp_get_user(THIS->__retvalue, (char *) (intptr_t) THIS->addr)) {
+fault:
+ THIS->__retvalue = 0;
+ }
+%}
+
+function user_char_warn:long (addr:long) %{ /* pure */
+ if (!access_ok(VERIFY_READ, (char *) (intptr_t) THIS->addr, sizeof(char)))
+ goto fault;
+ if (__stp_get_user(THIS->__retvalue, (char *) (intptr_t) THIS->addr)) {
+fault:
+ snprintf (CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
+ "user char copy fault %p", (void *) (uintptr_t) THIS->addr);
+ _stp_warn(CONTEXT->error_buffer);
+ THIS->__retvalue = 0;
+ }
+%}
+
diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog
index 16f7af57..14f96ecc 100644
--- a/testsuite/ChangeLog
+++ b/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2008-03-21 Eugene Teo <eugeneteo@kernel.sg>
+
+ PR 5528
+ * systemtap.stress/conversions.stp: Test new user_* functions.
+ * buildok/conversions.stp: Test new user_* functions.
+ * buildok/conversions-embedded.stp: Test new user_* functions.
+
2008-03-20 Frank Ch. Eigler <fche@elastic.org>
PR 5956.
diff --git a/testsuite/buildok/conversions-embedded.stp b/testsuite/buildok/conversions-embedded.stp
index 7aa5a0b4..55f6cdb7 100755
--- a/testsuite/buildok/conversions-embedded.stp
+++ b/testsuite/buildok/conversions-embedded.stp
@@ -9,5 +9,18 @@ probe begin {
print (user_string2 (0, ""))
print (user_string_warn (0))
print (user_string_quoted (0))
+
+ print (user_string_n(0, 5))
+ print (user_string_n2(0, 5, "foobar"))
+ print (user_string_n_warn(0, 0))
+ print (user_string_n_quoted(0, 0))
+ print (user_short(0))
+ print (user_short_warn(0))
+ print (user_int(0))
+ print (user_int_warn(0))
+ print (user_long(0))
+ print (user_long_warn(0))
+ print (user_char(0))
+ print (user_char_warn(0))
}
diff --git a/testsuite/buildok/conversions.stp b/testsuite/buildok/conversions.stp
index e83bd968..5f151f1d 100755
--- a/testsuite/buildok/conversions.stp
+++ b/testsuite/buildok/conversions.stp
@@ -12,4 +12,17 @@ probe begin {
print (user_string(2342))
print (user_string2(2342,"foobar"))
print (user_string_warn(2342))
+
+ print (user_string_n(2342, 5))
+ print (user_string_n2(2342, 5, "foobar"))
+ print (user_string_n_warn(2342, 5))
+ print (user_string_n_quoted(2342, 5))
+ print (user_short(2342))
+ print (user_short_warn(2342))
+ print (user_int(2342))
+ print (user_int_warn(2342))
+ print (user_long(2342))
+ print (user_long_warn(2342))
+ print (user_char(2342))
+ print (user_char_warn(2342))
}
diff --git a/testsuite/systemtap.stress/conversions.stp b/testsuite/systemtap.stress/conversions.stp
index 07795a6d..34bd0c28 100644
--- a/testsuite/systemtap.stress/conversions.stp
+++ b/testsuite/systemtap.stress/conversions.stp
@@ -13,4 +13,16 @@ probe begin { print (user_string ($1)) }
probe begin { print (user_string2 ($1,"<only suspected, not known>")) }
probe begin { print (user_string_warn ($1)) }
probe begin { print (user_string_quoted ($1)) }
+probe begin { print (user_string_n ($1, 5)) }
+probe begin { print (user_string_n2 ($1, 5, "<only suspected, not known>")) }
+probe begin { print (user_string_n_warn ($1, 5)) }
+probe begin { print (user_string_n_quoted ($1, 5)) }
+probe begin { print (user_short ($1)) }
+probe begin { print (user_short_warn ($1)) }
+probe begin { print (user_int ($1)) }
+probe begin { print (user_int_warn ($1)) }
+probe begin { print (user_long ($1)) }
+probe begin { print (user_long_warn ($1)) }
+probe begin { print (user_char ($1)) }
+probe begin { print (user_char_warn ($1)) }
probe begin(1) { print ("\n") exit () }