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