#!/usr/bin/python # This handles the systemtap equivalent of # $(DTRACE) $(DTRACEFLAGS) -G -s $^ -o $@ # $(DTRACE) $(DTRACEFLAGS) -h -s $^ -o $@ # which is a step that builds DTrace provider and probe definitions # Copyright (C) 2009 Red Hat Inc. # # This file is part of systemtap, and is free software. You can # redistribute it and/or modify it under the terms of the GNU General # Public License (GPL); either version 2, or (at your option) any # later version. import os,posix,sys from subprocess import call from tempfile import mkstemp class provider: arglist = dict() def open(self, provider, header): have_provider = False self.f = open(provider) self.h = open(header,mode='w') self.h.write("// Generated by the Systemtap dtrace wrapper\n") self.h.write("\n#include \n\n") in_comment = False while (True): line = self.f.readline() if (line == ""): break if (line.find("/*") >= 0): in_comment = True if (line.find("*/") >= 0): in_comment = False continue if (in_comment): continue if (line.find("provider") >= 0): tokens = line.split() have_provider = True self.provider = tokens[1] elif (have_provider and line.find("probe ") > 0): while (line.find(")") < 0): line += self.f.readline() this_probe = line[line.find("probe ")+5:line.find("(")].strip() this_probe_canon = self.provider.upper() + "_" + this_probe.replace("__","_").upper() args = (line[line.find("(")+1:line.find(")")]) new_args = "" i = 0 c = 0 self.arglist[this_probe] = "" while (i < len(args)): if (args[i:i+1] == ","): new_args = ('%s%s' % (new_args, args[i])) c += 1 else: new_args = new_args + args[i] i += 1 if (len(new_args) > 0): self.arglist[this_probe] = ('%s arg%d' % (new_args, c)) if (len(new_args) == 0): self.h.write ('#define %s() STAP_PROBE(provider,%s)\n' % (this_probe_canon, this_probe)) elif (c == 0): self.h.write ('#define %s(arg1) STAP_PROBE%d(provider,%s,arg1)\n' % (this_probe_canon, c+1, this_probe)) elif (c == 1): self.h.write ('#define %s(arg1,arg2) STAP_PROBE%d(provider,%s,arg1,arg2)\n' % (this_probe_canon, c+1, this_probe)) elif (c == 2): self.h.write ('#define %s(arg1,arg2,arg3) STAP_PROBE%d(provider,%s,arg1,arg2,arg3)\n' % (this_probe_canon, c+1, this_probe)) elif (c == 3): self.h.write ('#define %s(arg1,arg2,arg3,arg4) STAP_PROBE%d(provider,%s,arg1,arg2,arg3,arg4)\n' % (this_probe_canon, c+1, this_probe)) elif (c == 4): self.h.write ('#define %s(arg1,arg2,arg3,arg4,arg5) STAP_PROBE%d(provider,%s,arg1,arg2,arg3,arg4,arg5)\n' % (this_probe_canon, c+1, this_probe)) elif (c == 5): self.h.write ('#define %s(arg1,arg2,arg3,arg4,arg5,arg6) STAP_PROBE%d(provider,%s,arg1,arg2,arg3,arg4,arg5,arg6)\n' % (this_probe_canon, c+1, this_probe)) elif (c == 6): self.h.write ('#define %s(arg1,arg2,arg3,arg4,arg5,arg6,arg7) STAP_PROBE%d(provider,%s,arg1,arg2,arg3,arg4,arg5,arg6,arg7)\n' % (this_probe_canon, c+1, this_probe)) elif (c == 7): self.h.write ('#define %s(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) STAP_PROBE%d(provider,%s,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8)\n' % (this_probe_canon, c+1, this_probe)) elif (c == 8): self.h.write ('#define %s(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9) STAP_PROBE%d(provider,%s,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9)\n' % (this_probe_canon, c+1, this_probe)) elif (c == 9): self.h.write ('#define %s(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10) STAP_PROBE%d(provider,%s,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10)\n' % (this_probe_canon, c+1, this_probe)) self.h.write ('#define %s_ENABLED() 1\n' % this_probe_canon) def get(self, arg): print arg if (arg in self.arglist): return self.arglist[arg] else: return "" ######################################################################## # main ######################################################################## def usage (): print "Usage " + sys.argv[0] + " [-h | -G] -s File.d -o File {Files}" sys.exit(1) def open_file (arg): if (len (sys.argv) <= arg): return False try: file = open(sys.argv[arg], 'r') except IOError: print (sys.argv[arg] + " not found") sys.exit(1) return file if (len (sys.argv) < 2): usage() i = 1 build_header = False build_source = False filename = "" while (i < len (sys.argv)): if (sys.argv[i] == "-o"): i += 1 filename = sys.argv[i] elif (sys.argv[i] == "-s"): i += 1 s_filename = sys.argv[i] elif (sys.argv[i] == "-h"): build_header = True elif (sys.argv[i] == "-G"): build_source = True i += 1 if (build_header == False and build_source == False): usage() sys.exit(1) if (filename == ""): if (s_filename != ""): (filename,ext) = os.path.splitext(s_filename) filename = os.path.basename(filename) if (build_header): filename = filename + ".h" elif (build_source): filename = filename + ".o" else: usage sys.exit(1) if (build_header): providers = provider() providers.open(s_filename, filename) elif (build_source): (basename,ext) = os.path.splitext(s_filename) basename = os.path.basename(basename) (d,fn) = mkstemp(suffix=".c",prefix=basename) f = open(fn,mode='w') f.write("static __dtrace () {}\n") f.close() call(["gcc", "-fPIC", "-c", fn, "-o", filename], shell=False) os.remove(fn)