|
Server : Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8e-fips-rhel5 DAV/2 PHP/5.2.17 System : Linux localhost 2.6.18-419.el5 #1 SMP Fri Feb 24 22:47:42 UTC 2017 x86_64 User : nobody ( 99) PHP Version : 5.2.17 Disable Function : NONE Directory : /proc/21571/root/usr/share/systemtap/tapset/ |
Upload File : |
// userspace conversions tapset
// Copyright (C) 2005-2011 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) STAP_ARG_addr; \
assert_is_myproc(); \
if (! access_ok(VERIFY_READ, _ptr, sizeof(t))) \
goto deref_fault; \
if (__stp_get_user(STAP_RETVALUE, _ptr)) { \
deref_fault: \
STAP_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
*
* @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
*
* @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 */ /* myproc-unprivileged */
if (_stp_strncpy_from_user (STAP_RETVALUE,
(const char __user*) (uintptr_t) STAP_ARG_addr,
MAXSTRINGLEN) < 0)
strlcpy (STAP_RETVALUE, STAP_ARG_err_msg, MAXSTRINGLEN);
%}
/**
* sfunction user_string_warn - Retrieves string from user space
*
* @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 */ /* myproc-unprivileged */
long rc;
rc = _stp_strncpy_from_user (STAP_RETVALUE,
(const char __user*) (uintptr_t) STAP_ARG_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) STAP_ARG_addr);
_stp_warn(CONTEXT->error_buffer);
strlcpy (STAP_RETVALUE, "<unknown>", MAXSTRINGLEN);
}
%}
/**
* sfunction user_string_quoted - Retrieves and quotes string from user space
*
* @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 */ /* myproc-unprivileged */
if (STAP_ARG_addr == 0)
strlcpy (STAP_RETVALUE, "NULL", MAXSTRINGLEN);
else
/* XXX: stp_text_str uses sleepy __get_user() => unsafe ?! */
_stp_text_str(STAP_RETVALUE, (char *)(uintptr_t)STAP_ARG_addr,
MAXSTRINGLEN, 1, 1);
%}
/**
* sfunction user_string_n - Retrieves string of given length from user space
*
* @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
*
* @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 */ /* myproc-unprivileged */
int64_t len = clamp_t(int64_t, STAP_ARG_n + 1, 1, MAXSTRINGLEN);
if (_stp_strncpy_from_user(STAP_RETVALUE,
(char __user *) (uintptr_t) STAP_ARG_addr,
len) < 0)
strlcpy(STAP_RETVALUE, STAP_ARG_err_msg, MAXSTRINGLEN);
else
STAP_RETVALUE[len - 1] = '\0';
%}
/**
* sfunction user_string_n_warn - Retrieves string from user space
*
* @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 */ /* myproc-unprivileged */
int64_t len = clamp_t(int64_t, STAP_ARG_n + 1, 1, MAXSTRINGLEN);
long rc;
rc = _stp_strncpy_from_user(STAP_RETVALUE,
(char __user *) (uintptr_t) STAP_ARG_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) STAP_ARG_addr);
_stp_warn(CONTEXT->error_buffer);
strlcpy (STAP_RETVALUE, "<unknown>", MAXSTRINGLEN);
} else
STAP_RETVALUE[len - 1] = '\0';
%}
/**
* sfunction user_string_n_quoted - Retrieves and quotes string from user space
*
* @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 */ /* myproc-unprivileged */
int64_t len = clamp_t(int64_t, STAP_ARG_n + 1, 1, MAXSTRINGLEN);
if (STAP_ARG_addr == 0)
strlcpy(STAP_RETVALUE, "NULL", MAXSTRINGLEN);
else
/* XXX: stp_text_str uses sleepy __get_user() => unsafe ?! */
_stp_text_str(STAP_RETVALUE, (char *)(uintptr_t)STAP_ARG_addr,
len, 1, 1);
%}
/**
* sfunction user_char - Retrieves a char value stored in user space
*
* @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 */ /* myproc-unprivileged */
STP_GET_USER(char);
%}
/**
* sfunction user_char_warn - Retrieves a char value stored in user space
*
* @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 */ /* myproc-unprivileged */
STP_GET_USER_WARN(char);
%}
/**
* sfunction user_short - Retrieves a short value stored in user space
*
* @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 */ /* myproc-unprivileged */
STP_GET_USER(short);
%}
/**
* sfunction user_short_warn - Retrieves a short value stored in user space
*
* @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 */ /* myproc-unprivileged */
STP_GET_USER_WARN(short);
%}
/**
* sfunction user_ushort - Retrieves an unsigned short value stored in user space
*
* @addr: the user space address to retrieve the unsigned short from
*
* Description: Returns the unsigned short value from a given user
* space address. Returns zero when user space data is not accessible.
*/
function user_ushort:long (addr:long) %{ /* pure */ /* myproc-unprivileged */
STP_GET_USER(unsigned short);
%}
/**
* sfunction user_ushort_warn - Retrieves an unsigned short value stored in user space
*
* @addr: the user space address to retrieve the unsigned short from
*
* Description: Returns the unsigned short value from a given user
* space address. Returns zero when user space and warns (but does
* not abort) about the failure.
*/
function user_ushort_warn:long (addr:long) %{ /* pure */ /* myproc-unprivileged */
STP_GET_USER_WARN(unsigned short);
%}
/**
* sfunction user_int - Retrieves an int value stored in user space
*
* @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 */ /* myproc-unprivileged */
STP_GET_USER(int);
%}
/**
* sfunction user_int_warn - Retrieves an int value stored in user space
*
* @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 */ /* myproc-unprivileged */
STP_GET_USER_WARN(int);
%}
/**
* sfunction user_long - Retrieves a long value stored in user space
*
* @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 */ /* myproc-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
*
* @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 */ /* myproc-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
*
* @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 */ /* myproc-unprivileged */
STP_GET_USER(int8_t);
%}
/**
* sfunction user_uint8 - Retrieves an unsigned 8-bit integer value stored in user space
*
* @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 */ /* myproc-unprivileged */
STP_GET_USER(uint8_t);
%}
/**
* sfunction user_int16 - Retrieves a 16-bit integer value stored in user space
*
* @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 */ /* myproc-unprivileged */
STP_GET_USER(int16_t);
%}
/**
* sfunction user_uint16 - Retrieves an unsigned 16-bit integer value stored in user space
*
* @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 */ /* myproc-unprivileged */
STP_GET_USER(uint16_t);
%}
/**
* sfunction user_int32 - Retrieves a 32-bit integer value stored in user space
*
* @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 */ /* myproc-unprivileged */
STP_GET_USER(int32_t);
%}
/**
* sfunction user_uint32 - Retrieves an unsigned 32-bit integer value stored in user space
*
* @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 */ /* myproc-unprivileged */
STP_GET_USER(uint32_t);
%}
/**
* sfunction user_int64 - Retrieves a 64-bit integer value stored in user space
*
* @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 */ /* myproc-unprivileged */
#if defined (__i386__) || defined (__arm__)
/* As with kread() on i386 and arm, we must split 64-bit in two.
* STP_GET_USER isn't well designed for that, but I don't
* want to complicate all the other callers. */
uint32_t value[2];
STP_GET_USER(uint32_t);
value[0] = STAP_RETVALUE;
if (!CONTEXT->last_error) {
STAP_ARG_addr += 4;
STP_GET_USER(uint32_t);
value[1] = STAP_RETVALUE;
STAP_RETVALUE = *(int64_t*)value;
}
#else
STP_GET_USER(int64_t);
#endif
%}
/**
* sfunction user_uint64 - Retrieves an unsigned 64-bit integer value stored in user space
*
* @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) {
/* NB: We have no script-level notion of 64-bit unsigned,
* but we keep user_uint64 anyway for API completeness. */
return user_int64 (addr);
}