diff options
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | buildrun.cxx | 6 | ||||
-rw-r--r-- | runtime/ChangeLog | 8 | ||||
-rw-r--r-- | runtime/autoconf-probe-kernel.c | 7 | ||||
-rw-r--r-- | runtime/loc2c-runtime.h | 125 |
5 files changed, 120 insertions, 38 deletions
@@ -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: ; \ |