summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/autoconf-nameidata.c4
-rw-r--r--runtime/autoconf-x86-uniregs.c6
-rw-r--r--runtime/loc2c-runtime.h32
-rw-r--r--runtime/procfs.c6
-rw-r--r--runtime/regs.c79
-rw-r--r--runtime/regs.h5
-rw-r--r--runtime/stack-i386.c4
-rw-r--r--runtime/staprun/ChangeLog5
-rw-r--r--runtime/staprun/staprun_funcs.c2
-rw-r--r--runtime/staprun/symbols.c13
-rw-r--r--runtime/uprobes/uprobes.c72
11 files changed, 209 insertions, 19 deletions
diff --git a/runtime/autoconf-nameidata.c b/runtime/autoconf-nameidata.c
new file mode 100644
index 00000000..c1d02400
--- /dev/null
+++ b/runtime/autoconf-nameidata.c
@@ -0,0 +1,4 @@
+#include <linux/namei.h>
+
+struct nameidata nd __attribute__ ((unused)) = {.path={(void *)0}};
+
diff --git a/runtime/autoconf-x86-uniregs.c b/runtime/autoconf-x86-uniregs.c
new file mode 100644
index 00000000..25729c22
--- /dev/null
+++ b/runtime/autoconf-x86-uniregs.c
@@ -0,0 +1,6 @@
+#include <asm/ptrace.h>
+
+#if defined (__i386__) || defined (__x86_64__)
+struct pt_regs regs = {.ax = 0x0};
+#endif
+
diff --git a/runtime/loc2c-runtime.h b/runtime/loc2c-runtime.h
index 8dbff764..4674e399 100644
--- a/runtime/loc2c-runtime.h
+++ b/runtime/loc2c-runtime.h
@@ -75,7 +75,37 @@
})
-#if defined __i386__
+#if defined (STAPCONF_X86_UNIREGS) && defined (__i386__)
+
+#define dwarf_register_0(regs) regs->ax
+#define dwarf_register_1(regs) regs->cx
+#define dwarf_register_2(regs) regs->dx
+#define dwarf_register_3(regs) regs->bx
+#define dwarf_register_4(regs) ((long) &regs->sp)
+#define dwarf_register_5(regs) regs->bp
+#define dwarf_register_6(regs) regs->si
+#define dwarf_register_7(regs) regs->di
+
+#elif defined (STAPCONF_X86_UNIREGS) && defined (__x86_64__)
+
+#define dwarf_register_0(regs) regs->ax
+#define dwarf_register_1(regs) regs->dx
+#define dwarf_register_2(regs) regs->cx
+#define dwarf_register_3(regs) regs->bx
+#define dwarf_register_4(regs) regs->si
+#define dwarf_register_5(regs) regs->di
+#define dwarf_register_6(regs) regs->bp
+#define dwarf_register_7(regs) regs->sp
+#define dwarf_register_8(regs) regs->r8
+#define dwarf_register_9(regs) regs->r9
+#define dwarf_register_10(regs) regs->r10
+#define dwarf_register_11(regs) regs->r11
+#define dwarf_register_12(regs) regs->r12
+#define dwarf_register_13(regs) regs->r13
+#define dwarf_register_14(regs) regs->r14
+#define dwarf_register_15(regs) regs->r15
+
+#elif defined __i386__
/* The stack pointer is unlike other registers. When a trap happens in
kernel mode, it is not saved in the trap frame (struct pt_regs).
diff --git a/runtime/procfs.c b/runtime/procfs.c
index eb0f845c..1b1d5447 100644
--- a/runtime/procfs.c
+++ b/runtime/procfs.c
@@ -87,8 +87,14 @@ int _stp_mkdir_proc_module(void)
goto done;
}
} else {
+ #ifdef STAPCONF_NAMEIDATA_CLEANUP
+ _stp_proc_stap = PDE(nd.path.dentry->d_inode);
+ path_put (&nd.path);
+
+ #else
_stp_proc_stap = PDE(nd.dentry->d_inode);
path_release (&nd);
+ #endif
}
_stp_proc_root = proc_mkdir(THIS_MODULE->name, _stp_proc_stap);
diff --git a/runtime/regs.c b/runtime/regs.c
index bc717695..5e08e376 100644
--- a/runtime/regs.c
+++ b/runtime/regs.c
@@ -33,7 +33,13 @@
unsigned long _stp_ret_addr (struct pt_regs *regs)
{
-#ifdef __x86_64__
+#if defined (STAPCONF_X86_UNIREGS) && (defined (__x86_64__) || defined (__i386__))
+ unsigned long *ra = (unsigned long *)regs->sp;
+ if (ra)
+ return *ra;
+ else
+ return 0;
+#elif defined (__x86_64__)
unsigned long *ra = (unsigned long *)regs->rsp;
if (ra)
return *ra;
@@ -77,7 +83,76 @@ unsigned long _stp_ret_addr (struct pt_regs *regs)
*/
#define _stp_probe_addr_r(ri) (ri->rp->kp.addr)
-#ifdef __x86_64__
+#if defined (STAPCONF_X86_UNIREGS) && defined (__x86_64__)
+
+void _stp_print_regs(struct pt_regs * regs)
+{
+ unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs;
+ unsigned int fsindex,gsindex;
+ unsigned int ds,cs,es;
+
+ _stp_printf("RIP: %016lx\nRSP: %016lx EFLAGS: %08lx\n", regs->ip, regs->sp, regs->flags);
+ _stp_printf("RAX: %016lx RBX: %016lx RCX: %016lx\n",
+ regs->ax, regs->bx, regs->cx);
+ _stp_printf("RDX: %016lx RSI: %016lx RDI: %016lx\n",
+ regs->dx, regs->si, regs->di);
+ _stp_printf("RBP: %016lx R08: %016lx R09: %016lx\n",
+ regs->bp, regs->r8, regs->r9);
+ _stp_printf("R10: %016lx R11: %016lx R12: %016lx\n",
+ regs->r10, regs->r11, regs->r12);
+ _stp_printf("R13: %016lx R14: %016lx R15: %016lx\n",
+ regs->r13, regs->r14, regs->r15);
+
+ asm("movl %%ds,%0" : "=r" (ds));
+ asm("movl %%cs,%0" : "=r" (cs));
+ asm("movl %%es,%0" : "=r" (es));
+ asm("movl %%fs,%0" : "=r" (fsindex));
+ asm("movl %%gs,%0" : "=r" (gsindex));
+
+ rdmsrl(MSR_FS_BASE, fs);
+ rdmsrl(MSR_GS_BASE, gs);
+ rdmsrl(MSR_KERNEL_GS_BASE, shadowgs);
+
+ asm("movq %%cr0, %0": "=r" (cr0));
+ asm("movq %%cr2, %0": "=r" (cr2));
+ asm("movq %%cr3, %0": "=r" (cr3));
+ asm("movq %%cr4, %0": "=r" (cr4));
+
+ _stp_printf("FS: %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n",
+ fs,fsindex,gs,gsindex,shadowgs);
+ _stp_printf("CS: %04x DS: %04x ES: %04x CR0: %016lx\n", cs, ds, es, cr0);
+ _stp_printf("CR2: %016lx CR3: %016lx CR4: %016lx\n", cr2, cr3, cr4);
+}
+
+ #elif defined (STAPCONF_X86_UNIREGS) && defined (__i386__)
+
+void _stp_print_regs(struct pt_regs * regs)
+{
+ unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
+
+ _stp_printf ("EIP: %08lx\n",regs->ip);
+ _stp_printf ("ESP: %08lx\n",regs->sp);
+ _stp_printf ("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
+ regs->ax,regs->bx,regs->cx,regs->dx);
+ _stp_printf ("ESI: %08lx EDI: %08lx EBP: %08lx",
+ regs->si, regs->di, regs->bp);
+ _stp_printf (" DS: %04x ES: %04x\n",
+ 0xffff & regs->ds,0xffff & regs->es);
+
+ __asm__("movl %%cr0, %0": "=r" (cr0));
+ __asm__("movl %%cr2, %0": "=r" (cr2));
+ __asm__("movl %%cr3, %0": "=r" (cr3));
+ /* This could fault if %cr4 does not exist */
+ __asm__("1: movl %%cr4, %0 \n"
+ "2: \n"
+ ".section __ex_table,\"a\" \n"
+ ".long 1b,2b \n"
+ ".previous \n"
+ : "=r" (cr4): "0" (0));
+ _stp_printf ("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4);
+}
+
+#elif defined (__x86_64__)
void _stp_print_regs(struct pt_regs * regs)
{
unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L, fs, gs, shadowgs;
diff --git a/runtime/regs.h b/runtime/regs.h
index 0887d628..c1e2344b 100644
--- a/runtime/regs.h
+++ b/runtime/regs.h
@@ -11,8 +11,11 @@
#ifndef _REGS_H_ /* -*- linux-c -*- */
#define _REGS_H_
+#if defined (STAPCONF_X86_UNIREGS) && (defined (__x86_64__) || defined (__i386__))
+#define REG_IP(regs) regs->ip
+#define REG_SP(regs) regs->sp
-#ifdef __x86_64__
+#elif defined (__x86_64__)
#define REG_IP(regs) regs->rip
#define REG_SP(regs) regs->rsp
diff --git a/runtime/stack-i386.c b/runtime/stack-i386.c
index 3675fc97..d73f4c84 100644
--- a/runtime/stack-i386.c
+++ b/runtime/stack-i386.c
@@ -21,7 +21,11 @@ static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels)
#ifdef CONFIG_FRAME_POINTER
{
+ #ifdef STAPCONF_X86_UNIREGS
+ unsigned long ebp = regs->bp;
+ #elif
unsigned long ebp = regs->ebp;
+ #endif
while (_stp_valid_stack_ptr(context, (unsigned long)ebp)) {
addr = *(unsigned long *)(ebp + 4);
diff --git a/runtime/staprun/ChangeLog b/runtime/staprun/ChangeLog
index 3f373863..53545db2 100644
--- a/runtime/staprun/ChangeLog
+++ b/runtime/staprun/ChangeLog
@@ -1,3 +1,8 @@
+2008-01-21 Martin Hunt <hunt@redhat.com>
+
+ * symbols.c (send_module): Simplify and use new send_data() function to keep
+ longword alignment.
+
2008-01-14 Martin Hunt <hunt@redhat.com>
PR4037 and fixes to better synchronize staprun and stapio.
diff --git a/runtime/staprun/staprun_funcs.c b/runtime/staprun/staprun_funcs.c
index ebf05b34..d1bba3f8 100644
--- a/runtime/staprun/staprun_funcs.c
+++ b/runtime/staprun/staprun_funcs.c
@@ -16,8 +16,6 @@
#include <grp.h>
#include <pwd.h>
-void cleanup(int rc);
-
void setup_staprun_signals(void)
{
struct sigaction a;
diff --git a/runtime/staprun/symbols.c b/runtime/staprun/symbols.c
index 5a4855b3..e33ee624 100644
--- a/runtime/staprun/symbols.c
+++ b/runtime/staprun/symbols.c
@@ -12,9 +12,8 @@
#include "staprun.h"
/* send symbol data */
-static int send_data(void *data, int len)
+static int send_data(int32_t type, void *data, int len)
{
- int32_t type = STP_SYMBOLS;
if (write(control_channel, &type, 4) <= 0)
return -1;
return write(control_channel, data, len);
@@ -158,11 +157,9 @@ static int send_module (char *mname)
{
char data[65536];
int len;
- *(int32_t *)data = STP_MODULE;
- len = get_sections(mname, data + sizeof(int32_t),
- sizeof(data) - sizeof(int32_t));
+ len = get_sections(mname, data, sizeof(data));
if (len > 0) {
- if (write(control_channel, data, len + sizeof(int32_t)) <= 0) {
+ if (send_data(STP_MODULE, data, len) < 0) {
_err("Loading of module %s failed. Exiting...\n", mname);
return -1;
}
@@ -296,11 +293,11 @@ int do_kernel_symbols(void)
goto err;
/* send syms */
- if (send_data(syms, num_syms*struct_symbol_size) < 0)
+ if (send_data(STP_SYMBOLS, syms, num_syms*struct_symbol_size) < 0)
goto err;
/* send data */
- if (send_data(data_base, dataptr-data_base) < 0)
+ if (send_data(STP_SYMBOLS, data_base, dataptr-data_base) < 0)
goto err;
free(data_base);
diff --git a/runtime/uprobes/uprobes.c b/runtime/uprobes/uprobes.c
index 50930709..501c4298 100644
--- a/runtime/uprobes/uprobes.c
+++ b/runtime/uprobes/uprobes.c
@@ -42,8 +42,14 @@
#define MAX_SSOL_SLOTS 1024
+#ifdef NO_ACCESS_PROCESS_VM_EXPORT
+static int __access_process_vm(struct task_struct *tsk, unsigned long addr,
+ void *buf, int len, int write);
+#define access_process_vm __access_process_vm
+#else
extern int access_process_vm(struct task_struct *tsk, unsigned long addr,
void *buf, int len, int write);
+#endif
static int utask_fake_quiesce(struct uprobe_task *utask);
static void uprobe_release_ssol_vma(struct uprobe_process *uproc);
@@ -1601,7 +1607,7 @@ static u32 uprobe_report_signal(struct utrace_attached_engine *engine,
int hit_uretprobe_trampoline = 0;
int registrations_deferred = 0;
- utask = rcu_dereference((struct uprobe_task *)engine->data);
+ utask = (struct uprobe_task *)rcu_dereference(engine->data);
BUG_ON(!utask);
if (info->si_signo != BREAKPOINT_SIGNAL &&
@@ -1785,7 +1791,7 @@ static u32 uprobe_report_quiesce(struct utrace_attached_engine *engine,
struct uprobe_task *utask;
struct uprobe_process *uproc;
- utask = rcu_dereference((struct uprobe_task *)engine->data);
+ utask = (struct uprobe_task *)rcu_dereference(engine->data);
BUG_ON(!utask);
uproc = utask->uproc;
if (current == utask->quiesce_master) {
@@ -1886,7 +1892,7 @@ static u32 uprobe_report_exit(struct utrace_attached_engine *engine,
struct uprobe_probept *ppt;
int utask_quiescing;
- utask = rcu_dereference((struct uprobe_task *)engine->data);
+ utask = (struct uprobe_task *)rcu_dereference(engine->data);
uproc = utask->uproc;
uprobe_get_process(uproc);
@@ -1965,7 +1971,7 @@ static u32 uprobe_report_clone(struct utrace_attached_engine *engine,
struct uprobe_process *uproc;
struct uprobe_task *ptask, *ctask;
- ptask = rcu_dereference((struct uprobe_task *)engine->data);
+ ptask = (struct uprobe_task *)rcu_dereference(engine->data);
uproc = ptask->uproc;
/*
@@ -2054,7 +2060,7 @@ static u32 uprobe_report_exec(struct utrace_attached_engine *engine,
struct uprobe_task *utask;
int uproc_freed;
- utask = rcu_dereference((struct uprobe_task *)engine->data);
+ utask = (struct uprobe_task *)rcu_dereference(engine->data);
uproc = utask->uproc;
uprobe_get_process(uproc);
@@ -2267,5 +2273,61 @@ static void zap_uretprobe_instances(struct uprobe *u,
}
#endif /* CONFIG_URETPROBES */
+#ifdef NO_ACCESS_PROCESS_VM_EXPORT
+/*
+ * Some kernel versions export everything that uprobes.ko needs except
+ * access_process_vm, so we copied and pasted it here. Fortunately,
+ * everything it calls is exported.
+ */
+#include <linux/pagemap.h>
+#include <asm/cacheflush.h>
+static int __access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
+{
+ struct mm_struct *mm;
+ struct vm_area_struct *vma;
+ struct page *page;
+ void *old_buf = buf;
+
+ mm = get_task_mm(tsk);
+ if (!mm)
+ return 0;
+
+ down_read(&mm->mmap_sem);
+ /* ignore errors, just check how much was sucessfully transfered */
+ while (len) {
+ int bytes, ret, offset;
+ void *maddr;
+
+ ret = get_user_pages(tsk, mm, addr, 1,
+ write, 1, &page, &vma);
+ if (ret <= 0)
+ break;
+
+ bytes = len;
+ offset = addr & (PAGE_SIZE-1);
+ if (bytes > PAGE_SIZE-offset)
+ bytes = PAGE_SIZE-offset;
+
+ maddr = kmap(page);
+ if (write) {
+ copy_to_user_page(vma, page, addr,
+ maddr + offset, buf, bytes);
+ set_page_dirty_lock(page);
+ } else {
+ copy_from_user_page(vma, page, addr,
+ buf, maddr + offset, bytes);
+ }
+ kunmap(page);
+ page_cache_release(page);
+ len -= bytes;
+ buf += bytes;
+ addr += bytes;
+ }
+ up_read(&mm->mmap_sem);
+ mmput(mm);
+
+ return buf - old_buf;
+}
+#endif
#include "uprobes_arch.c"
MODULE_LICENSE("GPL");