]> sourceware.org Git - systemtap.git/commitdiff
PR12138: Convert the user_int functions to kread
authorJosh Stone <jistone@redhat.com>
Wed, 24 Nov 2010 00:13:55 +0000 (16:13 -0800)
committerJosh Stone <jistone@redhat.com>
Wed, 24 Nov 2010 00:13:55 +0000 (16:13 -0800)
This uses our more-centralized mechanism for reading uncertain memory,
which also has the ability to read 8-byte values on i386 (not atomically).

* tapset/uconversions.stp: New, move the user_* functions here.  The new
  STP_GET_USER[_WARN] standardize all integer accesses through kread.
* tapset/conversions.stp: This is only for kernel functions now.
* doc/SystemTap_Tapset_Reference/tapsets.tmpl: Include uconversions.
* testsuite/buildok/conversions.stp: Build the user_intNN too.
* testsuite/buildok/conversions-embedded.stp: Ditto.

doc/SystemTap_Tapset_Reference/tapsets.tmpl
tapset/conversions.stp
tapset/uconversions.stp [new file with mode: 0644]
testsuite/buildok/conversions-embedded.stp
testsuite/buildok/conversions.stp

index 0dd95e6bfeb4348f960f62998660e01c63676dc8..974b29e548972d3f5aecea5733d101bb2f4667d3 100644 (file)
       strings are of a maximum length given by MAXSTRINGLEN.
     </para>
 !Itapset/conversions.stp
+!Itapset/uconversions.stp
     </chapter>
   <chapter id="string.stp">
     <title>A collection of standard string functions</title>
index 11d9b73de834cc14a6a2b736e3f6812846c9147d..13553d6138367c90fba1079a8d3f1024bcc3555e 100644 (file)
@@ -7,17 +7,6 @@
 // Public License (GPL); either version 2, or (at your option) any
 // later version.
 
-%{
-#define STP_GET_USER(t)                                                        \
-       assert_is_myproc();                                             \
-       if (!access_ok(VERIFY_READ, (t *) (intptr_t) THIS->addr, sizeof(t))) \
-               goto fault;                                             \
-       if (__stp_get_user(THIS->__retvalue, (t *) (intptr_t) THIS->addr)) { \
-fault:                                                                 \
-               THIS->__retvalue = 0;                                   \
-       }
-%}
-
 /**
  * sfunction kernel_string - Retrieves string from kernel memory.
  *
@@ -176,468 +165,3 @@ deref_fault: /* branched to from kread() */
     CONTEXT->last_error = CONTEXT->error_buffer;
   }
 %}
-
-/**
- * sfunction user_string - Retrieves string from user space.
- *
- * General Syntax: user_string:string(addr:long)
- *
- * @addr: The user space address to retrieve the string from.
- *
- * Description: Returns the null terminated C string from a given user space
- * memory address. Reports "<unknown>" on the rare cases when userspace
- * data is not accessible.
- */
-function user_string:string (addr:long) { return user_string2 (addr, "<unknown>") }
-
-/**
- * sfunction user_string2 - Retrieves string from user space with alternative error string.
- *
- * General Syntax: user_string2:string(addr:long, err_msg:string)
- *
- * @addr: The user space address to retrieve the string from.
- * @err_msg: The error message to return when data isn't available.
- *
- * Description: Returns the null terminated C string from a given user space
- * memory address. Reports the given error message on the rare cases when
- * userspace data is not accessible.
- */
-function user_string2:string (addr:long, err_msg:string) %{ /* pure */ /* unprivileged */
-  assert_is_myproc();
-  if (_stp_strncpy_from_user (THIS->__retvalue, 
-        (const char __user*) (uintptr_t) THIS->addr,
-        MAXSTRINGLEN) < 0)
-    strlcpy (THIS->__retvalue, THIS->err_msg, MAXSTRINGLEN);
-%}
-
-/**
- * sfunction user_string_warn - Retrieves string from user space.
- * 
- * General Syntax: user_string_warn:string(addr:long)
- *
- * @addr: The user space address to retrieve the string from.
- *
- * Description: Returns the null terminated C string from a given user space
- * memory address. Reports "<unknown>" on the rare cases when userspace
- * data is not accessible and warns (but does not abort) about the failure.
- */
-function user_string_warn:string (addr:long) %{ /* pure */ /* unprivileged */
-  long rc;
-  assert_is_myproc();
-  rc = _stp_strncpy_from_user (THIS->__retvalue,
-      (const char __user*) (uintptr_t) THIS->addr, MAXSTRINGLEN);
-  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);
-  }
-%}
-
-/**
- * sfunction user_string_quoted - Retrieves and quotes string from user space.
- * 
- * General Syntax: user_string_quoted:string(addr:long)
- *
- * @addr: The user space address to retrieve the string from.
- *
- * Description: Returns the null terminated C string from a given user space
- * memory address where any ASCII characters that are not printable are
- * replaced by the corresponding escape sequence in the returned string.
- * Reports "NULL" for address zero. Returns "<unknown>" on the rare
- * cases when userspace data is not accessible at the given address.
- */
-function user_string_quoted:string (addr:long) %{ /* pure */ /* unprivileged */
-  assert_is_myproc();
-  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);
-%}
-
-/**
- * sfunction user_string_n - Retrieves string of given length from user space.
- * 
- * General Syntax: user_string_n:string(addr:long, n:long)
- *
- * @addr: The user space address to retrieve the string from.
- * @n: The maximum length of the string (if not null terminated).
- *
- * Description: Returns the C string of a maximum given length from a
- * given user space address. Returns "<unknown>" on the rare cases
- * when userspace data is not accessible at the given address.
- */
-function user_string_n:string (addr:long, n:long) {
-       return user_string_n2(addr, n, "<unknown>")
-}
-       
-/**
- * sfunction user_string_n2 - Retrieves string of given length from user space.
- * 
- * General Syntax: user_string_n2:string(addr:long, n:long, err_msg:string)
- *
- * @addr: The user space address to retrieve the string from.
- * @n: The maximum length of the string (if not null terminated).
- * @err_msg: The error message to return when data isn't available.
- *
- * Description: Returns the C string of a maximum given length from a
- * given user space address. Returns the given error message string on
- * the rare cases when userspace data is not accessible at the given
- * address.
- */
-function user_string_n2:string (addr:long, n:long, err_msg:string) %{ /* pure */ /* unprivileged */
-       int64_t len = clamp_t(int64_t, THIS->n + 1, 1, MAXSTRINGLEN);
-        assert_is_myproc();
-       if (_stp_strncpy_from_user(THIS->__retvalue,
-                               (char __user *) (uintptr_t) THIS->addr,
-                               len) < 0)
-               strlcpy(THIS->__retvalue, THIS->err_msg, MAXSTRINGLEN);
-       else
-               THIS->__retvalue[len - 1] = '\0';
-%}
-
-/**
- * sfunction user_string_n_warn - Retrieves string from user space.
- *
- * General Syntax: user_string_n_warn:string(addr:long, n:long)
- *
- * @addr: The user space address to retrieve the string from.
- * @n: The maximum length of the string (if not null terminated).
- *
- * Description: Returns up to n characters of a C string from a given
- * user space memory address. Reports "<unknown>" on the rare cases
- * when userspace data is not accessible and warns (but does not abort)
- * about the failure.
- */
-function user_string_n_warn:string (addr:long, n:long) %{ /* pure */ /* unprivileged */
-       int64_t len = clamp_t(int64_t, THIS->n + 1, 1, MAXSTRINGLEN);
-       long rc;
-
-        assert_is_myproc();
-       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);
-       } else
-               THIS->__retvalue[len - 1] = '\0';
-%}
-
-/**
- * sfunction user_string_n_quoted - Retrieves and quotes string from user space.
- * 
- * General Syntax: user_string_n_quoted:string(addr:long, n:long)
- * 
- * @addr: The user space address to retrieve the string from.
- * @n: The maximum length of the string (if not null terminated).
- *
- * Description: Returns up to n characters of a C string from the given
- * user space memory address where any ASCII characters that are not
- * printable are replaced by the corresponding escape sequence in the
- * returned string. Reports "NULL" for address zero. Returns "<unknown>"
- * on the rare cases when userspace data is not accessible at the given
- * address.
- */
-function user_string_n_quoted:string (addr:long, n:long) %{ /* pure */ /* unprivileged */
-        int64_t len = clamp_t(int64_t, THIS->n + 1, 1, MAXSTRINGLEN);
-        assert_is_myproc();
-       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);
-%}
-
-/**
- * sfunction user_short - Retrieves a short value stored in user space.
- * 
- * General Syntax: user_short:long(addr:long)
- *
- * @addr: The user space address to retrieve the short from.
- *
- * Description: Returns the short value from a given user space address.
- * Returns zero when user space data is not accessible.
- */
-function user_short:long (addr:long) %{ /* pure */ /* unprivileged */
-        STP_GET_USER(short);    
-%}
-
-/**
- * sfunction user_int16 - Retrieves a short value stored in user space.
- * 
- * General Syntax: user_int16:long(addr:long)
- *
- * @addr: The user space address to retrieve the short from.
- *
- * Description: Returns the short value from a given user space address.
- * Returns zero when user space data is not accessible.
- */
-function user_int16:long (addr:long) %{ /* pure */ /* unprivileged */
-        STP_GET_USER(short)  
-%}
-
-/**
- * sfunction user_uint16 - Retrieves an unsigned short value stored in user space.
- * 
- * General Syntax: user_uint16:long(addr:long)
- *
- * @addr: The user space address to retrieve the unsigned short from.
- *
- * Description: Returns the short value from a given user space address.
- * Returns zero when user space data is not accessible.
- */
-function user_uint16:long (addr:long) %{ /* pure */ /* unprivileged */
-        STP_GET_USER(unsigned short)
-%}
-
-
-/**
- * sfunction user_short_warn - Retrieves a short value stored in user space.
- *
- * General Syntax: user_short_warn:long(addr:long)
- *
- * @addr: The user space address to retrieve the short from.
- *
- * Description: Returns the short value from a given user space address.
- * Returns zero when user space and warns (but does not abort) about the
- * failure.
- */
-function user_short_warn:long (addr:long) %{ /* pure */ /* unprivileged */
-        assert_is_myproc();
-       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;
-       }
-%}
-
-/**
- * sfunction user_int - Retrieves an int value stored in user space.
- * 
- * General Syntax: user_int:long(addr:long)
- *
- * @addr: The user space address to retrieve the int from.
- *
- * Description: Returns the int value from a given user space address.
- * Returns zero when user space data is not accessible.
- */
-function user_int:long (addr:long) %{ /* pure */ /* unprivileged */
-       STP_GET_USER(int);
-%}
-
-/**
- * sfunction user_int32 - Retrieves an int value stored in user space.
- * 
- * General Syntax: user_int32:long(addr:long)
- *
- * @addr: The user space address to retrieve the int from.
- *
- * Description: Returns the int value from a given user space address.
- * Returns zero when user space data is not accessible.
- */
-function user_int32:long (addr:long) %{ /* pure */ /* unprivileged */
-        STP_GET_USER(int);
-%}
-
-/**
- * sfunction user_int_warn - Retrieves an int value stored in user space.
- * 
- * General Syntax: user_ing_warn:long(addr:long)
- * 
- * @addr: The user space address to retrieve the int from.
- *
- * Description: Returns the int value from a given user space address.
- * Returns zero when user space and warns (but does not abort) about the
- * failure.
- */
-function user_int_warn:long (addr:long) %{ /* pure */ /* unprivileged */
-        assert_is_myproc();
-       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;
-       }
-%}
-
-/**
- * sfunction user_uint32 - Retrieves an unsigned int value stored in user space.
- * 
- * General Syntax: user_uint32:long(addr:long)
- *
- * @addr: The user space address to retrieve the unsigned int from.
- *
- * Description: Returns the int value from a given user space address.
- * Returns zero when user space data is not accessible.
- */
-function user_uint32:long (addr:long) %{ /* pure */ /* unprivileged */
-        STP_GET_USER(unsigned int)
-%}
-
-/**
- * sfunction user_long - Retrieves a long value stored in user space.
- * 
- * General Syntax: user_long:long(addr:long)
- * 
- * @addr: The user space address to retrieve the long from.
- *
- * Description: Returns the long value from a given user space address.
- * Returns zero when user space data is not accessible. Note that the
- * size of the long depends on the architecture of the current user space
- * task (for those architectures that support both 64/32 bit compat tasks).
- */
-function user_long:long (addr:long) %{ /* pure */ /* unprivileged */
-       size_t l_size = sizeof(long);
-
-        assert_is_myproc();
-
-#ifdef CONFIG_COMPAT
-       if (_stp_is_compat_task())
-               l_size = sizeof(compat_long_t);
-#endif
-
-       if (!access_ok(VERIFY_READ, (long *) (intptr_t) THIS->addr, l_size))
-               goto fault;
-       if (l_size == sizeof(long)) {
-               if (__stp_get_user(THIS->__retvalue, (long *) (intptr_t) THIS->addr))
-               goto fault;
-#ifdef CONFIG_COMPAT
-       } else {
-               if (__stp_get_user(THIS->__retvalue, (compat_long_t *) (intptr_t) THIS->addr)) {
-
-                       goto fault;
-               }
-#endif
-       }
-
-       if (0) {
-fault:
-                       THIS->__retvalue = 0;
-       }
-%}
-
-/**
- * sfunction user_int64 - Retrieves a 64 bit int value stored in user space.
- * 
- * General Syntax: user_int64:long(addr:long)
- * 
- * @addr: The user space address to retrieve the 64 bit int from.
- *
- * Description: Returns the 64 bit int value from a given user space address.
- * Returns zero when user space data is not accessible.
- */
-function user_int64:long (addr:long) %{ /* pure */ /* unprivileged */
-#if __SIZEOF_LONG__ == 8
-        STP_GET_USER(long)
-#else
-        STP_GET_USER(long long)
-#endif
-%}
-
-/**
- * sfunction user_long_warn - Retrieves a long value stored in user space.
- * 
- * General Syntax: user_long_warn:long(addr:long)
- *
- * @addr: The user space address to retrieve the long from.
- *
- * Description: Returns the long value from a given user space address.
- * Returns zero when user space and warns (but does not abort) about the
- * failure. Note that the size of the long depends on the architecture
- * of the current user space task (for those architectures that support
- * both 64/32 bit compat tasks).
- */
-function user_long_warn:long (addr:long) %{ /* pure */ /* unprivileged */
-       size_t l_size = sizeof(long);
-
-        assert_is_myproc();
-
-#ifdef CONFIG_COMPAT
-       if (_stp_is_compat_task())
-               l_size = sizeof(compat_long_t);
-#endif
-
-       if (!access_ok(VERIFY_READ, (long *) (intptr_t) THIS->addr, l_size))
-               goto fault;
-       if (l_size == sizeof(long)) {
-               if (__stp_get_user(THIS->__retvalue, (long *) (intptr_t) THIS->addr)) {
-                       goto fault;
-               }
-#ifdef CONFIG_COMPAT
-       } else {
-               if (__stp_get_user(THIS->__retvalue, (compat_long_t *) (intptr_t) THIS->addr)) {
-
-                       goto fault;
-               }
-#endif
-       }
-
-       if (0) {
-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;
-       }
-%}
-
-/**
- * sfunction user_char - Retrieves a char value stored in user space.
- *
- * General Syntax: user_char:long(addr:long)
- *
- * @addr: The user space address to retrieve the char from.
- *
- * Description: Returns the char value from a given user space address.
- * Returns zero when user space data is not accessible.
- */
-function user_char:long (addr:long) %{ /* pure */ /* unprivileged */
-        STP_GET_USER(char)
-%}
-
-function user_int8:long (addr:long) %{ /* pure */ /* unprivileged */
-        STP_GET_USER(char)
-%}
-
-/**
- * sfunction user_char_warn - Retrieves a char value stored in user space.
- * 
- * General Syntax: user_char_warn:long(addr:long)
- *
- * @addr: The user space address to retrieve the char from.
- *
- * Description: Returns the char value from a given user space address.
- * Returns zero when user space and warns (but does not abort) about the
- * failure.
- */
-function user_char_warn:long (addr:long) %{ /* pure */ /* unprivileged */
-        assert_is_myproc();
-       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/tapset/uconversions.stp b/tapset/uconversions.stp
new file mode 100644 (file)
index 0000000..6fe7486
--- /dev/null
@@ -0,0 +1,458 @@
+// userspace conversions tapset
+// Copyright (C) 2005-2010 Red Hat Inc.
+// Copyright (C) 2007 Intel Corporation.
+//
+// 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.
+
+%{
+#define __STP_GET_USER(t, warn)                                                \
+       do {                                                            \
+               __label__ deref_fault;                                  \
+               t *_ptr = (t*) (intptr_t) THIS->addr;                   \
+               assert_is_myproc();                                     \
+               if (access_ok(VERIFY_READ, _ptr, sizeof(t)))            \
+                       THIS->__retvalue = kread(_ptr);                 \
+               else {                                                  \
+               deref_fault:                                            \
+                       THIS->__retvalue = 0;                           \
+                       CONTEXT->last_error = NULL;                     \
+                       if (warn) {                                     \
+                               snprintf(CONTEXT->error_buffer,         \
+                                   sizeof(CONTEXT->error_buffer),      \
+                                   "user %s copy fault %p", #t, _ptr); \
+                               _stp_warn(CONTEXT->error_buffer);       \
+                       }                                               \
+               }                                                       \
+       } while (0)
+
+#define STP_GET_USER(t) __STP_GET_USER(t, 0)
+#define STP_GET_USER_WARN(t) __STP_GET_USER(t, 1)
+%}
+
+/**
+ * sfunction user_string - Retrieves string from user space.
+ *
+ * General Syntax: user_string:string(addr:long)
+ *
+ * @addr: The user space address to retrieve the string from.
+ *
+ * Description: Returns the null terminated C string from a given user space
+ * memory address. Reports "<unknown>" on the rare cases when userspace
+ * data is not accessible.
+ */
+function user_string:string (addr:long) { return user_string2 (addr, "<unknown>") }
+
+/**
+ * sfunction user_string2 - Retrieves string from user space with alternative error string.
+ *
+ * General Syntax: user_string2:string(addr:long, err_msg:string)
+ *
+ * @addr: The user space address to retrieve the string from.
+ * @err_msg: The error message to return when data isn't available.
+ *
+ * Description: Returns the null terminated C string from a given user space
+ * memory address. Reports the given error message on the rare cases when
+ * userspace data is not accessible.
+ */
+function user_string2:string (addr:long, err_msg:string) %{ /* pure */ /* unprivileged */
+  assert_is_myproc();
+  if (_stp_strncpy_from_user (THIS->__retvalue,
+        (const char __user*) (uintptr_t) THIS->addr,
+        MAXSTRINGLEN) < 0)
+    strlcpy (THIS->__retvalue, THIS->err_msg, MAXSTRINGLEN);
+%}
+
+/**
+ * sfunction user_string_warn - Retrieves string from user space.
+ *
+ * General Syntax: user_string_warn:string(addr:long)
+ *
+ * @addr: The user space address to retrieve the string from.
+ *
+ * Description: Returns the null terminated C string from a given user space
+ * memory address. Reports "<unknown>" on the rare cases when userspace
+ * data is not accessible and warns (but does not abort) about the failure.
+ */
+function user_string_warn:string (addr:long) %{ /* pure */ /* unprivileged */
+  long rc;
+  assert_is_myproc();
+  rc = _stp_strncpy_from_user (THIS->__retvalue,
+      (const char __user*) (uintptr_t) THIS->addr, MAXSTRINGLEN);
+  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);
+  }
+%}
+
+/**
+ * sfunction user_string_quoted - Retrieves and quotes string from user space.
+ *
+ * General Syntax: user_string_quoted:string(addr:long)
+ *
+ * @addr: The user space address to retrieve the string from.
+ *
+ * Description: Returns the null terminated C string from a given user space
+ * memory address where any ASCII characters that are not printable are
+ * replaced by the corresponding escape sequence in the returned string.
+ * Reports "NULL" for address zero. Returns "<unknown>" on the rare
+ * cases when userspace data is not accessible at the given address.
+ */
+function user_string_quoted:string (addr:long) %{ /* pure */ /* unprivileged */
+  assert_is_myproc();
+  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);
+%}
+
+/**
+ * sfunction user_string_n - Retrieves string of given length from user space.
+ *
+ * General Syntax: user_string_n:string(addr:long, n:long)
+ *
+ * @addr: The user space address to retrieve the string from.
+ * @n: The maximum length of the string (if not null terminated).
+ *
+ * Description: Returns the C string of a maximum given length from a
+ * given user space address. Returns "<unknown>" on the rare cases
+ * when userspace data is not accessible at the given address.
+ */
+function user_string_n:string (addr:long, n:long) {
+       return user_string_n2(addr, n, "<unknown>")
+}
+
+/**
+ * sfunction user_string_n2 - Retrieves string of given length from user space.
+ *
+ * General Syntax: user_string_n2:string(addr:long, n:long, err_msg:string)
+ *
+ * @addr: The user space address to retrieve the string from.
+ * @n: The maximum length of the string (if not null terminated).
+ * @err_msg: The error message to return when data isn't available.
+ *
+ * Description: Returns the C string of a maximum given length from a
+ * given user space address. Returns the given error message string on
+ * the rare cases when userspace data is not accessible at the given
+ * address.
+ */
+function user_string_n2:string (addr:long, n:long, err_msg:string) %{ /* pure */ /* unprivileged */
+       int64_t len = clamp_t(int64_t, THIS->n + 1, 1, MAXSTRINGLEN);
+        assert_is_myproc();
+       if (_stp_strncpy_from_user(THIS->__retvalue,
+                               (char __user *) (uintptr_t) THIS->addr,
+                               len) < 0)
+               strlcpy(THIS->__retvalue, THIS->err_msg, MAXSTRINGLEN);
+       else
+               THIS->__retvalue[len - 1] = '\0';
+%}
+
+/**
+ * sfunction user_string_n_warn - Retrieves string from user space.
+ *
+ * General Syntax: user_string_n_warn:string(addr:long, n:long)
+ *
+ * @addr: The user space address to retrieve the string from.
+ * @n: The maximum length of the string (if not null terminated).
+ *
+ * Description: Returns up to n characters of a C string from a given
+ * user space memory address. Reports "<unknown>" on the rare cases
+ * when userspace data is not accessible and warns (but does not abort)
+ * about the failure.
+ */
+function user_string_n_warn:string (addr:long, n:long) %{ /* pure */ /* unprivileged */
+       int64_t len = clamp_t(int64_t, THIS->n + 1, 1, MAXSTRINGLEN);
+       long rc;
+
+        assert_is_myproc();
+       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);
+       } else
+               THIS->__retvalue[len - 1] = '\0';
+%}
+
+/**
+ * sfunction user_string_n_quoted - Retrieves and quotes string from user space.
+ *
+ * General Syntax: user_string_n_quoted:string(addr:long, n:long)
+ *
+ * @addr: The user space address to retrieve the string from.
+ * @n: The maximum length of the string (if not null terminated).
+ *
+ * Description: Returns up to n characters of a C string from the given
+ * user space memory address where any ASCII characters that are not
+ * printable are replaced by the corresponding escape sequence in the
+ * returned string. Reports "NULL" for address zero. Returns "<unknown>"
+ * on the rare cases when userspace data is not accessible at the given
+ * address.
+ */
+function user_string_n_quoted:string (addr:long, n:long) %{ /* pure */ /* unprivileged */
+        int64_t len = clamp_t(int64_t, THIS->n + 1, 1, MAXSTRINGLEN);
+        assert_is_myproc();
+       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);
+%}
+
+/**
+ * sfunction user_char - Retrieves a char value stored in user space.
+ *
+ * General Syntax: user_char:long(addr:long)
+ *
+ * @addr: The user space address to retrieve the char from.
+ *
+ * Description: Returns the char value from a given user space address.
+ * Returns zero when user space data is not accessible.
+ */
+function user_char:long (addr:long) %{ /* pure */ /* unprivileged */
+       STP_GET_USER(char);
+%}
+
+/**
+ * sfunction user_char_warn - Retrieves a char value stored in user space.
+ *
+ * General Syntax: user_char_warn:long(addr:long)
+ *
+ * @addr: The user space address to retrieve the char from.
+ *
+ * Description: Returns the char value from a given user space address.
+ * Returns zero when user space and warns (but does not abort) about the
+ * failure.
+ */
+function user_char_warn:long (addr:long) %{ /* pure */ /* unprivileged */
+       STP_GET_USER_WARN(char);
+%}
+
+/**
+ * sfunction user_short - Retrieves a short value stored in user space.
+ *
+ * General Syntax: user_short:long(addr:long)
+ *
+ * @addr: The user space address to retrieve the short from.
+ *
+ * Description: Returns the short value from a given user space address.
+ * Returns zero when user space data is not accessible.
+ */
+function user_short:long (addr:long) %{ /* pure */ /* unprivileged */
+       STP_GET_USER(short);
+%}
+
+/**
+ * sfunction user_short_warn - Retrieves a short value stored in user space.
+ *
+ * General Syntax: user_short_warn:long(addr:long)
+ *
+ * @addr: The user space address to retrieve the short from.
+ *
+ * Description: Returns the short value from a given user space address.
+ * Returns zero when user space and warns (but does not abort) about the
+ * failure.
+ */
+function user_short_warn:long (addr:long) %{ /* pure */ /* unprivileged */
+       STP_GET_USER_WARN(short);
+%}
+
+/**
+ * sfunction user_int - Retrieves an int value stored in user space.
+ *
+ * General Syntax: user_int:long(addr:long)
+ *
+ * @addr: The user space address to retrieve the int from.
+ *
+ * Description: Returns the int value from a given user space address.
+ * Returns zero when user space data is not accessible.
+ */
+function user_int:long (addr:long) %{ /* pure */ /* unprivileged */
+       STP_GET_USER(int);
+%}
+
+/**
+ * sfunction user_int_warn - Retrieves an int value stored in user space.
+ *
+ * General Syntax: user_ing_warn:long(addr:long)
+ *
+ * @addr: The user space address to retrieve the int from.
+ *
+ * Description: Returns the int value from a given user space address.
+ * Returns zero when user space and warns (but does not abort) about the
+ * failure.
+ */
+function user_int_warn:long (addr:long) %{ /* pure */ /* unprivileged */
+       STP_GET_USER_WARN(int);
+%}
+
+/**
+ * sfunction user_long - Retrieves a long value stored in user space.
+ *
+ * General Syntax: user_long:long(addr:long)
+ *
+ * @addr: The user space address to retrieve the long from.
+ *
+ * Description: Returns the long value from a given user space address.
+ * Returns zero when user space data is not accessible. Note that the
+ * size of the long depends on the architecture of the current user space
+ * task (for those architectures that support both 64/32 bit compat tasks).
+ */
+function user_long:long (addr:long) %{ /* pure */ /* unprivileged */
+#ifdef CONFIG_COMPAT
+       if (_stp_is_compat_task())
+               STP_GET_USER(compat_long_t);
+       else
+#endif
+               STP_GET_USER(long);
+%}
+
+/**
+ * sfunction user_long_warn - Retrieves a long value stored in user space.
+ *
+ * General Syntax: user_long_warn:long(addr:long)
+ *
+ * @addr: The user space address to retrieve the long from.
+ *
+ * Description: Returns the long value from a given user space address.
+ * Returns zero when user space and warns (but does not abort) about the
+ * failure. Note that the size of the long depends on the architecture
+ * of the current user space task (for those architectures that support
+ * both 64/32 bit compat tasks).
+ */
+function user_long_warn:long (addr:long) %{ /* pure */ /* unprivileged */
+#ifdef CONFIG_COMPAT
+       if (_stp_is_compat_task())
+               STP_GET_USER_WARN(compat_long_t);
+       else
+#endif
+               STP_GET_USER_WARN(long);
+%}
+
+/**
+ * sfunction user_int8 - Retrieves a 8-bit integer value stored in user space.
+ *
+ * General Syntax: user_int8:long(addr:long)
+ *
+ * @addr: The user space address to retrieve the 8-bit integer from.
+ *
+ * Description: Returns the 8-bit integer value from a given user space
+ * address.  Returns zero when user space data is not accessible.
+ */
+function user_int8:long (addr:long) %{ /* pure */ /* unprivileged */
+       STP_GET_USER(int8_t);
+%}
+
+/**
+ * sfunction user_uint8 - Retrieves an unsigned 8-bit integer value stored in user space.
+ *
+ * General Syntax: user_uint8:long(addr:long)
+ *
+ * @addr: The user space address to retrieve the unsigned 8-bit integer from.
+ *
+ * Description: Returns the unsigned 8-bit integer value from a given user
+ * space address.  Returns zero when user space data is not accessible.
+ */
+function user_uint8:long (addr:long) %{ /* pure */ /* unprivileged */
+       STP_GET_USER(uint8_t);
+%}
+
+/**
+ * sfunction user_int16 - Retrieves a 16-bit integer value stored in user space.
+ *
+ * General Syntax: user_int16:long(addr:long)
+ *
+ * @addr: The user space address to retrieve the 16-bit integer from.
+ *
+ * Description: Returns the 16-bit integer value from a given user space
+ * address.  Returns zero when user space data is not accessible.
+ */
+function user_int16:long (addr:long) %{ /* pure */ /* unprivileged */
+       STP_GET_USER(int16_t);
+%}
+
+/**
+ * sfunction user_uint16 - Retrieves an unsigned 16-bit integer value stored in user space.
+ *
+ * General Syntax: user_uint16:long(addr:long)
+ *
+ * @addr: The user space address to retrieve the unsigned 16-bit integer from.
+ *
+ * Description: Returns the unsigned 16-bit integer value from a given user
+ * space address.  Returns zero when user space data is not accessible.
+ */
+function user_uint16:long (addr:long) %{ /* pure */ /* unprivileged */
+       STP_GET_USER(uint16_t);
+%}
+
+/**
+ * sfunction user_int32 - Retrieves a 32-bit integer value stored in user space.
+ *
+ * General Syntax: user_int32:long(addr:long)
+ *
+ * @addr: The user space address to retrieve the 32-bit integer from.
+ *
+ * Description: Returns the 32-bit integer value from a given user space
+ * address.  Returns zero when user space data is not accessible.
+ */
+function user_int32:long (addr:long) %{ /* pure */ /* unprivileged */
+       STP_GET_USER(int32_t);
+%}
+
+/**
+ * sfunction user_uint32 - Retrieves an unsigned 32-bit integer value stored in user space.
+ *
+ * General Syntax: user_uint32:long(addr:long)
+ *
+ * @addr: The user space address to retrieve the unsigned 32-bit integer from.
+ *
+ * Description: Returns the unsigned 32-bit integer value from a given user
+ * space address.  Returns zero when user space data is not accessible.
+ */
+function user_uint32:long (addr:long) %{ /* pure */ /* unprivileged */
+       STP_GET_USER(uint32_t);
+%}
+
+/**
+ * sfunction user_int64 - Retrieves a 64-bit integer value stored in user space.
+ *
+ * General Syntax: user_int64:long(addr:long)
+ *
+ * @addr: The user space address to retrieve the 64-bit integer from.
+ *
+ * Description: Returns the 64-bit integer value from a given user space
+ * address.  Returns zero when user space data is not accessible.
+ */
+function user_int64:long (addr:long) %{ /* pure */ /* unprivileged */
+       STP_GET_USER(int64_t);
+%}
+
+/**
+ * sfunction user_uint64 - Retrieves an unsigned 64-bit integer value stored in user space.
+ *
+ * General Syntax: user_uint64:long(addr:long)
+ *
+ * @addr: The user space address to retrieve the unsigned 64-bit integer from.
+ *
+ * Description: Returns the unsigned 64-bit integer value from a given user
+ * space address.  Returns zero when user space data is not accessible.
+ */
+function user_uint64:long (addr:long) %{ /* pure */ /* unprivileged */
+       STP_GET_USER(uint64_t);
+%}
+
index e3c7f30330fffcee6b3cc04d09a236c18ec69444..ecd9b952a95772832fb5aa4d57bc0dbbfabd3ff1 100755 (executable)
@@ -26,5 +26,14 @@ probe begin {
        print (user_long_warn(0))
        print (user_char(0))
        print (user_char_warn(0))
+
+       print (user_int8(0))
+       print (user_uint8(0))
+       print (user_int16(0))
+       print (user_uint16(0))
+       print (user_int32(0))
+       print (user_uint32(0))
+       print (user_int64(0))
+       print (user_uint64(0))
 }
 
index 58ef9bfe71176020d1b75e4993aa1cf2c3f7b839..bb64b194a8786e605d3c0a208ad5da5e50142ddd 100755 (executable)
@@ -28,4 +28,13 @@ probe begin {
   print (user_long_warn(2342))
   print (user_char(2342))
   print (user_char_warn(2342))
+
+  print (user_int8(2342))
+  print (user_uint8(2342))
+  print (user_int16(2342))
+  print (user_uint16(2342))
+  print (user_int32(2342))
+  print (user_uint32(2342))
+  print (user_int64(2342))
+  print (user_uint64(2342))
 }
This page took 0.049458 seconds and 5 git commands to generate.