Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 37865
b: refs/heads/master
c: eae6c0d
h: refs/heads/master
i:
  37863: d482d51
v: v3
  • Loading branch information
Atsushi Nemoto authored and Ralf Baechle committed Oct 1, 2006
1 parent 9abe2b1 commit a32c4b8
Show file tree
Hide file tree
Showing 302 changed files with 3,749 additions and 5,343 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3f2e05e90e0846c42626e3d272454f26be34a1bc
refs/heads/master: eae6c0da9df81300895949897c0451423340ac40
89 changes: 33 additions & 56 deletions trunk/Documentation/kprobes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ So that you can load and unload Kprobes-based instrumentation modules,
make sure "Loadable module support" (CONFIG_MODULES) and "Module
unloading" (CONFIG_MODULE_UNLOAD) are set to "y".

Also make sure that CONFIG_KALLSYMS and perhaps even CONFIG_KALLSYMS_ALL
are set to "y", since kallsyms_lookup_name() is used by the in-kernel
kprobe address resolution code.
You may also want to ensure that CONFIG_KALLSYMS and perhaps even
CONFIG_KALLSYMS_ALL are set to "y", since kallsyms_lookup_name()
is a handy, version-independent way to find a function's address.

If you need to insert a probe in the middle of a function, you may find
it useful to "Compile the kernel with debug info" (CONFIG_DEBUG_INFO),
Expand All @@ -179,27 +179,6 @@ occurs during execution of kp->pre_handler or kp->post_handler,
or during single-stepping of the probed instruction, Kprobes calls
kp->fault_handler. Any or all handlers can be NULL.

NOTE:
1. With the introduction of the "symbol_name" field to struct kprobe,
the probepoint address resolution will now be taken care of by the kernel.
The following will now work:

kp.symbol_name = "symbol_name";

(64-bit powerpc intricacies such as function descriptors are handled
transparently)

2. Use the "offset" field of struct kprobe if the offset into the symbol
to install a probepoint is known. This field is used to calculate the
probepoint.

3. Specify either the kprobe "symbol_name" OR the "addr". If both are
specified, kprobe registration will fail with -EINVAL.

4. With CISC architectures (such as i386 and x86_64), the kprobes code
does not validate if the kprobe.addr is at an instruction boundary.
Use "offset" with caution.

register_kprobe() returns 0 on success, or a negative errno otherwise.

User's pre-handler (kp->pre_handler):
Expand Down Expand Up @@ -246,12 +225,6 @@ control to Kprobes.) If the probed function is declared asmlinkage,
fastcall, or anything else that affects how args are passed, the
handler's declaration must match.

NOTE: A macro JPROBE_ENTRY is provided to handle architecture-specific
aliasing of jp->entry. In the interest of portability, it is advised
to use:

jp->entry = JPROBE_ENTRY(handler);

register_jprobe() returns 0 on success, or a negative errno otherwise.

4.3 register_kretprobe
Expand All @@ -278,11 +251,6 @@ of interest:
- ret_addr: the return address
- rp: points to the corresponding kretprobe object
- task: points to the corresponding task struct

The regs_return_value(regs) macro provides a simple abstraction to
extract the return value from the appropriate register as defined by
the architecture's ABI.

The handler's return value is currently ignored.

4.4 unregister_*probe
Expand Down Expand Up @@ -401,6 +369,7 @@ stack trace and selected i386 registers when do_fork() is called.
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/kallsyms.h>
#include <linux/sched.h>

/*For each probe you need to allocate a kprobe structure*/
Expand Down Expand Up @@ -434,14 +403,18 @@ int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
return 0;
}

static int __init kprobe_init(void)
int init_module(void)
{
int ret;
kp.pre_handler = handler_pre;
kp.post_handler = handler_post;
kp.fault_handler = handler_fault;
kp.symbol_name = "do_fork";

kp.addr = (kprobe_opcode_t*) kallsyms_lookup_name("do_fork");
/* register the kprobe now */
if (!kp.addr) {
printk("Couldn't find %s to plant kprobe\n", "do_fork");
return -1;
}
if ((ret = register_kprobe(&kp) < 0)) {
printk("register_kprobe failed, returned %d\n", ret);
return -1;
Expand All @@ -450,14 +423,12 @@ static int __init kprobe_init(void)
return 0;
}

static void __exit kprobe_exit(void)
void cleanup_module(void)
{
unregister_kprobe(&kp);
printk("kprobe unregistered\n");
}

module_init(kprobe_init)
module_exit(kprobe_exit)
MODULE_LICENSE("GPL");
----- cut here -----

Expand Down Expand Up @@ -492,6 +463,7 @@ the arguments of do_fork().
#include <linux/fs.h>
#include <linux/uio.h>
#include <linux/kprobes.h>
#include <linux/kallsyms.h>

/*
* Jumper probe for do_fork.
Expand All @@ -513,13 +485,17 @@ long jdo_fork(unsigned long clone_flags, unsigned long stack_start,
}

static struct jprobe my_jprobe = {
.entry = JPROBE_ENTRY(jdo_fork)
.entry = (kprobe_opcode_t *) jdo_fork
};

static int __init jprobe_init(void)
int init_module(void)
{
int ret;
my_jprobe.kp.symbol_name = "do_fork";
my_jprobe.kp.addr = (kprobe_opcode_t *) kallsyms_lookup_name("do_fork");
if (!my_jprobe.kp.addr) {
printk("Couldn't find %s to plant jprobe\n", "do_fork");
return -1;
}

if ((ret = register_jprobe(&my_jprobe)) <0) {
printk("register_jprobe failed, returned %d\n", ret);
Expand All @@ -530,14 +506,12 @@ static int __init jprobe_init(void)
return 0;
}

static void __exit jprobe_exit(void)
void cleanup_module(void)
{
unregister_jprobe(&my_jprobe);
printk("jprobe unregistered\n");
}

module_init(jprobe_init)
module_exit(jprobe_exit)
MODULE_LICENSE("GPL");
----- cut here -----

Expand All @@ -556,13 +530,16 @@ report failed calls to sys_open().
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/kallsyms.h>

static const char *probed_func = "sys_open";

/* Return-probe handler: If the probed function fails, log the return value. */
static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
{
int retval = regs_return_value(regs);
// Substitute the appropriate register name for your architecture --
// e.g., regs->rax for x86_64, regs->gpr[3] for ppc64.
int retval = (int) regs->eax;
if (retval < 0) {
printk("%s returns %d\n", probed_func, retval);
}
Expand All @@ -575,11 +552,15 @@ static struct kretprobe my_kretprobe = {
.maxactive = 20
};

static int __init kretprobe_init(void)
int init_module(void)
{
int ret;
my_kretprobe.kp.symbol_name = (char *)probed_func;

my_kretprobe.kp.addr =
(kprobe_opcode_t *) kallsyms_lookup_name(probed_func);
if (!my_kretprobe.kp.addr) {
printk("Couldn't find %s to plant return probe\n", probed_func);
return -1;
}
if ((ret = register_kretprobe(&my_kretprobe)) < 0) {
printk("register_kretprobe failed, returned %d\n", ret);
return -1;
Expand All @@ -588,7 +569,7 @@ static int __init kretprobe_init(void)
return 0;
}

static void __exit kretprobe_exit(void)
void cleanup_module(void)
{
unregister_kretprobe(&my_kretprobe);
printk("kretprobe unregistered\n");
Expand All @@ -597,8 +578,6 @@ static void __exit kretprobe_exit(void)
my_kretprobe.nmissed, probed_func);
}

module_init(kretprobe_init)
module_exit(kretprobe_exit)
MODULE_LICENSE("GPL");
----- cut here -----

Expand All @@ -611,5 +590,3 @@ messages.)
For additional information on Kprobes, refer to the following URLs:
http://www-106.ibm.com/developerworks/library/l-kprobes.html?ca=dgr-lnxw42Kprobe
http://www.redhat.com/magazine/005mar05/features/kprobes/
http://www-users.cs.umn.edu/~boutcher/kprobes/
http://www.linuxsymposium.org/2006/linuxsymposium_procv2.pdf (pages 101-115)
3 changes: 2 additions & 1 deletion trunk/arch/alpha/kernel/alpha_ksyms.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <asm/cacheflush.h>
#include <asm/vga.h>

#define __KERNEL_SYSCALLS__
#include <asm/unistd.h>

extern struct hwrpb_struct *hwrpb;
Expand Down Expand Up @@ -115,7 +116,7 @@ EXPORT_SYMBOL(sys_dup);
EXPORT_SYMBOL(sys_exit);
EXPORT_SYMBOL(sys_write);
EXPORT_SYMBOL(sys_lseek);
EXPORT_SYMBOL(kernel_execve);
EXPORT_SYMBOL(execve);
EXPORT_SYMBOL(sys_setsid);
EXPORT_SYMBOL(sys_wait4);

Expand Down
10 changes: 5 additions & 5 deletions trunk/arch/alpha/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -655,12 +655,12 @@ kernel_thread:
.end kernel_thread

/*
* kernel_execve(path, argv, envp)
* execve(path, argv, envp)
*/
.align 4
.globl kernel_execve
.ent kernel_execve
kernel_execve:
.globl execve
.ent execve
execve:
/* We can be called from a module. */
ldgp $gp, 0($27)
lda $sp, -(32+SIZEOF_PT_REGS+8)($sp)
Expand Down Expand Up @@ -704,7 +704,7 @@ kernel_execve:

1: lda $sp, 32+SIZEOF_PT_REGS+8($sp)
ret
.end kernel_execve
.end execve


/*
Expand Down
26 changes: 13 additions & 13 deletions trunk/arch/alpha/kernel/osf_sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -402,15 +402,15 @@ osf_utsname(char __user *name)

down_read(&uts_sem);
error = -EFAULT;
if (copy_to_user(name + 0, utsname()->sysname, 32))
if (copy_to_user(name + 0, system_utsname.sysname, 32))
goto out;
if (copy_to_user(name + 32, utsname()->nodename, 32))
if (copy_to_user(name + 32, system_utsname.nodename, 32))
goto out;
if (copy_to_user(name + 64, utsname()->release, 32))
if (copy_to_user(name + 64, system_utsname.release, 32))
goto out;
if (copy_to_user(name + 96, utsname()->version, 32))
if (copy_to_user(name + 96, system_utsname.version, 32))
goto out;
if (copy_to_user(name + 128, utsname()->machine, 32))
if (copy_to_user(name + 128, system_utsname.machine, 32))
goto out;

error = 0;
Expand Down Expand Up @@ -449,8 +449,8 @@ osf_getdomainname(char __user *name, int namelen)

down_read(&uts_sem);
for (i = 0; i < len; ++i) {
__put_user(utsname()->domainname[i], name + i);
if (utsname()->domainname[i] == '\0')
__put_user(system_utsname.domainname[i], name + i);
if (system_utsname.domainname[i] == '\0')
break;
}
up_read(&uts_sem);
Expand Down Expand Up @@ -607,12 +607,12 @@ osf_sigstack(struct sigstack __user *uss, struct sigstack __user *uoss)
asmlinkage long
osf_sysinfo(int command, char __user *buf, long count)
{
char *sysinfo_table[] = {
utsname()->sysname,
utsname()->nodename,
utsname()->release,
utsname()->version,
utsname()->machine,
static char * sysinfo_table[] = {
system_utsname.sysname,
system_utsname.nodename,
system_utsname.release,
system_utsname.version,
system_utsname.machine,
"alpha", /* instruction set architecture */
"dummy", /* hardware serial number */
"dummy", /* hardware manufacturer */
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/alpha/kernel/srmcons.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ srmcons_close(struct tty_struct *tty, struct file *filp)

static struct tty_driver *srmcons_driver;

static const struct tty_operations srmcons_ops = {
static struct tty_operations srmcons_ops = {
.open = srmcons_open,
.close = srmcons_close,
.write = srmcons_write,
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/arm/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ static void __init setup_processor(void)
cpu_name, processor_id, (int)processor_id & 15,
proc_arch[cpu_architecture()], cr_alignment);

sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS);
sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS);
sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
elf_hwcap = list->elf_hwcap;
#ifndef CONFIG_ARM_THUMB
Expand Down
2 changes: 0 additions & 2 deletions trunk/arch/arm/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@
* The online bitmask indicates that the CPU is up and running.
*/
cpumask_t cpu_possible_map;
EXPORT_SYMBOL(cpu_possible_map);
cpumask_t cpu_online_map;
EXPORT_SYMBOL(cpu_online_map);

/*
* as from 2.5, kernels no longer have an init_tasks structure
Expand Down
4 changes: 2 additions & 2 deletions trunk/arch/arm/kernel/sys_arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ asmlinkage int sys_execve(char __user *filenamei, char __user * __user *argv,
return error;
}

int kernel_execve(const char *filename, char *const argv[], char *const envp[])
long execve(const char *filename, char **argv, char **envp)
{
struct pt_regs regs;
int ret;
Expand Down Expand Up @@ -317,7 +317,7 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[])
out:
return ret;
}
EXPORT_SYMBOL(kernel_execve);
EXPORT_SYMBOL(execve);

/*
* Since loff_t is a 64 bit type we avoid a lot of ABI hastle
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/arm26/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ static void __init setup_processor(void)

dump_cpu_info();

sprintf(init_utsname()->machine, "%s", list->arch_name);
sprintf(system_utsname.machine, "%s", list->arch_name);
sprintf(elf_platform, "%s", list->elf_name);
elf_hwcap = list->elf_hwcap;

Expand Down
4 changes: 2 additions & 2 deletions trunk/arch/arm26/kernel/sys_arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ asmlinkage int sys_execve(char *filenamei, char **argv, char **envp, struct pt_r
}

/* FIXME - see if this is correct for arm26 */
int kernel_execve(const char *filename, char *const argv[], char *const envp[])
long execve(const char *filename, char **argv, char **envp)
{
struct pt_regs regs;
int ret;
Expand Down Expand Up @@ -320,4 +320,4 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[])
return ret;
}

EXPORT_SYMBOL(kernel_execve);
EXPORT_SYMBOL(execve);
Loading

0 comments on commit a32c4b8

Please sign in to comment.