// context tapset
// Copyright (C) 2005-2009 Red Hat Inc.
// Copyright (C) 2006 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.
//
// Context functions provide additional information about where an event occurred. These functions can
//provide information such as a backtrace to where the event occured and the current register values for the
//processor.
//
%{
#include
%}
/**
* sfunction print_regs - Print a register dump.
*/
function print_regs () %{
if (CONTEXT->regs) {
_stp_print_regs (CONTEXT->regs);
}
%}
/**
* sfunction execname - Returns the execname of a target process (or group of processes).
*/
function execname:string () %{ /* pure */
strlcpy (THIS->__retvalue, current->comm, MAXSTRINGLEN);
%}
/**
* sfunction pid - Returns the ID of a target process.
*/
function pid:long () %{ /* pure */
THIS->__retvalue = current->tgid;
%}
/**
* sfunction tid - Returns the thread ID of a target process.
*/
function tid:long () %{ /* pure */
THIS->__retvalue = current->pid;
%}
/**
* sfunction ppid - Returns the process ID of a target process's parent process.
*/
function ppid:long () %{ /* pure */
#if defined(STAPCONF_REAL_PARENT)
THIS->__retvalue = current->real_parent->tgid;
#else
THIS->__retvalue = current->parent->tgid;
#endif
%}
/**
* sfunction pexecname - Returns the execname of a target process's parent process.
*/
function pexecname:string () %{ /* pure */
#if defined(STAPCONF_REAL_PARENT)
strlcpy (THIS->__retvalue, current->real_parent->comm, MAXSTRINGLEN);
#else
strlcpy (THIS->__retvalue, current->parent->comm, MAXSTRINGLEN);
#endif
%}
/**
* sfunction gid - Returns the group ID of a target process.
*/
function gid:long () %{ /* pure */
#ifdef STAPCONF_TASK_UID
THIS->__retvalue = current->gid;
#else
THIS->__retvalue = current_gid();
#endif
%}
/**
* sfunction egid - Returns the effective gid of a target process.
*/
function egid:long () %{ /* pure */
#ifdef STAPCONF_TASK_UID
THIS->__retvalue = current->egid;
#else
THIS->__retvalue = current_egid();
#endif
%}
/**
* sfunction uid - Returns the user ID of a target process.
*/
function uid:long () %{ /* pure */
#ifdef STAPCONF_TASK_UID
THIS->__retvalue = current->uid;
#else
THIS->__retvalue = current_uid();
#endif
%}
/**
* sfunction euid - Return the effective uid of a target process.
*/
function euid:long () %{ /* pure */
#ifdef STAPCONF_TASK_UID
THIS->__retvalue = current->euid;
#else
THIS->__retvalue = current_euid();
#endif
%}
// cpuid() is not documented
function cpuid:long () %{ /* pure */
THIS->__retvalue = smp_processor_id();
%}
/**
* sfunction cpu - Returns the current cpu number.
*/
function cpu:long () %{ /* pure */
THIS->__retvalue = smp_processor_id();
%}
/**
* sfunction pp - Return the probe point associated with the currently running probe handler,
* including alias and wildcard expansion effects
* Context:
* The current probe point.
*/
function pp:string () %{ /* pure */
strlcpy (THIS->__retvalue, CONTEXT->probe_point, MAXSTRINGLEN);
%}
/**
* sfunction registers_valid - Determines validity of register() and u_register() in current context.
*
* Return 1 if register() and u_register() can be used
* in the current context, or 0 otherwise.
* For example, registers_valid() returns 0
* when called from a begin or end probe.
*/
function registers_valid:long () %{ /* pure */
THIS->__retvalue = (CONTEXT->regs != NULL);
%}
/**
* sfunction user_mode - Determines if probe point occurs in user-mode.
*
* Return 1 if the probe point occurred in user-mode.
*/
function user_mode:long () %{ /* pure */ /* currently a user-mode address? */
if (CONTEXT->regs) {
#if defined(__i386__) || defined(__x86_64__)
THIS->__retvalue = (uint64_t) user_mode_vm (CONTEXT->regs);
#else
THIS->__retvalue = (uint64_t) user_mode (CONTEXT->regs);
#endif
} else {
THIS->__retvalue = 0;
}
%}
/**
* sfunction is_return - Determines if probe point is a return probe.
*
* Return 1 if the probe point is a return probe.
* Deprecated.
*/
function is_return:long () %{ /* pure */
if (CONTEXT->pi)
THIS->__retvalue = 1;
else
THIS->__retvalue = 0;
%}
/**
* sfunction target - Return the process ID of the target process.
*/
function target:long () %{ /* pure */
THIS->__retvalue = _stp_target;
%}
///
/// module_name:string()
/// module_name
///
/// FIXME: need description.
///
///
function module_name:string () %{ /* pure */
strlcpy(THIS->__retvalue, THIS_MODULE->name, MAXSTRINGLEN);
%}
///
/// stp_pid:long()
/// stp_pid
///
/// FIXME: need description.
///
///
function stp_pid:long () %{ /* pure */
THIS->__retvalue = _stp_pid;
%}
/**
* sfunction stack_size - Return the size of the kernel stack.
*/
function stack_size:long () %{ /* pure */
THIS->__retvalue = THREAD_SIZE;
%}
/**
* sfunction stack_used - Returns the amount of kernel stack used.
*
* Determines how many bytes are currently used in the kernel stack.
*/
function stack_used:long () %{ /* pure */
char a;
THIS->__retvalue = THREAD_SIZE - ((long)&a & (THREAD_SIZE-1));
%}
/**
* sfunction stack_unused - Returns the amount of kernel stack currently available.
*
* Determines how many bytes are currently available in the kernel stack.
*/
function stack_unused:long () %{ /* pure */
char a;
THIS->__retvalue = (long)&a & (THREAD_SIZE-1);
%}
/**
* sfunction uaddr - User space address of current running task.
*
* Description: Returns the address in userspace that the current
* task was at when the probe occured. When the current running task
* isn't a user space thread, or the address cannot be found, zero
* is returned.
*/
function uaddr:long () %{ /* pure */
int64_t addr = 0;
if (current->mm)
{
struct pt_regs *uregs;
uregs = task_pt_regs(current);
if (uregs)
addr = (int64_t) REG_IP(uregs);
}
THIS->__retvalue = addr;
%}