1 # common python utility routines for the Bionic tool scripts 2 3 import sys, os, commands, string 4 5 # support Bionic architectures, add new ones as appropriate 6 # 7 bionic_archs = [ "arm", "x86", "mips" ] 8 9 # basic debugging trace support 10 # call D_setlevel to set the verbosity level 11 # and D(), D2(), D3(), D4() to add traces 12 # 13 verbose = 0 14 15 def D(msg): 16 global verbose 17 if verbose > 0: 18 print msg 19 20 def D2(msg): 21 global verbose 22 if verbose >= 2: 23 print msg 24 25 def D3(msg): 26 global verbose 27 if verbose >= 3: 28 print msg 29 30 def D4(msg): 31 global verbose 32 if verbose >= 4: 33 print msg 34 35 def D_setlevel(level): 36 global verbose 37 verbose = level 38 39 40 # parser for the SYSCALLS.TXT file 41 # 42 class SysCallsTxtParser: 43 def __init__(self): 44 self.syscalls = [] 45 self.lineno = 0 46 47 def E(self, msg): 48 print "%d: %s" % (self.lineno, msg) 49 50 def parse_line(self, line): 51 """ parse a syscall spec line. 52 53 line processing, format is 54 return type func_name[:syscall_name[:call_id]] ( [paramlist] ) (syscall_number[,syscall_number_x86])|stub 55 """ 56 pos_lparen = line.find('(') 57 E = self.E 58 if pos_lparen < 0: 59 E("missing left parenthesis in '%s'" % line) 60 return 61 62 pos_rparen = line.rfind(')') 63 if pos_rparen < 0 or pos_rparen <= pos_lparen: 64 E("missing or misplaced right parenthesis in '%s'" % line) 65 return 66 67 return_type = line[:pos_lparen].strip().split() 68 if len(return_type) < 2: 69 E("missing return type in '%s'" % line) 70 return 71 72 syscall_func = return_type[-1] 73 return_type = string.join(return_type[:-1],' ') 74 call_id = -1 75 76 pos_colon = syscall_func.find(':') 77 if pos_colon < 0: 78 syscall_name = syscall_func 79 else: 80 if pos_colon == 0 or pos_colon+1 >= len(syscall_func): 81 E("misplaced colon in '%s'" % line) 82 return 83 84 # now find if there is a call_id for a dispatch-type syscall 85 # after the optional 2nd colon 86 pos_colon2 = syscall_func.find(':', pos_colon + 1) 87 if pos_colon2 < 0: 88 syscall_name = syscall_func[pos_colon+1:] 89 syscall_func = syscall_func[:pos_colon] 90 else: 91 if pos_colon2+1 >= len(syscall_func): 92 E("misplaced colon2 in '%s'" % line) 93 return 94 syscall_name = syscall_func[(pos_colon+1):pos_colon2] 95 call_id = int(syscall_func[pos_colon2+1:]) 96 syscall_func = syscall_func[:pos_colon] 97 98 if pos_rparen > pos_lparen+1: 99 syscall_params = line[pos_lparen+1:pos_rparen].split(',') 100 params = string.join(syscall_params,',') 101 else: 102 syscall_params = [] 103 params = "void" 104 105 number = line[pos_rparen+1:].strip() 106 if number == "stub": 107 syscall_common = -1 108 syscall_arm = -1 109 syscall_x86 = -1 110 syscall_mips = -1 111 else: 112 try: 113 if number[0] == '#': 114 number = number[1:].strip() 115 numbers = string.split(number,',') 116 if len(numbers) == 1: 117 syscall_common = int(numbers[0]) 118 syscall_arm = -1 119 syscall_x86 = -1 120 syscall_mips = -1 121 else: 122 if len(numbers) == 3: 123 syscall_common = -1 124 syscall_arm = int(numbers[0]) 125 syscall_x86 = int(numbers[1]) 126 syscall_mips = int(numbers[2]) 127 else: 128 E("invalid syscall number format in '%s'" % line) 129 return 130 except: 131 E("invalid syscall number in '%s'" % line) 132 return 133 134 global verbose 135 if verbose >= 2: 136 if call_id == -1: 137 if syscall_common == -1: 138 print "%s: %d,%d,%d" % (syscall_name, syscall_arm, syscall_x86, syscall_mips) 139 else: 140 print "%s: %d" % (syscall_name, syscall_common) 141 else: 142 if syscall_common == -1: 143 print "%s(%d): %d,%d,%d" % (syscall_name, call_id, syscall_arm, syscall_x86, syscall_mips) 144 else: 145 print "%s(%d): %d" % (syscall_name, call_id, syscall_common) 146 147 t = { "armid" : syscall_arm, 148 "x86id" : syscall_x86, 149 "mipsid" : syscall_mips, 150 "common" : syscall_common, 151 "cid" : call_id, 152 "name" : syscall_name, 153 "func" : syscall_func, 154 "params" : syscall_params, 155 "decl" : "%-15s %s (%s);" % (return_type, syscall_func, params) } 156 self.syscalls.append(t) 157 158 def parse_file(self, file_path): 159 D2("parse_file: %s" % file_path) 160 fp = open(file_path) 161 for line in fp.xreadlines(): 162 self.lineno += 1 163 line = line.strip() 164 if not line: continue 165 if line[0] == '#': continue 166 self.parse_line(line) 167 168 fp.close() 169 170 171 class StringOutput: 172 def __init__(self): 173 self.line = "" 174 175 def write(self,msg): 176 self.line += msg 177 D2("write '%s'" % msg) 178 179 def get(self): 180 return self.line 181