def splitMethodsByProfile(self, javaMethods): "Split methods into classes by the size of the classes" def nameInMethods(methods, name): for method in methods: for fn in method.functions: if fn.name == name or "%s_%x" % (fn.name, fn.address) == name: return method return None methods = [] name = "Cibyl" for e in self.profile.getEntriesSortedByCallCount(): if e.name == "start" or e.name == "CIBYL_callTable": continue method = nameInMethods(javaMethods, e.name) if method: del javaMethods[javaMethods.index(method)] methods.append(method) else: if not nameInMethods(methods, e.name): config.abortWithMessage("The profile contains method " + e.name + " which is not in the ELF file") # Special case for ones with zero calls out = self.splitMethodsBySize(methods) return self.splitMethodsBySize(javaMethods, out)
def splitMethodsByProfile(self, javaMethods): "Split methods into classes by the size of the classes" def nameInMethods(methods, name): for method in methods: for fn in method.functions: if fn.name == name or "%s_%x" % (fn.name, fn.address) == name: return method return None methods = [] name = "Cibyl" for e in self.profile.getEntriesSortedByCallCount(): if e.name == "start" or e.name == "CIBYL_callTable": continue method = nameInMethods(javaMethods, e.name) if method: del javaMethods[ javaMethods.index(method) ] methods.append(method) else: if not nameInMethods(methods, e.name): config.abortWithMessage("The profile contains method " + e.name + " which is not in the ELF file") # Special case for ones with zero calls out = self.splitMethodsBySize(methods) return self.splitMethodsBySize(javaMethods, out)
def __init__(self, filename, syscallDirectories, onlyReadSyscalls=False): self.filename = filename self.syscallDirectories = syscallDirectories self.tracing = config.tracing self.labels = {} self.instructions = [] self.instructionsByAddress = {} self.syscalls = {} self.usedSyscalls = {} self.compileFunctions = True self.prunedRanges = [] self.processes = [] self.bc = bytecode.ByteCodeGenerator(self) self.optimizer = optimizer.Optimizer() self.registerHandler = register.RegisterHandler(self, self.bc) self.elf = Cibyl.elf.Elf(self.filename) self.addressesToName = getSyscallStrings(self.elf.getSectionContents(".cibylstrtab")) if config.profileFile: f = open(config.profileFile) d = f.read() f.close() try: self.profile = profile.Profile(d) except: config.abortWithMessage("Failed loading the profile") # Read everything allFunctions = Cibyl.SyscallHandling.function.functionsFromHeaderDirectories(syscallDirectories) for fn in allFunctions: self.addSyscall(fn) self.readBinary() # Fixup the jump destinations and other stuff with the instructions for insn in self.instructions: insn.fixup() self.instructionsByAddress[insn.address] = insn if insn.delayed: assert(not self.instructionsByAddress.has_key(insn.delayed.address)) self.instructionsByAddress[insn.delayed.address] = insn.delayed insn.delayed.fixup() if insn.prefix: assert(not self.instructionsByAddress.has_key(insn.prefix.address)) self.instructionsByAddress[insn.prefix.address] = insn.prefix insn.prefix.fixup() for insn in self.instructions: if insn.address in self.labels: insn.isBranchDestination = True # Arrange instructions into functions self.functions = [] self.functionsByName = {} for sym in self.elf.getSymbolsByType("tW"): if self.isPruned(sym.address) >= 0: continue # Add a label for this address and create a new function self.addLabel(sym.address, inJumpTab = True, name = sym.name, isFunction = True) insns, labels = self.splitByAddresses(sym.address, sym.address + sym.size) # Maybe trace this function useTracing = self.tracing if config.traceFunctions: useTracing = sym.name in config.traceFunctions fn = function.Function(self, sym.name, insns, labels, useTracing) self.functions.append(fn) for fn in self.functions: self.functionsByName[fn.name] = fn self.functions.sort() javaMethods = [] colocateFunctions = [] otherFunctions = [] # if config.profileFile: # config.colocateFunctions = self.getColocatedFunctionsByProfile() for fn in self.functions: if fn.name in config.colocateFunctions: colocateFunctions.append(fn) else: otherFunctions.append(fn) # Insert java methods (colocated and normal) if colocateFunctions != []: javaMethods.append(javamethod.JavaMethod(self, colocateFunctions)) for fn in otherFunctions: javaMethods.append(javamethod.JavaMethod(self, [fn])) self.jumptab = javamethod.GlobalJavaCallTableMethod(self, colocateFunctions + otherFunctions) javaMethods.append(self.jumptab) self.javaClasses = self.splitMethodsInClasses(javaMethods)
def __init__(self, filename, syscallDirectories, onlyReadSyscalls=False): self.filename = filename self.syscallDirectories = syscallDirectories self.tracing = config.tracing self.labels = {} self.instructions = [] self.instructionsByAddress = {} self.syscalls = {} self.usedSyscalls = {} self.compileFunctions = True self.prunedRanges = [] self.processes = [] self.bc = bytecode.ByteCodeGenerator(self) self.optimizer = optimizer.Optimizer() self.registerHandler = register.RegisterHandler(self, self.bc) self.elf = Cibyl.elf.Elf(self.filename) self.addressesToName = getSyscallStrings( self.elf.getSectionContents(".cibylstrtab")) if config.profileFile: f = open(config.profileFile) d = f.read() f.close() try: self.profile = profile.Profile(d) except: config.abortWithMessage("Failed loading the profile") # Read everything allFunctions = Cibyl.SyscallHandling.function.functionsFromHeaderDirectories( syscallDirectories) for fn in allFunctions: self.addSyscall(fn) self.readBinary() # Fixup the jump destinations and other stuff with the instructions for insn in self.instructions: insn.fixup() self.instructionsByAddress[insn.address] = insn if insn.delayed: assert (not self.instructionsByAddress.has_key( insn.delayed.address)) self.instructionsByAddress[insn.delayed.address] = insn.delayed insn.delayed.fixup() if insn.prefix: assert (not self.instructionsByAddress.has_key( insn.prefix.address)) self.instructionsByAddress[insn.prefix.address] = insn.prefix insn.prefix.fixup() for insn in self.instructions: if insn.address in self.labels: insn.isBranchDestination = True # Arrange instructions into functions self.functions = [] self.functionsByName = {} for sym in self.elf.getSymbolsByType("tW"): if self.isPruned(sym.address) >= 0: continue # Add a label for this address and create a new function self.addLabel(sym.address, inJumpTab=True, name=sym.name, isFunction=True) insns, labels = self.splitByAddresses(sym.address, sym.address + sym.size) # Maybe trace this function useTracing = self.tracing if config.traceFunctions: useTracing = sym.name in config.traceFunctions fn = function.Function(self, sym.name, insns, labels, useTracing) self.functions.append(fn) for fn in self.functions: self.functionsByName[fn.name] = fn self.functions.sort() javaMethods = [] colocateFunctions = [] otherFunctions = [] # if config.profileFile: # config.colocateFunctions = self.getColocatedFunctionsByProfile() for fn in self.functions: if fn.name in config.colocateFunctions: colocateFunctions.append(fn) else: otherFunctions.append(fn) # Insert java methods (colocated and normal) if colocateFunctions != []: javaMethods.append(javamethod.JavaMethod(self, colocateFunctions)) for fn in otherFunctions: javaMethods.append(javamethod.JavaMethod(self, [fn])) self.jumptab = javamethod.GlobalJavaCallTableMethod( self, colocateFunctions + otherFunctions) javaMethods.append(self.jumptab) self.javaClasses = self.splitMethodsInClasses(javaMethods)