#!/usr/bin/python """ Generates common/src/SyscallInformation.C and dynutil/h/dyn_syscalls.h """ import os import sys import string def generate_dyn_syscalls(allSyscallNames): # Open file for writing outFile = open("dyn_syscalls.h", "w") # Write out "header" information outFile.write("/* This file was autogenerated from syscalls/generateSyscallInformation.py */" + "\n") outFile.write("#if !defined(DYN_SYSCALLS_H_)\n") outFile.write("#define DYN_SYSCALLS_H_ \n") outFile.write("\n") outFile.write("namespace Dyninst {\n") outFile.write("namespace Syscall {\n") outFile.write("enum {\n") # Write out our system calls! for syscall in allSyscallNames: if (syscall.find("//") == -1): outFile.write("\tdyn_" + syscall + ", \n") else: outFile.write("\t" + syscall + "\n") # Write out "footer" information outFile.write("};\n") outFile.write("}}\n") outFile.write("#endif\n") # Close file outFile.close() def generate_SyscallInformation(allSyscallNames, allSyscalls): # Open file for writing outFile = open("SyscallInformation.C", "w") # Write out "header" information outFile.write("/* This file was autogenerated from syscalls/generateSyscallInformation.py */" + "\n") outFile.write("#include \"Architecture.h\"\n") outFile.write("#include \"dyn_syscalls.h\"\n") outFile.write("SyscallInformation::SyscallInformation() {\n") curOS = allSyscalls[0][0] curArch = allSyscalls[0][1] curPlatName = curOS + "_" + curArch outFile.write("\n/* " + curOS + " " + curArch + " Numbers */\n") outFile.write("Platform " + curPlatName + "(" + curArch + ", " + curOS + ");\n") for syscall in allSyscalls: newPlat = False if (curOS != syscall[0]): curOS = syscall[0] newPlat = True if (curArch != syscall[1]): curArch = syscall[1] newPlat = True if (newPlat): curPlatName = curOS + "_" + curArch outFile.write("\n/* " + curOS + " " + curArch + " Numbers */\n") outFile.write("Platform " + curPlatName + "_plat(" + curArch + ", " + curOS + ");\n") curName = syscall[2] curPlatformNumber = syscall[3] # Write out the two mapping insertions outFile.write(curPlatName + "_syscallNumbers.insert(make_pair(Syscall::dyn_" + curName + ", " + str(curPlatformNumber) + "));\n") outFile.write(curPlatName + "_syscallNames.insert(make_pair(" + curPlatformNumber + ", \"" + curName + "\"));\n") # Write out "footer" information outFile.write("}\n") # Close file outFile.close() allSyscallNames = [] allSyscalls = [] topDir = "unistd-by-platform" for curOS in os.listdir(topDir): print curOS for curArch in os.listdir(topDir + "/" + curOS): print "\t" + curArch for curFile in os.listdir(topDir + "/" + curOS + "/" + curArch): print "\t\t" + curFile # Cheat and add some additional information to the dyn_syscalls.h enum allSyscallNames.append("// " + curOS + "/" + curArch + "/" + curFile) # Process the file! curFileHandle = open(topDir + "/" + curOS + "/" + curArch + "/" + curFile, "r") # Keep a simple name-number mapping to deal with subsequent syscalls defined with addition sysNumbers = dict() for line in curFileHandle: line = line.rstrip() if (line.find("#define") == 0) and (line.find("NR") != -1): print line # Extract out system call name and number define, NR, info = line.partition("NR_") infoList = info.split() syscallName = infoList[0] syscallNumber = infoList[1] # Build a platform-specific descriptor for the current syscall curSyscall = [] curSyscall.append(curOS) curSyscall.append(curArch) curSyscall.append(syscallName) # Deal with non-numeric values (e.g., those that do math) if (syscallNumber.find("NR") != -1): # Deal with addition shenanigans in unistd.h left, NR, add = syscallNumber.partition("NR_") syscallNumber = add.rstrip(")") baseSyscall, add, val = syscallNumber.partition("+") baseSyscallNumber = sysNumbers[baseSyscall] realSyscallNumber = int(float(baseSyscallNumber)) + int(float(val)) syscallNumber = realSyscallNumber # Finally, add correct syscall numbers to our map curSyscall.append(str(syscallNumber)) allSyscalls.append(curSyscall) # Add to our dictionary for later sysNumbers[syscallName] = syscallNumber # If necessary, add current syscall name to master list if (allSyscallNames.count(syscallName) == 0): allSyscallNames.append(syscallName) # Generate the two files generate_dyn_syscalls(allSyscallNames) generate_SyscallInformation(allSyscallNames, allSyscalls)