Example #1
0
    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)
Example #2
0
	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)
Example #3
0
	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)
Example #4
0
    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)