Esempio n. 1
0
			def visit_FuncCall(self, node):
				if not isinstance(node.name, c_ast.Cast) and node.name.name == "jamaicaInterpreter_getInterfaceMethod":
					#Verify the format of the getInterfaceMethod Compound. It is believed this is constant.
					decl = node.parent
					compound = decl.parent
					if (not isinstance(decl, c_ast.Decl) or (not isinstance(compound, c_ast.Compound))):
						raise CaicosError("Call to jamaicaInterpreter_getInterfaceMethod appears to be in a different format. Are you using a compatible version of Jamaica?") 
					expected = [c_ast.Decl, c_ast.Assignment, c_ast.If, c_ast.If, c_ast.Assignment]
					for i in xrange(len(compound.block_items)):
						if not isinstance(compound.block_items[i], expected[i]):
							raise CaicosError("Call to jamaicaInterpreter_getInterfaceMethod is a different format. Are you using a compatible version of Jamaica?") 
					
					compound.block_items[0].type.type.names[0] = "jamaica_int32"
					
					del compound.block_items[1] #ct->calledMethod = m;
					del compound.block_items[1] #If jamaica_throwIncompClassChangeErr
					del compound.block_items[1] #If jamaica_throwAbstrMethodErr
					
					block_items = []
					
					for m in intreslv.parse_getInterfaceMethod_call(node):
						cname, _ = c_name_of_java_method(m, intreslv.jamaicaoutputdir)

						funccall = c_ast.FuncCall(c_ast.ID(cname), compound.block_items[-1].rvalue.args)
						assignment = c_ast.Assignment(compound.block_items[-1].op, compound.block_items[-1].lvalue, funccall)
						case = c_ast.Case(c_ast.ID("(unsigned long) " + str(cname)), [assignment, c_ast.Break()])
						block_items.append(case)
						
					swi = c_ast.Switch(c_ast.ID(compound.block_items[0].name), c_ast.Compound(block_items))
					compound.block_items[-1] = swi
Esempio n. 2
0
	def parse_getInterfaceMethod_call(self, node):
		"""
		Given a FuncCall node to jamaicaInterpreter_getInterfaceMethod, determine which methods might be returned.
		"""
		with open(node.coord.file) as ofile:
			lines = ofile.readlines()
	
		errorstr = "When handling interface calls, file " + node.coord.file + " does not appear to be in the correct format. Was a version of JamaicaBuilder that supports interface enumeration used?"
		
		if lines[node.coord.line - 2].strip() != "*/":
			raise CaicosError(errorstr)
		
		offset = 3
		interfaces = []
		while True:
			if node.coord.line - offset < 0:
				raise CaicosError(errorstr)
			line = lines[node.coord.line - offset].strip()	
			if line.startswith(INTERFACE_START):
				break
			else:
				interfaces.append(line)
			offset += 1
			
		interfacename = line[len(INTERFACE_START):]
		if not interfacename[-1] == ':':
			raise CaicosError(errorstr)
		interfacename = interfacename[:-1]
		
		methodname = interfacename[interfacename.rfind("."):]
	
		found = set()
		for i in interfaces:
			name = i + methodname
			found.add(name)
			
			if not name in self.interfacemapping: 
				self.interfacemapping[name] = (self.next_id, c_name_of_java_method(name, self.jamaicaoutputdir))
				self.next_id += 1
			
		return found
Esempio n. 3
0
	def find_reachable_functions(self, fndef):
		#Prevent loops
		if fndef in self.func_defs_seen:
			return
		self.func_defs_seen.append(fndef)
			
		#Find all calls in the function definition
		callsfound = []
		def search_for_fcall(node):
			if isinstance(node, c_ast.FuncCall):
				callsfound.append(node)
			for c in node.children():
				search_for_fcall(c[1])
		search_for_fcall(fndef)

		#Resolve the calls into function definitions
		for call in callsfound:
			if isinstance(call.name, c_ast.Cast):
				log().warning("A cast to a function type detected at " + os.path.basename(call.coord.file) + ":" + str(call.coord.line) + ". Flow analysis may not be complete.")
			else:
				cnames = [(str(call.name.name), None)]
				if cnames[0][0] == "jamaicaInterpreter_getInterfaceMethod":
					int_sigs = self.interfaceResolver.parse_getInterfaceMethod_call(call)
					for sig in int_sigs:
						cnames.append(c_name_of_java_method(sig, self.jamaicaoutputdir))

				for callname, fnode in cnames:
					if callname in excluded_functions:
						self.reachable_non_translated.add(callname)
					else:	
						if not callname in calls_to_ignore:			
							if not callname in resolutioncache:
								if fnode == None:
									resolutioncache[callname] = self.resolve_call(callname)
								else: 
									resolutioncache[callname] = fnode
							if resolutioncache[callname] != None:
								self.reachable_functions.add(resolutioncache[callname])
								self.find_reachable_functions(resolutioncache[callname])