ruby-dtrace 0.2.8 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -0
- data/README.txt +4 -5
- data/examples/scsi.rb +0 -0
- data/ext/dof/Makefile +34 -31
- data/ext/dof/parser.c +1 -1
- data/ext/dof/section.c +2 -2
- data/ext/dtrace_hdl.c +5 -2
- data/ext/dtrace_probe.c +10 -0
- data/ext/extconf.rb +58 -15
- data/ext/i386-darwin/dtrace_probe.c +3 -3
- data/ext/powerpc-darwin/dtrace_probe.c +470 -0
- data/ext/sparc-solaris/dtrace_probe.c +586 -0
- data/ext/x86_64-darwin/dtrace_probe.c +177 -0
- data/ext/x86_64-solaris/dtrace_probe.c +159 -0
- data/lib/dtrace/version.rb +2 -2
- data/plugin/dtrace/bin/dtracer.rb +0 -0
- data/test/test_dof_providers.rb +6 -2
- data/test/test_dof_strtabs.rb +3 -1
- data/test/test_dtrace_probe.rb +6 -2
- data/test/test_dtrace_probes.rb +8 -63
- metadata +25 -29
- data/ext/dof/mkmf.log +0 -10
- data/ext/stubs.txt +0 -78
- data/test/apple-dof +0 -0
- data/test/disabled_probe_effect.txt +0 -19
- data/test/dof +0 -0
- data/test/dof2 +0 -0
data/History.txt
CHANGED
data/README.txt
CHANGED
@@ -63,12 +63,11 @@ Probes: see Dtrace::Provider
|
|
63
63
|
== REQUIREMENTS
|
64
64
|
|
65
65
|
* For the consumer API, platform with DTrace support (OpenSolaris, Mac
|
66
|
-
OS X 10.5 Leopard tested, possibly also FreeBSD).
|
66
|
+
OS X 10.5 Leopard and 10.6 Snow Leopard tested, possibly also FreeBSD).
|
67
67
|
|
68
68
|
* For the probe API, a platform with DTrace support (as for the
|
69
|
-
consumer API), with a 32 bit Ruby build - i386,
|
70
|
-
and SPARC (for Solaris) are all supported.
|
71
|
-
yet.
|
69
|
+
consumer API), with a 32 bit or 64 bit Ruby build - i386/x86_64,
|
70
|
+
PowerPC (for OS X) and SPARC (for Solaris) are all supported.
|
72
71
|
|
73
72
|
* root, or some/all of the dtrace privileges on Solaris: dtrace_user,
|
74
73
|
dtrace_proc and dtrace_kernel.
|
@@ -79,7 +78,7 @@ Probes: see Dtrace::Provider
|
|
79
78
|
|
80
79
|
== LICENSE
|
81
80
|
|
82
|
-
Copyright (c) 2008, 2009 Chris Andrews <chris@nodnol.org>
|
81
|
+
Copyright (c) 2008, 2009, 2011 Chris Andrews <chris@nodnol.org>
|
83
82
|
|
84
83
|
Permission is hereby granted, free of charge, to any person obtaining
|
85
84
|
a copy of this software and associated documentation files (the
|
data/examples/scsi.rb
CHANGED
File without changes
|
data/ext/dof/Makefile
CHANGED
@@ -4,63 +4,65 @@ SHELL = /bin/sh
|
|
4
4
|
#### Start of system configuration section. ####
|
5
5
|
|
6
6
|
srcdir = .
|
7
|
-
topdir = /
|
7
|
+
topdir = /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin10.0
|
8
8
|
hdrdir = $(topdir)
|
9
9
|
VPATH = $(srcdir):$(topdir):$(hdrdir)
|
10
|
-
prefix = $(DESTDIR)/opt/local
|
11
10
|
exec_prefix = $(prefix)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
dvidir = $(docdir)
|
16
|
-
datarootdir = $(prefix)/share
|
17
|
-
archdir = $(rubylibdir)/$(arch)
|
18
|
-
sbindir = $(exec_prefix)/sbin
|
11
|
+
prefix = $(DESTDIR)/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr
|
12
|
+
sharedstatedir = $(prefix)/com
|
13
|
+
mandir = $(DESTDIR)/usr/share/man
|
19
14
|
psdir = $(docdir)
|
20
|
-
|
15
|
+
oldincludedir = $(DESTDIR)/usr/include
|
21
16
|
localedir = $(datarootdir)/locale
|
17
|
+
bindir = $(exec_prefix)/bin
|
18
|
+
libexecdir = $(exec_prefix)/libexec
|
19
|
+
sitedir = $(DESTDIR)/Library/Ruby/Site
|
22
20
|
htmldir = $(docdir)
|
23
|
-
|
21
|
+
vendorarchdir = $(vendorlibdir)/$(sitearch)
|
24
22
|
includedir = $(prefix)/include
|
25
|
-
infodir = $(
|
23
|
+
infodir = $(DESTDIR)/usr/share/info
|
24
|
+
vendorlibdir = $(vendordir)/$(ruby_version)
|
26
25
|
sysconfdir = $(prefix)/etc
|
27
26
|
libdir = $(exec_prefix)/lib
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
sbindir = $(exec_prefix)/sbin
|
28
|
+
rubylibdir = $(libdir)/ruby/$(ruby_version)
|
29
|
+
docdir = $(datarootdir)/doc/$(PACKAGE)
|
30
|
+
dvidir = $(docdir)
|
31
|
+
vendordir = $(libdir)/ruby/vendor_ruby
|
32
|
+
datarootdir = $(prefix)/share
|
31
33
|
pdfdir = $(docdir)
|
34
|
+
archdir = $(rubylibdir)/$(arch)
|
32
35
|
sitearchdir = $(sitelibdir)/$(sitearch)
|
33
|
-
|
36
|
+
datadir = $(datarootdir)
|
34
37
|
localstatedir = $(prefix)/var
|
35
|
-
bindir = $(exec_prefix)/bin
|
36
|
-
vendorlibdir = $(vendordir)/$(ruby_version)
|
37
38
|
sitelibdir = $(sitedir)/$(ruby_version)
|
38
|
-
libexecdir = $(exec_prefix)/libexec
|
39
39
|
|
40
|
-
CC =
|
40
|
+
CC = gcc
|
41
41
|
LIBRUBY = $(LIBRUBY_SO)
|
42
42
|
LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
|
43
43
|
LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
|
44
|
-
LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)
|
44
|
+
LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)
|
45
45
|
|
46
46
|
RUBY_EXTCONF_H =
|
47
|
-
CFLAGS = -fno-common -
|
47
|
+
CFLAGS = -fno-common -arch i386 -arch x86_64 -g -Os -pipe -fno-common -DENABLE_DTRACE -fno-common -pipe -fno-common $(cflags) -D_LONGLONG_TYPE -g
|
48
48
|
INCFLAGS = -I. -I$(topdir) -I$(hdrdir) -I$(srcdir)
|
49
49
|
DEFS =
|
50
|
-
CPPFLAGS = -DHAVE_SYS_DTRACE_H -
|
50
|
+
CPPFLAGS = -DHAVE_SYS_DTRACE_H -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE $(DEFS) $(cppflags)
|
51
51
|
CXXFLAGS = $(CFLAGS)
|
52
|
-
|
53
|
-
|
52
|
+
ldflags = -L. -arch i386 -arch x86_64
|
53
|
+
dldflags =
|
54
|
+
archflag =
|
55
|
+
DLDFLAGS = $(ldflags) $(dldflags) $(archflag)
|
56
|
+
LDSHARED = cc -arch i386 -arch x86_64 -pipe -bundle -undefined dynamic_lookup
|
54
57
|
AR = ar
|
55
58
|
EXEEXT =
|
56
59
|
|
57
60
|
RUBY_INSTALL_NAME = ruby
|
58
61
|
RUBY_SO_NAME = ruby
|
59
|
-
arch =
|
60
|
-
sitearch =
|
61
|
-
vendorarch = i686-darwin9.7.0
|
62
|
+
arch = universal-darwin10.0
|
63
|
+
sitearch = universal-darwin10.0
|
62
64
|
ruby_version = 1.8
|
63
|
-
ruby = /
|
65
|
+
ruby = /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
|
64
66
|
RUBY = $(ruby)
|
65
67
|
RM = rm -f
|
66
68
|
MAKEDIRS = mkdir -p
|
@@ -84,7 +86,7 @@ extout =
|
|
84
86
|
extout_prefix =
|
85
87
|
target_prefix =
|
86
88
|
LOCAL_LIBS =
|
87
|
-
LIBS = $(LIBRUBYARG_SHARED) -lpthread -ldl
|
89
|
+
LIBS = $(LIBRUBYARG_SHARED) -lpthread -ldl
|
88
90
|
SRCS = constants.c dof_api.c dof_helper.c file.c generator.c header.c parser.c section.c
|
89
91
|
OBJS = constants.o dof_api.o dof_helper.o file.o generator.o header.o parser.o section.o
|
90
92
|
TARGET = dof_api
|
@@ -92,6 +94,7 @@ DLLIB = $(TARGET).bundle
|
|
92
94
|
EXTSTATIC =
|
93
95
|
STATIC_LIB =
|
94
96
|
|
97
|
+
BINDIR = $(bindir)
|
95
98
|
RUBYCOMMONDIR = $(sitedir)$(target_prefix)
|
96
99
|
RUBYLIBDIR = $(sitelibdir)$(target_prefix)
|
97
100
|
RUBYARCHDIR = $(sitearchdir)$(target_prefix)
|
@@ -145,7 +148,7 @@ site-install-rb: install-rb
|
|
145
148
|
.c.o:
|
146
149
|
$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $<
|
147
150
|
|
148
|
-
$(DLLIB): $(OBJS)
|
151
|
+
$(DLLIB): $(OBJS)
|
149
152
|
@-$(RM) $@
|
150
153
|
$(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
|
151
154
|
|
data/ext/dof/parser.c
CHANGED
@@ -145,7 +145,7 @@ _dof_parse_dof_probe_t_array(VALUE self, char *dof, dof_sec_t *sec)
|
|
145
145
|
count++;
|
146
146
|
|
147
147
|
probe_data = rb_hash_new();
|
148
|
-
sprintf(addr_str, "%p", probe.dofpr_addr);
|
148
|
+
sprintf(addr_str, "%p", (void *)probe.dofpr_addr);
|
149
149
|
rb_hash_aset(probe_data, ID2SYM(rb_intern("addr")), rb_str_new2(addr_str));
|
150
150
|
rb_hash_aset(probe_data, ID2SYM(rb_intern("func")), rb_hash_aref(strtab, INT2FIX(probe.dofpr_func)));
|
151
151
|
rb_hash_aset(probe_data, ID2SYM(rb_intern("name")), rb_hash_aref(strtab, INT2FIX(probe.dofpr_name)));
|
data/ext/dof/section.c
CHANGED
@@ -69,12 +69,12 @@ VALUE dof_generate_probes(VALUE self) {
|
|
69
69
|
dof_probe_t p;
|
70
70
|
memset(&p, 0, sizeof(p));
|
71
71
|
|
72
|
-
p.dofpr_addr = (uint64_t)
|
72
|
+
p.dofpr_addr = (uint64_t)NUM2LL(rb_hash_aref(probe, ID2SYM(rb_intern("addr"))));
|
73
73
|
p.dofpr_func = (dof_stridx_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("func"))));
|
74
74
|
p.dofpr_name = (dof_stridx_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("name"))));
|
75
75
|
p.dofpr_nargv = (dof_stridx_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("nargv"))));
|
76
76
|
p.dofpr_xargv = (dof_stridx_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("xargv"))));
|
77
|
-
|
77
|
+
|
78
78
|
p.dofpr_argidx = (uint32_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("argidx"))));
|
79
79
|
p.dofpr_offidx = (uint32_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("offidx"))));
|
80
80
|
p.dofpr_nargc = (uint8_t)FIX2INT(rb_hash_aref(probe, ID2SYM(rb_intern("nargc"))));
|
data/ext/dtrace_hdl.c
CHANGED
@@ -77,7 +77,7 @@ VALUE dtrace_hdl_alloc(VALUE klass)
|
|
77
77
|
return obj;
|
78
78
|
}
|
79
79
|
else {
|
80
|
-
rb_raise(eDtraceException, "unable to open dtrace (not root?)");
|
80
|
+
rb_raise(eDtraceException, "unable to open dtrace: %s (not root?)", strerror(err));
|
81
81
|
}
|
82
82
|
}
|
83
83
|
|
@@ -440,7 +440,10 @@ VALUE dtrace_hdl_work(int argc, VALUE *argv, VALUE self)
|
|
440
440
|
handlers.rec = rec_consumer;
|
441
441
|
handlers.handle = self;
|
442
442
|
|
443
|
-
|
443
|
+
FILE *devnull = fopen("/dev/null", "w");
|
444
|
+
status = dtrace_work(handle->hdl, devnull, _probe_consumer, _rec_consumer, &handlers);
|
445
|
+
fclose(devnull);
|
446
|
+
|
444
447
|
if (status < 0)
|
445
448
|
rb_raise(eDtraceException, (dtrace_errmsg(handle->hdl, dtrace_errno(handle->hdl))));
|
446
449
|
|
data/ext/dtrace_probe.c
ADDED
data/ext/extconf.rb
CHANGED
@@ -1,29 +1,72 @@
|
|
1
1
|
require 'mkmf'
|
2
2
|
require 'rbconfig'
|
3
3
|
|
4
|
-
|
5
|
-
begin
|
6
|
-
File.symlink(old, new)
|
7
|
-
rescue Errno::EEXIST
|
8
|
-
File.unlink(new)
|
9
|
-
retry
|
10
|
-
end
|
11
|
-
end
|
4
|
+
$CFLAGS += " -D_LONGLONG_TYPE"
|
12
5
|
|
13
|
-
|
14
|
-
|
6
|
+
# Need to specify full path to dtrace.h or we'll pick up ruby's
|
7
|
+
# dtrace.h on Solaris or other builds with the runtime probes included.
|
8
|
+
have_library("dtrace", "dtrace_open", "/usr/include/dtrace.h")
|
15
9
|
|
16
|
-
#
|
10
|
+
# Figure out target platform
|
17
11
|
os = Config::CONFIG['target_os']
|
18
12
|
os.gsub! /[0-9.]+$/, ''
|
19
13
|
|
20
|
-
#
|
21
|
-
#cpu = Config::CONFIG['target_cpu']
|
14
|
+
# Snow Leopard handling: detect Universal build and invoke dual build of dtrace_probe.c
|
22
15
|
cpu = `uname -p`.chomp
|
16
|
+
if cpu == "i386"
|
17
|
+
ldflags = Config::CONFIG['LDFLAGS']
|
18
|
+
if ldflags =~ /i386/ && ldflags =~ /x86_64/
|
19
|
+
puts "Universal build detected"
|
20
|
+
apple_universal = true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
arch = "#{cpu}-#{os}"
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
+
# Set up generated Makefile to build everything except dtrace_probe.c
|
27
|
+
$srcs = %w{ dtrace_aggdata.c
|
28
|
+
dtrace_dropdata.c
|
29
|
+
dtrace_process.c
|
30
|
+
dtrace_recdesc.c
|
31
|
+
dtrace_api.c
|
32
|
+
dtrace_errdata.c
|
33
|
+
dtrace_probedata.c
|
34
|
+
dtrace_program.c
|
35
|
+
dtrace_util.c
|
36
|
+
dtrace_bufdata.c
|
37
|
+
dtrace_hdl.c
|
38
|
+
dtrace_probedesc.c
|
39
|
+
dtrace_programinfo.c
|
40
|
+
}
|
41
|
+
|
42
|
+
$objs = []
|
43
|
+
for f in $srcs
|
44
|
+
obj = File.basename(f, ".*") << ".o"
|
45
|
+
$objs.push(obj)
|
46
|
+
end
|
47
|
+
|
48
|
+
$objs.push "dtrace_probe.o"
|
26
49
|
|
27
50
|
# Create makefile in the usual way
|
28
51
|
create_makefile("dtrace_api")
|
29
52
|
|
53
|
+
# Then append rule(s) to create dtrace_probe.c
|
54
|
+
begin
|
55
|
+
mfile = open("Makefile", "ab")
|
56
|
+
mfile.puts
|
57
|
+
|
58
|
+
if apple_universal
|
59
|
+
# create i386 .o and x86_64.o
|
60
|
+
mfile.print "dtrace_probe_i386-darwin.o:\n\t$(CC) $(INCFLAGS) -arch i386 -o dtrace_probe_i386-darwin.o -c i386-darwin/dtrace_probe.c\n\n"
|
61
|
+
mfile.print "dtrace_probe_x86_64-darwin.o:\n\t$(CC) $(INCFLAGS) -arch x86_64 -o dtrace_probe_x86_64-darwin.o -c x86_64-darwin/dtrace_probe.c\n\n"
|
62
|
+
|
63
|
+
# link those into a universal dtrace_probe.o
|
64
|
+
mfile.print "dtrace_probe.o: dtrace_probe_i386-darwin.o dtrace_probe_x86_64-darwin.o\n" +
|
65
|
+
"\tlipo -create -output dtrace_probe.o dtrace_probe_x86_64-darwin.o dtrace_probe_i386-darwin.o"
|
66
|
+
else
|
67
|
+
# just selected arch
|
68
|
+
mfile.print "dtrace_probe.o:\n\t$(CC) $(INCFLAGS) $(CXXFLAGS) -c #{arch}/dtrace_probe.c\n\n"
|
69
|
+
end
|
70
|
+
ensure
|
71
|
+
mfile.close
|
72
|
+
end
|
@@ -250,8 +250,8 @@ VALUE dtraceprobe_probe_offset(VALUE self, VALUE file_addr, VALUE argc)
|
|
250
250
|
{
|
251
251
|
void *probe_addr;
|
252
252
|
int offset;
|
253
|
-
probe_addr = (void *)
|
254
|
-
switch FIX2INT(argc) {
|
253
|
+
probe_addr = (void *)FIX2UINT(rb_funcall(self, rb_intern("addr"), 0));
|
254
|
+
switch (FIX2INT(argc)) {
|
255
255
|
case 0:
|
256
256
|
offset = 40; /* 32 + 6 + 2 */
|
257
257
|
break;
|
@@ -262,7 +262,7 @@ VALUE dtraceprobe_probe_offset(VALUE self, VALUE file_addr, VALUE argc)
|
|
262
262
|
offset = 46 + (FIX2INT(argc)-1) * 7; /* 32 + 6 + 6 + 7 per subsequent arg + 2 */
|
263
263
|
break;
|
264
264
|
}
|
265
|
-
return INT2FIX((
|
265
|
+
return INT2FIX((uint32_t)probe_addr - (uint32_t)FIX2UINT(file_addr) + offset);
|
266
266
|
}
|
267
267
|
|
268
268
|
/*
|
@@ -0,0 +1,470 @@
|
|
1
|
+
/* Ruby-Dtrace
|
2
|
+
* (c) 2008 Chris Andrews <chris@nodnol.org>
|
3
|
+
*/
|
4
|
+
|
5
|
+
#include "dtrace_api.h"
|
6
|
+
|
7
|
+
#include <errno.h>
|
8
|
+
#include <stdlib.h>
|
9
|
+
#include <sys/mman.h>
|
10
|
+
|
11
|
+
RUBY_EXTERN VALUE eDtraceException;
|
12
|
+
|
13
|
+
#define FUNC_SIZE 256
|
14
|
+
#define IS_ENABLED_FUNC_LEN 32
|
15
|
+
|
16
|
+
void install_insns(uint8_t *probe_insns, uint8_t *insns, int count)
|
17
|
+
{
|
18
|
+
int i,j;
|
19
|
+
uint8_t *ip;
|
20
|
+
ip = insns;
|
21
|
+
for (j = 1; j <= count; j++) {
|
22
|
+
for (i = 0; i < 4; i++) {
|
23
|
+
*ip++ = *probe_insns++;
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
/* :nodoc: */
|
29
|
+
VALUE dtraceprobe_init(VALUE self, VALUE rargc)
|
30
|
+
{
|
31
|
+
dtrace_probe_t *probe;
|
32
|
+
uint8_t *ip;
|
33
|
+
int i;
|
34
|
+
int argc = FIX2INT(rargc);
|
35
|
+
uint8_t probe_insns[FUNC_SIZE];
|
36
|
+
|
37
|
+
Data_Get_Struct(self, dtrace_probe_t, probe);
|
38
|
+
|
39
|
+
/* First initialise the is_enabled tracepoint */
|
40
|
+
uint8_t insns[FUNC_SIZE] = {
|
41
|
+
/* stmw r30,0xfff8(r1) */
|
42
|
+
0xbf, 0xc1, 0xff, 0xf8,
|
43
|
+
/* stwu r1,0xffd0(r1) */
|
44
|
+
0x94, 0x21, 0xff, 0xd0,
|
45
|
+
/* or r30,r1,r1 */
|
46
|
+
0x7c, 0x3e, 0x0b, 0x78,
|
47
|
+
/* li r0,0x0 */
|
48
|
+
0x38, 0x00, 0x00, 0x00,
|
49
|
+
/* or r3,r0,r0 */
|
50
|
+
0x7c, 0x03, 0x03, 0x78,
|
51
|
+
/* lwz r1,0x0(r1) */
|
52
|
+
0x80, 0x21, 0x00, 0x00,
|
53
|
+
/* lmw r30,0xfff8(r1) */
|
54
|
+
0xbb, 0xc1, 0xff, 0xf8,
|
55
|
+
/* blr */
|
56
|
+
0x4e, 0x80, 0x00, 0x20
|
57
|
+
};
|
58
|
+
|
59
|
+
/* Now build probe tracepoint */
|
60
|
+
switch (argc) {
|
61
|
+
|
62
|
+
case 0:
|
63
|
+
{
|
64
|
+
uint8_t probe_insns[FUNC_SIZE] = {
|
65
|
+
/* stmw r30,0xfff8(r1) */
|
66
|
+
0xbf, 0xc1, 0xff, 0xf8,
|
67
|
+
/* stwu r1,0xffd0(r1) */
|
68
|
+
0x94, 0x21, 0xff, 0xd0,
|
69
|
+
/* or r30,r1,r1 */
|
70
|
+
0x7c, 0x3e, 0x0b, 0x78,
|
71
|
+
/* lwz r1,0x0(r1) */
|
72
|
+
0x80, 0x21, 0x00, 0x00,
|
73
|
+
/* lmw r30,0xfff8(r1) */
|
74
|
+
0xbb, 0xc1, 0xff, 0xf8,
|
75
|
+
/* blr */
|
76
|
+
0x4e, 0x80, 0x00, 0x20
|
77
|
+
};
|
78
|
+
install_insns(probe_insns, &insns[IS_ENABLED_FUNC_LEN], 6);
|
79
|
+
}
|
80
|
+
break;
|
81
|
+
|
82
|
+
case 1:
|
83
|
+
{
|
84
|
+
uint8_t probe_insns[FUNC_SIZE] = {
|
85
|
+
/* stmw r30,0xfff8(r1) */
|
86
|
+
0xbf, 0xc1, 0xff, 0xf8,
|
87
|
+
/* stwu r1,0xffd0(r1) */
|
88
|
+
0x94, 0x21, 0xff, 0xd0,
|
89
|
+
/* or r30,r1,r1 */
|
90
|
+
0x7c, 0x3e, 0x0b, 0x78,
|
91
|
+
/* stw r3,0x48(r30) */
|
92
|
+
0x90, 0x7e, 0x00, 0x48,
|
93
|
+
/* lwz r1,0x0(r1) */
|
94
|
+
0x80, 0x21, 0x00, 0x00,
|
95
|
+
/* lmw r30,0xfff8(r1) */
|
96
|
+
0xbb, 0xc1, 0xff, 0xf8,
|
97
|
+
/* blr */
|
98
|
+
0x4e, 0x80, 0x00, 0x20
|
99
|
+
};
|
100
|
+
install_insns(probe_insns, &insns[IS_ENABLED_FUNC_LEN], 7);
|
101
|
+
}
|
102
|
+
break;
|
103
|
+
|
104
|
+
case 2:
|
105
|
+
{
|
106
|
+
uint8_t probe_insns[FUNC_SIZE] = {
|
107
|
+
/* stmw r30,0xfff8(r1) */
|
108
|
+
0xbf, 0xc1, 0xff, 0xf8,
|
109
|
+
/* stwu r1,0xffd0(r1) */
|
110
|
+
0x94, 0x21, 0xff, 0xd0,
|
111
|
+
/* or r30,r1,r1 */
|
112
|
+
0x7c, 0x3e, 0x0b, 0x78,
|
113
|
+
/* stw r3,0x48(r30) */
|
114
|
+
0x90, 0x7e, 0x00, 0x48,
|
115
|
+
/* stw r4,0x4c(r30) */
|
116
|
+
0x90, 0x9e, 0x00, 0x4c,
|
117
|
+
/* lwz r1,0x0(r1) */
|
118
|
+
0x80, 0x21, 0x00, 0x00,
|
119
|
+
/* lmw r30,0xfff8(r1) */
|
120
|
+
0xbb, 0xc1, 0xff, 0xf8,
|
121
|
+
/* blr */
|
122
|
+
0x4e, 0x80, 0x00, 0x20
|
123
|
+
};
|
124
|
+
install_insns(probe_insns, &insns[IS_ENABLED_FUNC_LEN], 8);
|
125
|
+
}
|
126
|
+
break;
|
127
|
+
|
128
|
+
case 3:
|
129
|
+
{
|
130
|
+
uint8_t probe_insns[FUNC_SIZE] = {
|
131
|
+
/* stmw r30,0xfff8(r1) */
|
132
|
+
0xbf, 0xc1, 0xff, 0xf8,
|
133
|
+
/* stwu r1,0xffd0(r1) */
|
134
|
+
0x94, 0x21, 0xff, 0xd0,
|
135
|
+
/* or r30,r1,r1 */
|
136
|
+
0x7c, 0x3e, 0x0b, 0x78,
|
137
|
+
/* stw r3,0x48(r30) */
|
138
|
+
0x90, 0x7e, 0x00, 0x48,
|
139
|
+
/* stw r4,0x4c(r30) */
|
140
|
+
0x90, 0x9e, 0x00, 0x4c,
|
141
|
+
/* stw r5,0x50(r30) */
|
142
|
+
0x90, 0xbe, 0x00, 0x50,
|
143
|
+
/* lwz r1,0x0(r1) */
|
144
|
+
0x80, 0x21, 0x00, 0x00,
|
145
|
+
/* lmw r30,0xfff8(r1) */
|
146
|
+
0xbb, 0xc1, 0xff, 0xf8,
|
147
|
+
/* blr */
|
148
|
+
0x4e, 0x80, 0x00, 0x20
|
149
|
+
};
|
150
|
+
install_insns(probe_insns, &insns[IS_ENABLED_FUNC_LEN], 9);
|
151
|
+
}
|
152
|
+
break;
|
153
|
+
|
154
|
+
case 4:
|
155
|
+
{
|
156
|
+
uint8_t probe_insns[FUNC_SIZE] = {
|
157
|
+
/* stmw r30,0xfff8(r1) */
|
158
|
+
0xbf, 0xc1, 0xff, 0xf8,
|
159
|
+
/* stwu r1,0xffd0(r1) */
|
160
|
+
0x94, 0x21, 0xff, 0xd0,
|
161
|
+
/* or r30,r1,r1 */
|
162
|
+
0x7c, 0x3e, 0x0b, 0x78,
|
163
|
+
/* stw r3,0x48(r30) */
|
164
|
+
0x90, 0x7e, 0x00, 0x48,
|
165
|
+
/* stw r4,0x4c(r30) */
|
166
|
+
0x90, 0x9e, 0x00, 0x4c,
|
167
|
+
/* stw r5,0x50(r30) */
|
168
|
+
0x90, 0xbe, 0x00, 0x50,
|
169
|
+
/* stw r5,0x50(r30) */
|
170
|
+
0x90, 0xde, 0x00, 0x54,
|
171
|
+
/* lwz r1,0x0(r1) */
|
172
|
+
0x80, 0x21, 0x00, 0x00,
|
173
|
+
/* lmw r30,0xfff8(r1) */
|
174
|
+
0xbb, 0xc1, 0xff, 0xf8,
|
175
|
+
/* blr */
|
176
|
+
0x4e, 0x80, 0x00, 0x20
|
177
|
+
};
|
178
|
+
install_insns(probe_insns, &insns[IS_ENABLED_FUNC_LEN], 10);
|
179
|
+
}
|
180
|
+
break;
|
181
|
+
|
182
|
+
case 5:
|
183
|
+
{
|
184
|
+
uint8_t probe_insns[FUNC_SIZE] = {
|
185
|
+
/* stmw r30,0xfff8(r1) */
|
186
|
+
0xbf, 0xc1, 0xff, 0xf8,
|
187
|
+
/* stwu r1,0xffd0(r1) */
|
188
|
+
0x94, 0x21, 0xff, 0xd0,
|
189
|
+
/* or r30,r1,r1 */
|
190
|
+
0x7c, 0x3e, 0x0b, 0x78,
|
191
|
+
/* stw r3,0x48(r30) */
|
192
|
+
0x90, 0x7e, 0x00, 0x48,
|
193
|
+
/* stw r4,0x4c(r30) */
|
194
|
+
0x90, 0x9e, 0x00, 0x4c,
|
195
|
+
/* stw r5,0x50(r30) */
|
196
|
+
0x90, 0xbe, 0x00, 0x50,
|
197
|
+
/* stw r6,0x54(r30) */
|
198
|
+
0x90, 0xde, 0x00, 0x54,
|
199
|
+
/* stw r7,0x58(r30) */
|
200
|
+
0x90, 0xfe, 0x00, 0x58,
|
201
|
+
/* lwz r1,0x0(r1) */
|
202
|
+
0x80, 0x21, 0x00, 0x00,
|
203
|
+
/* lmw r30,0xfff8(r1) */
|
204
|
+
0xbb, 0xc1, 0xff, 0xf8,
|
205
|
+
/* blr */
|
206
|
+
0x4e, 0x80, 0x00, 0x20
|
207
|
+
};
|
208
|
+
install_insns(probe_insns, &insns[IS_ENABLED_FUNC_LEN], 11);
|
209
|
+
}
|
210
|
+
break;
|
211
|
+
|
212
|
+
case 6:
|
213
|
+
{
|
214
|
+
uint8_t probe_insns[FUNC_SIZE] = {
|
215
|
+
/* stmw r30,0xfff8(r1) */
|
216
|
+
0xbf, 0xc1, 0xff, 0xf8,
|
217
|
+
/* stwu r1,0xffd0(r1) */
|
218
|
+
0x94, 0x21, 0xff, 0xd0,
|
219
|
+
/* or r30,r1,r1 */
|
220
|
+
0x7c, 0x3e, 0x0b, 0x78,
|
221
|
+
/* stw r3,0x48(r30) */
|
222
|
+
0x90, 0x7e, 0x00, 0x48,
|
223
|
+
/* stw r4,0x4c(r30) */
|
224
|
+
0x90, 0x9e, 0x00, 0x4c,
|
225
|
+
/* stw r5,0x50(r30) */
|
226
|
+
0x90, 0xbe, 0x00, 0x50,
|
227
|
+
/* stw r6,0x54(r30) */
|
228
|
+
0x90, 0xde, 0x00, 0x54,
|
229
|
+
/* stw r7,0x58(r30) */
|
230
|
+
0x90, 0xfe, 0x00, 0x58,
|
231
|
+
/* stw r8,0x5c(r30) */
|
232
|
+
0x91, 0x1e, 0x00, 0x5c,
|
233
|
+
/* lwz r1,0x0(r1) */
|
234
|
+
0x80, 0x21, 0x00, 0x00,
|
235
|
+
/* lmw r30,0xfff8(r1) */
|
236
|
+
0xbb, 0xc1, 0xff, 0xf8,
|
237
|
+
/* blr */
|
238
|
+
0x4e, 0x80, 0x00, 0x20
|
239
|
+
};
|
240
|
+
install_insns(probe_insns, &insns[IS_ENABLED_FUNC_LEN], 12);
|
241
|
+
}
|
242
|
+
break;
|
243
|
+
|
244
|
+
case 7:
|
245
|
+
{
|
246
|
+
uint8_t probe_insns[FUNC_SIZE] = {
|
247
|
+
/* stmw r30,0xfff8(r1) */
|
248
|
+
0xbf, 0xc1, 0xff, 0xf8,
|
249
|
+
/* stwu r1,0xffd0(r1) */
|
250
|
+
0x94, 0x21, 0xff, 0xd0,
|
251
|
+
/* or r30,r1,r1 */
|
252
|
+
0x7c, 0x3e, 0x0b, 0x78,
|
253
|
+
/* stw r3,0x48(r30) */
|
254
|
+
0x90, 0x7e, 0x00, 0x48,
|
255
|
+
/* stw r4,0x4c(r30) */
|
256
|
+
0x90, 0x9e, 0x00, 0x4c,
|
257
|
+
/* stw r5,0x50(r30) */
|
258
|
+
0x90, 0xbe, 0x00, 0x50,
|
259
|
+
/* stw r6,0x54(r30) */
|
260
|
+
0x90, 0xde, 0x00, 0x54,
|
261
|
+
/* stw r7,0x58(r30) */
|
262
|
+
0x90, 0xfe, 0x00, 0x58,
|
263
|
+
/* stw r8,0x5c(r30) */
|
264
|
+
0x91, 0x1e, 0x00, 0x5c,
|
265
|
+
/* stw r9,0x60(r30) */
|
266
|
+
0x91, 0x3e, 0x00, 0x60,
|
267
|
+
/* lwz r1,0x0(r1) */
|
268
|
+
0x80, 0x21, 0x00, 0x00,
|
269
|
+
/* lmw r30,0xfff8(r1) */
|
270
|
+
0xbb, 0xc1, 0xff, 0xf8,
|
271
|
+
/* blr */
|
272
|
+
0x4e, 0x80, 0x00, 0x20
|
273
|
+
};
|
274
|
+
install_insns(probe_insns, &insns[IS_ENABLED_FUNC_LEN], 13);
|
275
|
+
}
|
276
|
+
break;
|
277
|
+
|
278
|
+
case 8:
|
279
|
+
{
|
280
|
+
uint8_t probe_insns[FUNC_SIZE] = {
|
281
|
+
/* stmw r30,0xfff8(r1) */
|
282
|
+
0xbf, 0xc1, 0xff, 0xf8,
|
283
|
+
/* stwu r1,0xffd0(r1) */
|
284
|
+
0x94, 0x21, 0xff, 0xd0,
|
285
|
+
/* or r30,r1,r1 */
|
286
|
+
0x7c, 0x3e, 0x0b, 0x78,
|
287
|
+
/* stw r3,0x48(r30) */
|
288
|
+
0x90, 0x7e, 0x00, 0x48,
|
289
|
+
/* stw r4,0x4c(r30) */
|
290
|
+
0x90, 0x9e, 0x00, 0x4c,
|
291
|
+
/* stw r5,0x50(r30) */
|
292
|
+
0x90, 0xbe, 0x00, 0x50,
|
293
|
+
/* stw r6,0x54(r30) */
|
294
|
+
0x90, 0xde, 0x00, 0x54,
|
295
|
+
/* stw r7,0x58(r30) */
|
296
|
+
0x90, 0xfe, 0x00, 0x58,
|
297
|
+
/* stw r8,0x5c(r30) */
|
298
|
+
0x91, 0x1e, 0x00, 0x5c,
|
299
|
+
/* stw r9,0x60(r30) */
|
300
|
+
0x91, 0x3e, 0x00, 0x60,
|
301
|
+
/* stw r10,0x64(r30) */
|
302
|
+
0x91, 0x5e, 0x00, 0x64,
|
303
|
+
/* lwz r1,0x0(r1) */
|
304
|
+
0x80, 0x21, 0x00, 0x00,
|
305
|
+
/* lmw r30,0xfff8(r1) */
|
306
|
+
0xbb, 0xc1, 0xff, 0xf8,
|
307
|
+
/* blr */
|
308
|
+
0x4e, 0x80, 0x00, 0x20
|
309
|
+
};
|
310
|
+
install_insns(probe_insns, &insns[IS_ENABLED_FUNC_LEN], 14);
|
311
|
+
}
|
312
|
+
break;
|
313
|
+
|
314
|
+
default:
|
315
|
+
rb_raise(eDtraceException, "probe argc max is 8");
|
316
|
+
return Qnil;
|
317
|
+
break;
|
318
|
+
}
|
319
|
+
|
320
|
+
/* allocate memory on a page boundary, for mprotect */
|
321
|
+
probe->func = (void *)valloc(FUNC_SIZE);
|
322
|
+
if (probe->func < 0) {
|
323
|
+
rb_raise(eDtraceException, "malloc failed: %s\n", strerror(errno));
|
324
|
+
return Qnil;
|
325
|
+
}
|
326
|
+
|
327
|
+
if ((mprotect((void *)probe->func, FUNC_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC)) < 0) {
|
328
|
+
rb_raise(eDtraceException, "mprotect failed: %s\n", strerror(errno));
|
329
|
+
return Qnil;
|
330
|
+
}
|
331
|
+
|
332
|
+
if ((memcpy(probe->func, insns, FUNC_SIZE)) < 0) {
|
333
|
+
rb_raise(eDtraceException, "memcpy failed: %s\n", strerror(errno));
|
334
|
+
return Qnil;
|
335
|
+
}
|
336
|
+
|
337
|
+
return self;
|
338
|
+
}
|
339
|
+
|
340
|
+
VALUE dtraceprobe_free(void *arg)
|
341
|
+
{
|
342
|
+
dtrace_probe_t *probe = (dtrace_probe_t *)arg;
|
343
|
+
|
344
|
+
if (probe) {
|
345
|
+
free(probe);
|
346
|
+
}
|
347
|
+
}
|
348
|
+
|
349
|
+
VALUE dtraceprobe_alloc(VALUE klass)
|
350
|
+
{
|
351
|
+
VALUE obj;
|
352
|
+
dtrace_probe_t *probe;
|
353
|
+
|
354
|
+
probe = ALLOC(dtrace_probe_t);
|
355
|
+
if (!probe) {
|
356
|
+
rb_raise(eDtraceException, "alloc failed");
|
357
|
+
return Qnil;
|
358
|
+
}
|
359
|
+
|
360
|
+
/* no mark function: no ruby objects hung off this struct */
|
361
|
+
obj = Data_Wrap_Struct(klass, NULL, dtraceprobe_free, probe);
|
362
|
+
return obj;
|
363
|
+
}
|
364
|
+
|
365
|
+
VALUE dtraceprobe_addr(VALUE self)
|
366
|
+
{
|
367
|
+
dtrace_probe_t *probe;
|
368
|
+
|
369
|
+
Data_Get_Struct(self, dtrace_probe_t, probe);
|
370
|
+
return INT2FIX(probe->func);
|
371
|
+
}
|
372
|
+
|
373
|
+
VALUE dtraceprobe_is_enabled(VALUE self)
|
374
|
+
{
|
375
|
+
dtrace_probe_t *probe;
|
376
|
+
|
377
|
+
Data_Get_Struct(self, dtrace_probe_t, probe);
|
378
|
+
return ((int)(*probe->func)()) ? Qtrue : Qfalse;
|
379
|
+
}
|
380
|
+
|
381
|
+
VALUE dtraceprobe_fire(int argc, VALUE *ruby_argv, VALUE self) {
|
382
|
+
dtrace_probe_t *probe;
|
383
|
+
int i;
|
384
|
+
void *argv[8]; // probe argc max for now.
|
385
|
+
void (*func)();
|
386
|
+
|
387
|
+
Data_Get_Struct(self, dtrace_probe_t, probe);
|
388
|
+
|
389
|
+
/* munge Ruby values to either char *s or ints. */
|
390
|
+
for (i = 0; i < argc; i++) {
|
391
|
+
switch (TYPE(ruby_argv[i])) {
|
392
|
+
case T_STRING:
|
393
|
+
argv[i] = (void *)RSTRING(ruby_argv[i])->ptr;
|
394
|
+
break;
|
395
|
+
case T_FIXNUM:
|
396
|
+
argv[i] = (void *)FIX2INT(ruby_argv[i]);
|
397
|
+
break;
|
398
|
+
default:
|
399
|
+
rb_raise(eDtraceException, "type of arg[%d] is not string or fixnum", i);
|
400
|
+
break;
|
401
|
+
}
|
402
|
+
}
|
403
|
+
|
404
|
+
func = (void (*)())(probe->func + IS_ENABLED_FUNC_LEN);
|
405
|
+
|
406
|
+
switch (argc) {
|
407
|
+
case 0:
|
408
|
+
(void)(*func)();
|
409
|
+
break;
|
410
|
+
case 1:
|
411
|
+
(void)(*func)(argv[0]);
|
412
|
+
break;
|
413
|
+
case 2:
|
414
|
+
(void)(*func)(argv[0], argv[1]);
|
415
|
+
break;
|
416
|
+
case 3:
|
417
|
+
(void)(*func)(argv[0], argv[1], argv[2]);
|
418
|
+
break;
|
419
|
+
case 4:
|
420
|
+
(void)(*func)(argv[0], argv[1], argv[2], argv[3]);
|
421
|
+
break;
|
422
|
+
case 5:
|
423
|
+
(void)(*func)(argv[0], argv[1], argv[2], argv[3],
|
424
|
+
argv[4]);
|
425
|
+
break;
|
426
|
+
case 6:
|
427
|
+
(void)(*func)(argv[0], argv[1], argv[2], argv[3],
|
428
|
+
argv[4], argv[5]);
|
429
|
+
break;
|
430
|
+
case 7:
|
431
|
+
(void)(*func)(argv[0], argv[1], argv[2], argv[3],
|
432
|
+
argv[4], argv[5], argv[6]);
|
433
|
+
break;
|
434
|
+
case 8:
|
435
|
+
(void)(*func)(argv[0], argv[1], argv[2], argv[3],
|
436
|
+
argv[4], argv[5], argv[6], argv[7]);
|
437
|
+
break;
|
438
|
+
default:
|
439
|
+
rb_raise(eDtraceException, "probe argc max is 8");
|
440
|
+
break;
|
441
|
+
}
|
442
|
+
|
443
|
+
return Qnil;
|
444
|
+
}
|
445
|
+
|
446
|
+
|
447
|
+
/*
|
448
|
+
* Returns the offset for this probe in the PROFFS section, based on
|
449
|
+
* the location of the DOF, and the location of this probe.
|
450
|
+
*/
|
451
|
+
VALUE dtraceprobe_probe_offset(VALUE self, VALUE file_addr, VALUE argc)
|
452
|
+
{
|
453
|
+
void *probe_addr;
|
454
|
+
int offset;
|
455
|
+
probe_addr = (void *)FIX2INT(rb_funcall(self, rb_intern("addr"), 0));
|
456
|
+
offset = IS_ENABLED_FUNC_LEN + 8 + (FIX2INT(argc) * 4);
|
457
|
+
return INT2FIX((int)probe_addr - (int)FIX2INT(file_addr) + offset);
|
458
|
+
}
|
459
|
+
|
460
|
+
/*
|
461
|
+
* Returns the offset for this probe's is-enabled tracepoint in the
|
462
|
+
* PRENOFFS section, based on the location of the DOF, and the
|
463
|
+
* location of this probe.
|
464
|
+
*/
|
465
|
+
VALUE dtraceprobe_is_enabled_offset(VALUE self, VALUE file_addr)
|
466
|
+
{
|
467
|
+
void *probe_addr;
|
468
|
+
probe_addr = (void *)FIX2INT(rb_funcall(self, rb_intern("addr"), 0));
|
469
|
+
return INT2FIX((int)probe_addr - (int)FIX2INT(file_addr) + 12);
|
470
|
+
}
|