summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--buildrun.cxx6
-rw-r--r--runtime/ChangeLog8
-rw-r--r--runtime/autoconf-probe-kernel.c7
-rw-r--r--runtime/loc2c-runtime.h125
5 files changed, 120 insertions, 38 deletions
diff --git a/ChangeLog b/ChangeLog
index 0db1ca55..cb786d0e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-05-27 Josh Stone <joshua.i.stone@intel.com>
+
+ PR 6432
+ * buildrun.cxx (compile_pass): Add the autoconf test for probe_kernel_*
+ functions, but leave it #if-0'ed for now.
+
2008-05-23 Jim Keniston <jkenisto@us.ibm.com>
PR 4311, cont. Address powerpc dwarfless test failures.
@@ -6,9 +12,9 @@
that map to sys_ni_syscall.
2008-05-23 Srinivasa DS <srinivasa@in.ibm.com>
- PR 6429: Inerim fix to avoid compilation error of systemtap module
- * runtime/transport/symbols.c: added definitions of struct
- module_sect_attr, struct module_sect_attrs for 2.6.25 above kernels.
+ PR 6429: Inerim fix to avoid compilation error of systemtap module
+ * runtime/transport/symbols.c: added definitions of struct
+ module_sect_attr, struct module_sect_attrs for 2.6.25 above kernels.
2008-05-22 Wenji Huang <wenji.huang@oracle.com>
diff --git a/buildrun.cxx b/buildrun.cxx
index 76efe7c0..a39f2b63 100644
--- a/buildrun.cxx
+++ b/buildrun.cxx
@@ -96,6 +96,12 @@ compile_pass (systemtap_session& s)
o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-nameidata.c, -DSTAPCONF_NAMEIDATA_CLEANUP,)" << endl;
o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-unregister-kprobes.c, -DSTAPCONF_UNREGISTER_KPROBES,)" << endl;
o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-module-nsections.c, -DSTAPCONF_MODULE_NSECTIONS,)" << endl;
+#if 0
+ /* NB: For now, the performance hit of probe_kernel_read/write (vs. our
+ * homegrown safe-access functions) is deemed undesireable, so we'll skip
+ * this autoconf. */
+ o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-probe-kernel.c, -DSTAPCONF_PROBE_KERNEL,)" << endl;
+#endif
for (unsigned i=0; i<s.macros.size(); i++)
o << "EXTRA_CFLAGS += -D " << lex_cast_qstring(s.macros[i]) << endl;
diff --git a/runtime/ChangeLog b/runtime/ChangeLog
index bdf6e56d..3d506a18 100644
--- a/runtime/ChangeLog
+++ b/runtime/ChangeLog
@@ -1,3 +1,11 @@
+2008-05-27 Josh Stone <joshua.i.stone@intel.com>
+
+ PR 6432
+ * loc2c-runtime.h (kread, kwrite, deref, store_deref): Add
+ architecture-neutral implementations, using probe_kernel_*
+ facilites (controlled by autoconf).
+ * autoconf-probe-kernel.c: test for above.
+
2008-05-16 David Smith <dsmith@redhat.com>
PR 6499.
diff --git a/runtime/autoconf-probe-kernel.c b/runtime/autoconf-probe-kernel.c
new file mode 100644
index 00000000..93fbaae6
--- /dev/null
+++ b/runtime/autoconf-probe-kernel.c
@@ -0,0 +1,7 @@
+#include <linux/uaccess.h>
+
+void probe_kernel(void *dst, void *src, size_t size)
+{
+ (void)probe_kernel_read(dst, src, size);
+ (void)probe_kernel_write(dst, src, size);
+}
diff --git a/runtime/loc2c-runtime.h b/runtime/loc2c-runtime.h
index 66fd1e43..a7472691 100644
--- a/runtime/loc2c-runtime.h
+++ b/runtime/loc2c-runtime.h
@@ -9,6 +9,7 @@
* later version.
*/
+#include <linux/uaccess.h>
#include <linux/types.h>
#define intptr_t long
#define uintptr_t unsigned long
@@ -31,9 +32,6 @@
<< (sizeof (base) * 8 - (higherbits) - (nbits))))
-/* These operations are target-specific. */
-#include <asm/uaccess.h>
-
/* Given a DWARF register number, fetch its intptr_t (long) value from the
probe context, or store a new value into the probe context.
@@ -173,6 +171,61 @@
#endif
+
+/* NB: this autoconf is always disabled, pending further performance eval. */
+#if defined STAPCONF_PROBE_KERNEL
+
+/* Kernel 2.6.26 adds probe_kernel_{read,write}, which lets us write
+ * architecture-neutral implementations of kread, kwrite, deref, and
+ * store_deref.
+ *
+ * NB: deref and store_deref shouldn't be used with 64-bit values on 32-bit
+ * platforms, because they will lose data in the conversion to intptr_t. We
+ * generally want to encourage using kread and kwrite instead.
+ */
+
+#define kread(ptr) ({ \
+ typeof(*(ptr)) _v; \
+ if (probe_kernel_read((void *)&_v, (void *)(ptr), sizeof(*(ptr)))) \
+ DEREF_FAULT(ptr); \
+ _v; \
+ })
+
+#define kwrite(ptr, value) ({ \
+ typeof(*(ptr)) _v; \
+ _v = (typeof(*(ptr)))(value); \
+ if (probe_kernel_write((void *)(ptr), (void *)&_v, sizeof(*(ptr)))) \
+ STORE_DEREF_FAULT(ptr); \
+ })
+
+#define deref(size, addr) ({ \
+ intptr_t _i; \
+ switch (size) { \
+ case 1: _i = kread((u8 *)(addr)); break; \
+ case 2: _i = kread((u16 *)(addr)); break; \
+ case 4: _i = kread((u32 *)(addr)); break; \
+ case 8: _i = kread((u64 *)(addr)); break; \
+ default: __deref_bad(); \
+ /* uninitialized _i should also be caught by -Werror */ \
+ } \
+ _i; \
+ })
+
+#define store_deref(size, addr, value) ({ \
+ switch (size) { \
+ case 1: kwrite((u8 *)(addr), (value)); break; \
+ case 2: kwrite((u16 *)(addr), (value)); break; \
+ case 4: kwrite((u32 *)(addr), (value)); break; \
+ case 8: kwrite((u64 *)(addr), (value)); break; \
+ default: __store_deref_bad(); \
+ } \
+ })
+
+extern void __deref_bad(void);
+extern void __store_deref_bad(void);
+
+#else /* !STAPCONF_PROBE_KERNEL */
+
#if defined __i386__
#define deref(size, addr) \
@@ -614,38 +667,6 @@
#endif /* (s390) || (s390x) */
-#define deref_string(dst, addr, maxbytes) \
- ({ \
- uintptr_t _addr; \
- size_t _len; \
- unsigned char _c; \
- char *_d = (dst); \
- for (_len = (maxbytes), _addr = (uintptr_t)(addr); \
- _len > 1 && (_c = deref (1, _addr)) != '\0'; \
- --_len, ++_addr) \
- if (_d) \
- *_d++ = _c; \
- if (_d) \
- *_d = '\0'; \
- (dst); \
- })
-
-#define deref_buffer(dst, addr, numbytes) \
- ({ \
- uintptr_t _addr; \
- size_t _len; \
- unsigned char _c; \
- char *_d = (dst); \
- for (_len = (numbytes), _addr = (uintptr_t)(addr); \
- _len >= 1; \
- --_len, ++_addr) { \
- _c = deref (1, _addr); \
- if (_d) \
- *_d++ = _c; \
- } \
- (dst); \
- })
-
#if defined __i386__
@@ -678,6 +699,40 @@
#endif
+#endif /* STAPCONF_PROBE_KERNEL */
+
+#define deref_string(dst, addr, maxbytes) \
+ ({ \
+ uintptr_t _addr; \
+ size_t _len; \
+ unsigned char _c; \
+ char *_d = (dst); \
+ for (_len = (maxbytes), _addr = (uintptr_t)(addr); \
+ _len > 1 && (_c = deref (1, _addr)) != '\0'; \
+ --_len, ++_addr) \
+ if (_d) \
+ *_d++ = _c; \
+ if (_d) \
+ *_d = '\0'; \
+ (dst); \
+ })
+
+#define deref_buffer(dst, addr, numbytes) \
+ ({ \
+ uintptr_t _addr; \
+ size_t _len; \
+ unsigned char _c; \
+ char *_d = (dst); \
+ for (_len = (numbytes), _addr = (uintptr_t)(addr); \
+ _len >= 1; \
+ --_len, ++_addr) { \
+ _c = deref (1, _addr); \
+ if (_d) \
+ *_d++ = _c; \
+ } \
+ (dst); \
+ })
+
#define CATCH_DEREF_FAULT() \
if (0) { \
deref_fault: ; \