ruby-dtrace 0.2.8 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
}
|