]> sourceware.org Git - systemtap.git/blame - dtrace.in
PR14574 partial fix: Add dyninst support to more tests.
[systemtap.git] / dtrace.in
CommitLineData
c1008fd0 1#!/usr/bin/python
bc65bf81 2# vim: et sta sts=4 sw=4 ts=8
c1008fd0
SC
3
4# This handles the systemtap equivalent of
d294a649 5# $(DTRACE) $(DTRACEFLAGS) -G -s $^ -o $@
c1008fd0 6# $(DTRACE) $(DTRACEFLAGS) -h -s $^ -o $@
d294a649
SC
7# which is a step that builds DTrace provider and probe definitions
8
b1568fd8 9# Copyright (C) 2009, 2010, 2011 Red Hat Inc.
c1008fd0
SC
10#
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
14# later version.
15
398d1973
SC
16import os
17import posix
398d1973 18import sys
4c353c3a 19import shlex
c0d0d868 20from subprocess import call
e3c5bcd9 21from tempfile import mkstemp
c1008fd0 22
d4168b3a
JS
23def init_gettext():
24 if "@USE_NLS@" == "yes":
25 import gettext
26 # hack around autoconf's weird stepwise substitution
27 datarootdir = "@datarootdir@".replace("${prefix}", "@STAP_PREFIX@")
28 localedir = "@LOCALEDIR@".replace("${datarootdir}", datarootdir)
29 gettext.bindtextdomain('@PACKAGE@', localedir)
30 gettext.textdomain('@PACKAGE@')
31 return gettext.gettext
32 return str
398d1973 33
50e767ff
JS
34class _provider(object):
35 def __init__(self):
36 self.semaphores_def = "\n"
37
4f46087f 38 # is the type a basic scalar type?
398d1973
SC
39 def __basic_type(self, arg):
40 basic_types = [ "int","int*","long","long*","short","short int",
41 "unsigned long","char","char*","float","double" ]
4f46087f
SC
42 split_arg = arg.rsplit(None,1)
43 return (split_arg[0].strip() in basic_types) & (arg.find("[") == -1)
50e767ff 44
a49946ac 45 def __typedef_append(self, typedefs, this_probe, arg, c, add_typedefs):
5111fc3e
SC
46 if (add_typedefs):
47 split_arg = arg.rsplit(None,1)
398d1973 48 if (self.__basic_type(arg)):
4f46087f 49 return typedefs
5111fc3e
SC
50 type_name = " %s_arg%d" % (this_probe.replace("__","_"),c)
51 if (len(split_arg) > 1):
52 typedefs += ("typedef " + arg.replace(" " + split_arg[1].split("[")[0].lstrip("*"),type_name).strip() + "; ")
53 typedefs += (type_name + type_name + "_v;\n")
54 else:
55 typedefs += ("typedef " + arg.strip() + type_name + "; ")
56 typedefs += (type_name + type_name + "_v;\n")
57 return typedefs
50e767ff 58
398d1973 59 def __semaphore_def_append(self, this_probe):
8faa1fc5 60 # NB: unsigned short is fixed in ABI
ebbd2b45 61 self.semaphores_def += '#if defined STAP_SDT_V1\n'
398d1973
SC
62 self.semaphores_def += '#define %s_%s_semaphore %s_semaphore\n' % \
63 (self.provider,this_probe,this_probe)
a794dbeb 64 self.semaphores_def += '#endif\n'
5561d47d
SC
65 self.semaphores_def += '#if defined STAP_SDT_V1 || defined STAP_SDT_V2 \n'
66 self.semaphores_def += "__extension__ unsigned short %s_%s_semaphore __attribute__ ((unused)) __attribute__ ((section (\".probes\")));\n" % \
67 (self.provider,this_probe)
68 self.semaphores_def += '#else\n'
8f549224 69 self.semaphores_def += "__extension__ unsigned short %s_%s_semaphore __attribute__ ((unused)) __attribute__ ((section (\".probes\"))) __attribute__ ((visibility (\"hidden\")));\n" % \
398d1973 70 (self.provider,this_probe)
5561d47d 71 self.semaphores_def += '#endif\n'
50e767ff 72
4f46087f
SC
73 def semaphore_def_write(self, file):
74 file.write(self.semaphores_def)
50e767ff 75
5111fc3e 76 def generate(self, provider, header, add_typedefs):
c1008fd0
SC
77 have_provider = False
78 self.f = open(provider)
79 self.h = open(header,mode='w')
2a22df62 80 self.h.write("/* Generated by the Systemtap dtrace wrapper */\n")
6b51ee12
SC
81 self.h.write("\n#define _SDT_HAS_SEMAPHORES 1\n\n")
82 self.h.write("\n#define STAP_HAS_SEMAPHORES 1 /* deprecated */\n\n")
c1008fd0
SC
83 self.h.write("\n#include <sys/sdt.h>\n\n")
84 in_comment = False
5111fc3e 85 typedefs = ""
c1008fd0
SC
86 while (True):
87 line = self.f.readline()
88 if (line == ""):
89 break
5111fc3e 90 if (line.find("/*") != -1):
c1008fd0 91 in_comment = True
5111fc3e 92 if (line.find("*/") != -1):
c1008fd0
SC
93 in_comment = False
94 continue
95 if (in_comment):
96 continue
5111fc3e 97 if (line.find("provider") != -1):
c1008fd0
SC
98 tokens = line.split()
99 have_provider = True
100 self.provider = tokens[1]
5111fc3e
SC
101 elif (not have_provider):
102 if (add_typedefs):
103 self.h.write (line)
104 elif (have_provider and line.find("probe ") != -1):
c1008fd0
SC
105 while (line.find(")") < 0):
106 line += self.f.readline()
107 this_probe = line[line.find("probe ")+5:line.find("(")].strip()
108 this_probe_canon = self.provider.upper() + "_" + this_probe.replace("__","_").upper()
109 args = (line[line.find("(")+1:line.find(")")])
5111fc3e
SC
110 args_string = ""
111 arg = ""
c1008fd0
SC
112 i = 0
113 c = 0
398d1973 114 self.__semaphore_def_append (this_probe)
c1008fd0
SC
115 while (i < len(args)):
116 if (args[i:i+1] == ","):
398d1973
SC
117 args_string = ('%s %s,' %
118 (args_string, arg.strip()))
c1008fd0 119 c += 1
a49946ac
JS
120 typedefs = self.__typedef_append (typedefs, this_probe,
121 arg, c, add_typedefs)
5111fc3e 122 arg = ""
c1008fd0 123 else:
5111fc3e 124 arg = arg + args[i]
c1008fd0 125 i += 1
5111fc3e
SC
126 if (i != 0):
127 args_string = ('%s %s' % (args_string, arg.strip()))
398d1973 128 if (not args_string):
46607641 129 c = 0
63877c9a 130 stap_str = "DTRACE_PROBE(%s,%s" % \
398d1973 131 (self.provider,this_probe)
46607641
SC
132 else:
133 c += 1
a49946ac
JS
134 typedefs = self.__typedef_append (typedefs, this_probe,
135 arg, c, add_typedefs)
63877c9a 136 stap_str = "DTRACE_PROBE%d(%s,%s" % \
398d1973 137 (c,self.provider,this_probe)
4f988cd3 138 define_str = "#define %s(" % (this_probe_canon)
46607641 139 i = 1
4f988cd3 140 while (i <= c):
2a22df62 141 if (i != 1):
4f988cd3 142 define_str += ","
46607641
SC
143 define_str = define_str + "arg%s" % (i);
144 stap_str = stap_str + ",arg%s" % (i);
4f988cd3 145 i += 1
398d1973
SC
146 self.h.write('/* %s (%s) */\n' % \
147 (this_probe_canon,args_string))
148 self.h.write('#if defined STAP_SDT_V1\n')
149 self.h.write('#define %s_ENABLED() __builtin_expect (%s_semaphore, 0)\n' % \
150 (this_probe_canon,this_probe))
151 self.h.write('#define %s_%s_semaphore %s_semaphore\n' % \
152 (self.provider,this_probe,this_probe))
153 self.h.write('#else\n')
154 self.h.write('#define %s_ENABLED() __builtin_expect (%s_%s_semaphore, 0)\n' % \
155 (this_probe_canon,self.provider,this_probe))
156 self.h.write('#endif\n')
8faa1fc5 157 # NB: unsigned short is fixed in ABI
398d1973
SC
158 self.h.write("__extension__ extern unsigned short %s_%s_semaphore __attribute__ ((unused)) __attribute__ ((section (\".probes\")));\n" % \
159 (self.provider,this_probe))
160 self.h.write(define_str + ") \\\n")
161 self.h.write(stap_str + ")\n\n")
5111fc3e
SC
162 elif (line.find("}") != -1 and have_provider):
163 have_provider = False
164 if (add_typedefs):
398d1973 165 self.h.write(typedefs)
5111fc3e
SC
166 self.h.close()
167
c1008fd0 168
c1008fd0 169def usage ():
bad3553d 170 print _("Usage ") + sys.argv[0] + " [--help] [-h | -G] [-C [-I<Path>]] -s File.d [-o <File>]"
5111fc3e
SC
171
172def help ():
173 usage()
bad3553d
LB
174 print _("Where -h builds a systemtap header file from the .d file")
175 print _(" -C when used with -h, also run cpp preprocessor")
176 print _(" -o specifies an explicit output file name,")
177 print _(" the default for -G is file.o and -h is file.h")
178 print _(" -I when running cpp pass through this -I include Path")
179 print _(" -s specifies the name of the .d input file")
180 print _(" -G builds a stub file.o from file.d,")
181 print _(" which is required by some packages that use dtrace.")
c1008fd0
SC
182 sys.exit(1)
183
4f988cd3
SC
184
185########################################################################
186# main
187########################################################################
188
a49946ac
JS
189def main():
190 if (len(sys.argv) < 2):
191 usage()
12aad6f0 192 return 1
c1008fd0 193
a49946ac
JS
194 i = 1
195 build_header = False
196 build_source = False
197 add_typedefs = False
198 keep_temps = False
199 use_cpp = False
b571f934 200 suffix = ""
a49946ac
JS
201 filename = ""
202 s_filename = ""
203 includes = []
204 defines = []
205 while (i < len(sys.argv)):
206 if (sys.argv[i] == "-o"):
207 i += 1
208 filename = sys.argv[i]
209 elif (sys.argv[i] == "-s"):
210 i += 1
211 s_filename = sys.argv[i]
212 elif (sys.argv[i] == "-C"):
213 use_cpp = True
214 elif (sys.argv[i].startswith("-D")):
215 defines.append(sys.argv[i])
216 elif (sys.argv[i] == "-h"):
217 build_header = True
b571f934 218 suffix = ".h"
a49946ac
JS
219 elif (sys.argv[i].startswith("-I")):
220 includes.append(sys.argv[i])
221 elif (sys.argv[i] == "-G"):
222 build_source = True
b571f934 223 suffix = ".o"
a49946ac
JS
224 elif (sys.argv[i] == "-k"):
225 keep_temps = True
226 elif (sys.argv[i] == "--types"):
227 add_typedefs = True
228 elif (sys.argv[i] == "--help"):
229 help()
c1008fd0 230 i += 1
a49946ac 231 if (build_header == False and build_source == False):
dd66ed3f 232 usage()
12aad6f0 233 return 1
a49946ac
JS
234
235 if (s_filename != "" and use_cpp):
236 (d,fn) = mkstemp(suffix=".d")
237 CPP = os.environ.get("CPP", "cpp")
4c353c3a 238 retcode = call(shlex.split(CPP) + includes + defines + [s_filename, fn])
a49946ac
JS
239 if (retcode != 0):
240 print "\"cpp includes s_filename\" failed"
241 usage()
12aad6f0 242 return 1
a49946ac
JS
243 s_filename = fn
244 if (filename == ""):
245 if (s_filename != ""):
246 (filename,ext) = os.path.splitext(s_filename)
247 filename = os.path.basename(filename)
248 else:
249 usage()
12aad6f0 250 return 1
c1008fd0 251 else:
b571f934 252 suffix = ""
8bab68f6 253 if (build_header):
a49946ac 254 providers = _provider()
b571f934 255 providers.generate(s_filename, filename + suffix, add_typedefs)
a49946ac
JS
256 elif (build_source):
257 (basename,ext) = os.path.splitext(s_filename)
4f46087f 258
a49946ac
JS
259 # create for semaphore_def_write
260 providers = _provider()
261 (d,fn) = mkstemp(suffix=".h")
262 providers.generate(s_filename, fn, add_typedefs)
263 if (not keep_temps):
264 os.remove(fn)
265 else:
266 print "header: " + fn
4f46087f 267
a49946ac
JS
268 (d,fn) = mkstemp(suffix=".c")
269 f = open(fn,mode='w')
270 f.write("static __dtrace () {}\n")
271 f.write("\n#include <sys/sdt.h>\n\n")
272 providers.semaphore_def_write(f)
273 f.close()
274 CC = os.environ.get("CC", "gcc")
275 CFLAGS = "-g " + os.environ.get("CFLAGS", "")
4c353c3a 276 retcode = call(shlex.split(CC) + defines + includes + shlex.split(CFLAGS) +
f6b267eb 277 ["-fPIC", "-I.", "-I@prefix@/include", "-c", fn, "-o",
b571f934
SC
278 filename + suffix], shell=False)
279 if (retcode != 0):
280 print "\"gcc " + fn + "\" failed"
281 usage()
12aad6f0 282 return 1
bc65bf81 283 if (not keep_temps):
a49946ac 284 os.remove(fn)
bc65bf81 285 else:
a49946ac
JS
286 print "source: " + fn
287 if (use_cpp):
288 if (not keep_temps):
289 os.remove(s_filename)
290 else:
291 print "cpp: " + s_filename
12aad6f0 292 return 0
a49946ac
JS
293
294if __name__ == "__main__":
d4168b3a 295 _ = init_gettext()
12aad6f0 296 sys.exit(main())
This page took 0.112883 seconds and 5 git commands to generate.