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>
// 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.
*
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;
- }
-%}
-
--- /dev/null
+// 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);
+%}
+
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))
}
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))
}