]>
sourceware.org Git - systemtap.git/blob - dtrace.in
3 # This handles the systemtap equivalent of
4 # $(DTRACE) $(DTRACEFLAGS) -G -s $^ -o $@
5 # $(DTRACE) $(DTRACEFLAGS) -h -s $^ -o $@
6 # which is a step that builds DTrace provider and probe definitions
8 # Copyright (C) 2009 Red Hat Inc.
10 # This file is part of systemtap, and is free software. You can
11 # redistribute it and/or modify it under the terms of the GNU General
12 # Public License (GPL); either version 2, or (at your option) any
15 import os
,posix
,string
,sys
16 from subprocess
import call
17 from tempfile
import mkstemp
21 # is the type a basic scalar type?
22 def basic_type(self
, arg
):
23 basic_types
= [ "int","int*","long","long*","short","short int","unsigned long","char","char*","float","double" ]
24 split_arg
= arg
.rsplit(None,1)
25 return (split_arg
[0].strip() in basic_types
) & (arg
.find("[") == -1)
26 def typedef_append(self
, typedefs
,this_probe
,arg
,c
):
28 split_arg
= arg
.rsplit(None,1)
29 if (self
.basic_type(arg
)):
31 type_name
= " %s_arg%d" % (this_probe
.replace("__","_"),c
)
32 if (len(split_arg
) > 1):
33 typedefs
+= ("typedef " + arg
.replace(" " + split_arg
[1].split("[")[0].lstrip("*"),type_name
).strip() + "; ")
34 typedefs
+= (type_name
+ type_name
+ "_v;\n")
36 typedefs
+= ("typedef " + arg
.strip() + type_name
+ "; ")
37 typedefs
+= (type_name
+ type_name
+ "_v;\n")
39 def semaphore_def_append(self
, this_probe
):
40 # NB: unsigned short is fixed in ABI
41 self
.semaphores_def
+= "__extension__ unsigned short %s_semaphore __attribute__ ((unused)) __attribute__ ((section (\".probes\")));\n" % (this_probe
)
42 def semaphore_def_write(self
, file):
43 file.write(self
.semaphores_def
)
44 def generate(self
, provider
, header
, add_typedefs
):
46 self
.f
= open(provider
)
47 self
.h
= open(header
,mode
='w')
48 self
.h
.write("/* Generated by the Systemtap dtrace wrapper */\n")
49 self
.h
.write("\n#define STAP_HAS_SEMAPHORES 1\n\n")
50 self
.h
.write("\n#include <sys/sdt.h>\n\n")
54 line
= self
.f
.readline()
57 if (line
.find("/*") != -1):
59 if (line
.find("*/") != -1):
64 if (line
.find("provider") != -1):
67 self
.provider
= tokens
[1]
68 elif (not have_provider
):
71 elif (have_provider
and line
.find("probe ") != -1):
72 while (line
.find(")") < 0):
73 line
+= self
.f
.readline()
74 this_probe
= line
[line
.find("probe ")+5:line
.find("(")].strip()
75 this_probe_canon
= self
.provider
.upper() + "_" + this_probe
.replace("__","_").upper()
76 args
= (line
[line
.find("(")+1:line
.find(")")])
81 self
.semaphore_def_append (this_probe
)
82 while (i
< len(args
)):
83 if (args
[i
:i
+1] == ","):
84 args_string
= ('%s %s,' % (args_string
, arg
.strip()))
86 typedefs
= self
.typedef_append (typedefs
,this_probe
,arg
,c
)
92 args_string
= ('%s %s' % (args_string
, arg
.strip()))
93 if (len(args_string
) == 0):
95 stap_str
= "STAP_PROBE(provider,%s" % (this_probe
)
98 typedefs
= self
.typedef_append (typedefs
,this_probe
,arg
,c
)
99 stap_str
= "STAP_PROBE%d(provider,%s" % (c
,this_probe
)
100 define_str
= "#define %s(" % (this_probe_canon
)
105 define_str
= define_str
+ "arg%s" % (i
);
106 stap_str
= stap_str
+ ",arg%s" % (i
);
108 self
.h
.write ('/* %s (%s) */\n' % (this_probe_canon
,args_string
))
109 # XXX Enable this when .so semaphores work properly
110 self
.h
.write ('#define %s_ENABLED() 1 /*%s_semaphore*/\n' % (this_probe_canon
,this_probe
))
111 # NB: unsigned short is fixed in ABI
112 self
.h
.write ("__extension__ extern unsigned short %s_semaphore __attribute__ ((unused)) __attribute__ ((section (\".probes\")));\n" % (this_probe
))
113 self
.h
.write (define_str
+ ") \\\n")
114 self
.h
.write (stap_str
+ ")\n\n")
115 elif (line
.find("}") != -1 and have_provider
):
116 have_provider
= False
118 self
.h
.write (typedefs
)
123 print "Usage " + sys
.argv
[0] + " [--help] [-h | -G] -s File.d [-o File]"
127 print "Where -h builds a systemtap header file from the .d file"
128 print " -o specifies an explicit output file name,"
129 print " The default for -G is file.o and -h is file.h"
130 print " -s specifies the name of the .d input file"
131 print " -G builds a stub file.o from file.d,"
132 print " which is required by some packages that use dtrace."
136 if (len (sys
.argv
) <= arg
):
139 file = open(sys
.argv
[arg
], 'r')
141 print (sys
.argv
[arg
] + " not found")
146 ########################################################################
148 ########################################################################
150 if (len (sys
.argv
) < 2):
162 while (i
< len (sys
.argv
)):
163 if (sys
.argv
[i
] == "-o"):
165 filename
= sys
.argv
[i
]
166 elif (sys
.argv
[i
] == "-s"):
168 s_filename
= sys
.argv
[i
]
169 elif (sys
.argv
[i
] == "-C"):
171 elif (sys
.argv
[i
] == "-h"):
173 elif (sys
.argv
[i
] == "-G"):
175 elif (sys
.argv
[i
] == "-k"):
177 elif (sys
.argv
[i
] == "--types"):
179 elif (sys
.argv
[i
] == "--help"):
182 if (build_header
== False and build_source
== False):
186 if (s_filename
!= "" and use_cpp
):
187 (d
,fn
) = mkstemp(suffix
=".d")
188 retcode
= call(["cpp", s_filename
, fn
])
190 print "\"cpp s_filename\" failed"
195 if (s_filename
!= ""):
196 (filename
,ext
) = os
.path
.splitext(s_filename
)
197 filename
= os
.path
.basename(filename
)
205 (filename
,ext
) = os
.path
.splitext(filename
)
207 providers
= provider()
208 providers
.generate(s_filename
, filename
+ h_ext
, add_typedefs
)
210 (basename
,ext
) = os
.path
.splitext(s_filename
)
212 # create for semaphore_def_write
213 providers
= provider()
214 (d
,fn
) = mkstemp(suffix
=".h")
215 providers
.generate(s_filename
, fn
, add_typedefs
)
219 print "header: " + fn
221 (d
,fn
) = mkstemp(suffix
=".c")
222 f
= open(fn
,mode
='w')
223 f
.write("static __dtrace () {}\n")
224 providers
.semaphore_def_write(f
)
226 call(["gcc", "-fPIC", "-I.", "-I@prefix@/include", "-g", "-c", fn
, "-o", filename
+ ".o"], shell
=False)
230 print "source: " + fn
233 os
.remove(s_filename
)
235 print "cpp: " + s_filename
This page took 0.097865 seconds and 6 git commands to generate.