summaryrefslogtreecommitdiffstats
path: root/tapset/conversions.stp
diff options
context:
space:
mode:
authorfche <fche>2007-02-06 20:23:25 +0000
committerfche <fche>2007-02-06 20:23:25 +0000
commitf902d9596b3f7ee135d180ec0bae01c05d9a97bd (patch)
tree360649626b889dbeb0d1ed861e2b6631fe9ba1ab /tapset/conversions.stp
parent34f6a71cdaa6cf4835819ca5b92a152e2cd5bde0 (diff)
downloadsystemtap-steved-f902d9596b3f7ee135d180ec0bae01c05d9a97bd.tar.gz
systemtap-steved-f902d9596b3f7ee135d180ec0bae01c05d9a97bd.tar.xz
systemtap-steved-f902d9596b3f7ee135d180ec0bae01c05d9a97bd.zip
* kernel_{string,long,...,char} protected accessor functions
* test suites for all of 'em too * even documentation * mm, donuts 2007-02-06 Frank Ch. Eigler <fche@elastic.org> * stapfuncs.5.in: Add docs for kernel_{long,int,short,char} and some user_string* variants. 2007-02-06 Frank Ch. Eigler <fche@elastic.org> * conversions.stp (kernel_long/int/short/char): New functions. 2007-02-06 Frank Ch. Eigler <fche@elastic.org> * buildok/conversions.stp: Build-test all conversions.stp functions. * systemtap.stress/conversions.*: New test.
Diffstat (limited to 'tapset/conversions.stp')
-rw-r--r--tapset/conversions.stp61
1 files changed, 58 insertions, 3 deletions
diff --git a/tapset/conversions.stp b/tapset/conversions.stp
index c311d25a..fe5adc10 100644
--- a/tapset/conversions.stp
+++ b/tapset/conversions.stp
@@ -1,5 +1,5 @@
// conversions tapset
-// Copyright (C) 2005, 2006 Red Hat Inc.
+// Copyright (C) 2005-2007 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
@@ -12,7 +12,8 @@ function kernel_string:string (addr:long) %{ /* pure */
goto success;
deref_fault: /* branched to from deref() */
{
- static char errmsg[40];
+ /* XXX: concurrent errors could result in corrupted message string */
+ static char errmsg[50];
snprintf (errmsg, 40, "kernel string copy fault at 0x%p",
(void *) (uintptr_t) THIS->addr);
CONTEXT->last_error = errmsg;
@@ -20,6 +21,59 @@ deref_fault: /* branched to from deref() */
success: ;
%}
+function kernel_long:long (addr:long) %{ /* pure */
+ THIS->__retvalue = (int64_t) deref (sizeof (long), (long *) (intptr_t) THIS->addr);
+ goto success;
+deref_fault: /* branched to from deref() */
+ {
+ static char errmsg[50];
+ snprintf (errmsg, 40, "kernel long copy fault at 0x%p",
+ (void *) (uintptr_t) THIS->addr);
+ CONTEXT->last_error = errmsg;
+ }
+success: ;
+%}
+
+function kernel_int:long (addr:long) %{ /* pure */
+ THIS->__retvalue = (int64_t) deref (sizeof (int), (int *) (intptr_t) THIS->addr);
+deref_fault: /* branched to from deref() */
+ {
+ static char errmsg[50];
+ snprintf (errmsg, 40, "kernel int copy fault at 0x%p",
+ (void *) (uintptr_t) THIS->addr);
+ CONTEXT->last_error = errmsg;
+ }
+success: ;
+%}
+
+function kernel_short:long (addr:long) %{ /* pure */
+ THIS->__retvalue = (int64_t) deref (sizeof (short), (short *) (intptr_t) THIS->addr);
+ goto success;
+deref_fault: /* branched to from deref() */
+ {
+ static char errmsg[50];
+ snprintf (errmsg, 40, "kernel short copy fault at 0x%p",
+ (void *) (uintptr_t) THIS->addr);
+ CONTEXT->last_error = errmsg;
+ }
+success: ;
+%}
+
+function kernel_char:long (addr:long) %{ /* pure */
+ THIS->__retvalue = (int64_t) deref (sizeof (char), (char *) (intptr_t) THIS->addr);
+ goto success;
+deref_fault: /* branched to from deref() */
+ {
+ static char errmsg[50];
+ snprintf (errmsg, 40, "kernel char copy fault at 0x%p",
+ (void *) (uintptr_t) THIS->addr);
+ CONTEXT->last_error = errmsg;
+ }
+success: ;
+%}
+
+
+
// On rare cases when userspace data is not accessible,
// this function returns "<unknown>"
@@ -42,7 +96,7 @@ function user_string_warn:string (addr:long) %{ /* pure */
long rc = _stp_strncpy_from_user (THIS->__retvalue,
(const char __user*) (uintptr_t) THIS->addr, MAXSTRINGLEN);
if (rc < 0) {
- static char errmsg[40];
+ static char errmsg[60];
snprintf (errmsg, 40, "user string copy fault %ld at %p", rc,
(void *) (uintptr_t) THIS->addr);
_stp_warn(errmsg);
@@ -54,5 +108,6 @@ function user_string_quoted:string (addr:long) %{ /* pure */
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, MAXSTRINGLEN, 1, 1);
%}