]>
sourceware.org Git - systemtap.git/blob - dtrace.in
2 # vim: et sta sts=4 sw=4 ts=8
4 # This handles the systemtap equivalent of
5 # $(DTRACE) $(DTRACEFLAGS) -G -s $^ -o $@
6 # $(DTRACE) $(DTRACEFLAGS) -h -s $^ -o $@
7 # which is a step that builds DTrace provider and probe definitions
9 # Copyright (C) 2009, 2010, 2011 Red Hat Inc.
11 # This file is part of systemtap, and is free software. You can
12 # redistribute it and/or modify it under the terms of the GNU General
13 # Public License (GPL); either version 2, or (at your option) any
20 from subprocess
import call
21 from tempfile
import mkstemp
23 class _provider(object):
25 self
.semaphores_def
= "\n"
27 # is the type a basic scalar type?
28 def __basic_type(self
, arg
):
29 basic_types
= [ "int","int*","long","long*","short","short int",
30 "unsigned long","char","char*","float","double" ]
31 split_arg
= arg
.rsplit(None,1)
32 return (split_arg
[0].strip() in basic_types
) & (arg
.find("[") == -1)
34 def __typedef_append(self
, typedefs
, this_probe
, arg
, c
, add_typedefs
):
36 split_arg
= arg
.rsplit(None,1)
37 if (self
.__basic
_type
(arg
)):
39 type_name
= " %s_arg%d" % (this_probe
.replace("__","_"),c
)
40 if (len(split_arg
) > 1):
41 typedefs
+= ("typedef " + arg
.replace(" " + split_arg
[1].split("[")[0].lstrip("*"),type_name
).strip() + "; ")
42 typedefs
+= (type_name
+ type_name
+ "_v;\n")
44 typedefs
+= ("typedef " + arg
.strip() + type_name
+ "; ")
45 typedefs
+= (type_name
+ type_name
+ "_v;\n")
48 def __semaphore_def_append(self
, this_probe
):
49 # NB: unsigned short is fixed in ABI
50 self
.semaphores_def
+= '#if defined STAP_SDT_V1\n'
51 self
.semaphores_def
+= '#define %s_%s_semaphore %s_semaphore\n' % \
52 (self
.provider
,this_probe
,this_probe
)
53 self
.semaphores_def
+= '#endif\n'
54 self
.semaphores_def
+= '#if defined STAP_SDT_V1 || defined STAP_SDT_V2 \n'
55 self
.semaphores_def
+= "__extension__ unsigned short %s_%s_semaphore __attribute__ ((unused)) __attribute__ ((section (\".probes\")));\n" % \
56 (self
.provider
,this_probe
)
57 self
.semaphores_def
+= '#else\n'
58 self
.semaphores_def
+= "__extension__ unsigned short %s_%s_semaphore __attribute__ ((unused)) __attribute__ ((section (\".probes\"))) __attribute__ ((visibility (\"hidden\")));\n" % \
59 (self
.provider
,this_probe
)
60 self
.semaphores_def
+= '#endif\n'
62 def semaphore_def_write(self
, file):
63 file.write(self
.semaphores_def
)
65 def generate(self
, provider
, header
, add_typedefs
):
67 self
.f
= open(provider
)
68 self
.h
= open(header
,mode
='w')
69 self
.h
.write("/* Generated by the Systemtap dtrace wrapper */\n")
70 self
.h
.write("\n#define _SDT_HAS_SEMAPHORES 1\n\n")
71 self
.h
.write("\n#define STAP_HAS_SEMAPHORES 1 /* deprecated */\n\n")
72 self
.h
.write("\n#include <sys/sdt.h>\n\n")
76 line
= self
.f
.readline()
79 if (line
.find("/*") != -1):
81 if (line
.find("*/") != -1):
86 if (line
.find("provider") != -1):
89 self
.provider
= tokens
[1]
90 elif (not have_provider
):
93 elif (have_provider
and line
.find("probe ") != -1):
94 while (line
.find(")") < 0):
95 line
+= self
.f
.readline()
96 this_probe
= line
[line
.find("probe ")+5:line
.find("(")].strip()
97 this_probe_canon
= self
.provider
.upper() + "_" + this_probe
.replace("__","_").upper()
98 args
= (line
[line
.find("(")+1:line
.find(")")])
103 self
.__semaphore
_def
_append
(this_probe
)
104 while (i
< len(args
)):
105 if (args
[i
:i
+1] == ","):
106 args_string
= ('%s %s,' %
107 (args_string
, arg
.strip()))
109 typedefs
= self
.__typedef
_append
(typedefs
, this_probe
,
110 arg
, c
, add_typedefs
)
116 args_string
= ('%s %s' % (args_string
, arg
.strip()))
117 if (not args_string
):
119 stap_str
= "DTRACE_PROBE(%s,%s" % \
120 (self
.provider
,this_probe
)
123 typedefs
= self
.__typedef
_append
(typedefs
, this_probe
,
124 arg
, c
, add_typedefs
)
125 stap_str
= "DTRACE_PROBE%d(%s,%s" % \
126 (c
,self
.provider
,this_probe
)
127 define_str
= "#define %s(" % (this_probe_canon
)
132 define_str
= define_str
+ "arg%s" % (i
);
133 stap_str
= stap_str
+ ",arg%s" % (i
);
135 self
.h
.write('/* %s (%s) */\n' % \
136 (this_probe_canon
,args_string
))
137 self
.h
.write('#if defined STAP_SDT_V1\n')
138 self
.h
.write('#define %s_ENABLED() __builtin_expect (%s_semaphore, 0)\n' % \
139 (this_probe_canon
,this_probe
))
140 self
.h
.write('#define %s_%s_semaphore %s_semaphore\n' % \
141 (self
.provider
,this_probe
,this_probe
))
142 self
.h
.write('#else\n')
143 self
.h
.write('#define %s_ENABLED() __builtin_expect (%s_%s_semaphore, 0)\n' % \
144 (this_probe_canon
,self
.provider
,this_probe
))
145 self
.h
.write('#endif\n')
146 # NB: unsigned short is fixed in ABI
147 self
.h
.write("__extension__ extern unsigned short %s_%s_semaphore __attribute__ ((unused)) __attribute__ ((section (\".probes\")));\n" % \
148 (self
.provider
,this_probe
))
149 self
.h
.write(define_str
+ ") \\\n")
150 self
.h
.write(stap_str
+ ")\n\n")
151 elif (line
.find("}") != -1 and have_provider
):
152 have_provider
= False
154 self
.h
.write(typedefs
)
159 print "Usage " + sys
.argv
[0] + " [--help] [-h | -G] [-C [-I<Path>]] -s File.d [-o <File>]"
163 print "Where -h builds a systemtap header file from the .d file"
164 print " -C when used with -h, also run cpp preprocessor"
165 print " -o specifies an explicit output file name,"
166 print " the default for -G is file.o and -h is file.h"
167 print " -I when running cpp pass through this -I include Path"
168 print " -s specifies the name of the .d input file"
169 print " -G builds a stub file.o from file.d,"
170 print " which is required by some packages that use dtrace."
174 ########################################################################
176 ########################################################################
179 if (len(sys
.argv
) < 2):
194 while (i
< len(sys
.argv
)):
195 if (sys
.argv
[i
] == "-o"):
197 filename
= sys
.argv
[i
]
198 elif (sys
.argv
[i
] == "-s"):
200 s_filename
= sys
.argv
[i
]
201 elif (sys
.argv
[i
] == "-C"):
203 elif (sys
.argv
[i
].startswith("-D")):
204 defines
.append(sys
.argv
[i
])
205 elif (sys
.argv
[i
] == "-h"):
208 elif (sys
.argv
[i
].startswith("-I")):
209 includes
.append(sys
.argv
[i
])
210 elif (sys
.argv
[i
] == "-G"):
213 elif (sys
.argv
[i
] == "-k"):
215 elif (sys
.argv
[i
] == "--types"):
217 elif (sys
.argv
[i
] == "--help"):
220 if (build_header
== False and build_source
== False):
224 if (s_filename
!= "" and use_cpp
):
225 (d
,fn
) = mkstemp(suffix
=".d")
226 CPP
= os
.environ
.get("CPP", "cpp")
227 retcode
= call(shlex
.split(CPP
) + includes
+ defines
+ [s_filename
, fn
])
229 print "\"cpp includes s_filename\" failed"
234 if (s_filename
!= ""):
235 (filename
,ext
) = os
.path
.splitext(s_filename
)
236 filename
= os
.path
.basename(filename
)
243 providers
= _provider()
244 providers
.generate(s_filename
, filename
+ suffix
, add_typedefs
)
246 (basename
,ext
) = os
.path
.splitext(s_filename
)
248 # create for semaphore_def_write
249 providers
= _provider()
250 (d
,fn
) = mkstemp(suffix
=".h")
251 providers
.generate(s_filename
, fn
, add_typedefs
)
255 print "header: " + fn
257 (d
,fn
) = mkstemp(suffix
=".c")
258 f
= open(fn
,mode
='w')
259 # dummy declaration just to make the object file non-empty
260 f
.write("static void __dtrace (void) __attribute__((unused));\n")
261 f
.write("static void __dtrace (void) {}\n")
262 f
.write("\n#include <sys/sdt.h>\n\n")
263 providers
.semaphore_def_write(f
)
265 CC
= os
.environ
.get("CC", "gcc")
266 CFLAGS
= "-g " + os
.environ
.get("CFLAGS", "")
267 retcode
= call(shlex
.split(CC
) + defines
+ includes
+ shlex
.split(CFLAGS
) +
268 ["-fPIC", "-I.", "-I@prefix@/include", "-c", fn
, "-o",
269 filename
+ suffix
], shell
=False)
271 print "\"gcc " + fn
+ "\" failed"
277 print "source: " + fn
281 os
.remove(s_filename
)
283 print "cpp: " + s_filename
287 if __name__
== "__main__":
This page took 0.06241 seconds and 5 git commands to generate.