]> sourceware.org Git - systemtap.git/blob - dtrace.in
Fix construction of ".local" variant of the DNS name on server certificates.
[systemtap.git] / dtrace.in
1 #!/usr/bin/python
2 # vim: et sta sts=4 sw=4 ts=8
3
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
8
9 # Copyright (C) 2009, 2010, 2011 Red Hat Inc.
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
16 import os
17 import posix
18 import sys
19 import shlex
20 from subprocess import call
21 from tempfile import mkstemp
22
23 class _provider(object):
24 def __init__(self):
25 self.semaphores_def = "\n"
26
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)
33
34 def __typedef_append(self, typedefs, this_probe, arg, c, add_typedefs):
35 if (add_typedefs):
36 split_arg = arg.rsplit(None,1)
37 if (self.__basic_type(arg)):
38 return typedefs
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")
43 else:
44 typedefs += ("typedef " + arg.strip() + type_name + "; ")
45 typedefs += (type_name + type_name + "_v;\n")
46 return typedefs
47
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'
61
62 def semaphore_def_write(self, file):
63 file.write(self.semaphores_def)
64
65 def generate(self, provider, header, add_typedefs):
66 have_provider = False
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")
73 in_comment = False
74 typedefs = ""
75 while (True):
76 line = self.f.readline()
77 if (line == ""):
78 break
79 if (line.find("/*") != -1):
80 in_comment = True
81 if (line.find("*/") != -1):
82 in_comment = False
83 continue
84 if (in_comment):
85 continue
86 if (line.find("provider") != -1):
87 tokens = line.split()
88 have_provider = True
89 self.provider = tokens[1]
90 elif (not have_provider):
91 if (add_typedefs):
92 self.h.write (line)
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(")")])
99 args_string = ""
100 arg = ""
101 i = 0
102 c = 0
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()))
108 c += 1
109 typedefs = self.__typedef_append (typedefs, this_probe,
110 arg, c, add_typedefs)
111 arg = ""
112 else:
113 arg = arg + args[i]
114 i += 1
115 if (i != 0):
116 args_string = ('%s %s' % (args_string, arg.strip()))
117 if (not args_string):
118 c = 0
119 stap_str = "DTRACE_PROBE(%s,%s" % \
120 (self.provider,this_probe)
121 else:
122 c += 1
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)
128 i = 1
129 while (i <= c):
130 if (i != 1):
131 define_str += ","
132 define_str = define_str + "arg%s" % (i);
133 stap_str = stap_str + ",arg%s" % (i);
134 i += 1
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
153 if (add_typedefs):
154 self.h.write(typedefs)
155 self.h.close()
156
157
158 def usage ():
159 print "Usage " + sys.argv[0] + " [--help] [-h | -G] [-C [-I<Path>]] -s File.d [-o <File>]"
160
161 def help ():
162 usage()
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."
171 sys.exit(1)
172
173
174 ########################################################################
175 # main
176 ########################################################################
177
178 def main():
179 if (len(sys.argv) < 2):
180 usage()
181 return 1
182
183 i = 1
184 build_header = False
185 build_source = False
186 add_typedefs = False
187 keep_temps = False
188 use_cpp = False
189 suffix = ""
190 filename = ""
191 s_filename = ""
192 includes = []
193 defines = []
194 while (i < len(sys.argv)):
195 if (sys.argv[i] == "-o"):
196 i += 1
197 filename = sys.argv[i]
198 elif (sys.argv[i] == "-s"):
199 i += 1
200 s_filename = sys.argv[i]
201 elif (sys.argv[i] == "-C"):
202 use_cpp = True
203 elif (sys.argv[i].startswith("-D")):
204 defines.append(sys.argv[i])
205 elif (sys.argv[i] == "-h"):
206 build_header = True
207 suffix = ".h"
208 elif (sys.argv[i].startswith("-I")):
209 includes.append(sys.argv[i])
210 elif (sys.argv[i] == "-G"):
211 build_source = True
212 suffix = ".o"
213 elif (sys.argv[i] == "-k"):
214 keep_temps = True
215 elif (sys.argv[i] == "--types"):
216 add_typedefs = True
217 elif (sys.argv[i] == "--help"):
218 help()
219 i += 1
220 if (build_header == False and build_source == False):
221 usage()
222 return 1
223
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])
228 if (retcode != 0):
229 print "\"cpp includes s_filename\" failed"
230 usage()
231 return 1
232 s_filename = fn
233 if (filename == ""):
234 if (s_filename != ""):
235 (filename,ext) = os.path.splitext(s_filename)
236 filename = os.path.basename(filename)
237 else:
238 usage()
239 return 1
240 else:
241 suffix = ""
242 if (build_header):
243 providers = _provider()
244 providers.generate(s_filename, filename + suffix, add_typedefs)
245 elif (build_source):
246 (basename,ext) = os.path.splitext(s_filename)
247
248 # create for semaphore_def_write
249 providers = _provider()
250 (d,fn) = mkstemp(suffix=".h")
251 providers.generate(s_filename, fn, add_typedefs)
252 if (not keep_temps):
253 os.remove(fn)
254 else:
255 print "header: " + fn
256
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)
264 f.close()
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)
270 if (retcode != 0):
271 print "\"gcc " + fn + "\" failed"
272 usage()
273 return 1
274 if (not keep_temps):
275 os.remove(fn)
276 else:
277 print "source: " + fn
278
279 if (use_cpp):
280 if (not keep_temps):
281 os.remove(s_filename)
282 else:
283 print "cpp: " + s_filename
284
285 return 0
286
287 if __name__ == "__main__":
288 sys.exit(main())
This page took 0.06241 seconds and 5 git commands to generate.