def prototype(ctx, proto): """Get prototype definitions from the remote database (or the local database if no remote is found) matching constraints on name of its return type or specific arguments. """ reqs = {} try: for p in proto: pos, t = p.split(':') pos = int(pos) reqs[pos] = c_type(t).show() except Exception: click.secho('invalid arguments', fg='red', err=True) return db = ctx.obj['db'] Q = ctx.obj.get('select', Query().noop()) L = db.search(Q, cls='cFunc') R = [] with click.progressbar(L) as pL: for l in L: x = ccore.from_db(l) P = [c_type(t).show() for t in x.argtypes()] P.insert(0, c_type(x.restype()).show()) if max(reqs) >= len(P): continue if not all(((t == P[i]) for (i, t) in reqs.items())): continue R.append(x.show(db, form='C')) if R: click.echo('\n'.join(R))
def cStruct_ctypes(obj, db, recursive): name = id_ctypes(c_type(obj.identifier)) cls = "Union" if obj._is_union else "Structure" R = ["{0} = type('{0}',({1},),{{}})\n".format(name, cls)] if isinstance(recursive, set): if obj.identifier in recursive: return R[0] Q = True recursive.update(struct_letters) recursive.add(obj.identifier) else: Q = None anon = [] S = [] fld = "%s._fields_ = [" % name S.append(fld) pad = " " * len(fld) padded = False for i in obj: t, n, c = i r = c_type(t) if not n and not r.lbase.startswith("union "): continue if Q and (r.lbase not in recursive): q = db.tag & (where("id") == r.lbase) if "?_" in r.lbase: anon.append('"%s"' % n) q &= where("src") == obj.identifier if db.contains(q): x = obj.from_db(db.get(q)).show(db, recursive, form="ctypes") x = x.split("\n") for xrl in x: if (xrl + "\n" in R) and not xrl.startswith(" "): continue if xrl: R.append(xrl + "\n") recursive.add(r.lbase) else: secho("identifier %s not found" % r.lbase, fg="red", err=True) t = id_ctypes(r) if r.lbfw: t += ", %d" % r.lbfw S.append('("{}", {}),\n'.format(n, t) + pad) padded = True if padded: S.append(S.pop().strip()[:-1]) S.append("]") if len(anon) > 0: S.insert(0, "%s._anonymous_ = (%s,)\n" % (name, ",".join(anon))) return "".join(R) + "\n" + "".join(S)
def formatproto(res, proto): f = "CFUNCTYPE" params = [id_ctypes(c_type(x)) for x in proto.args] if res == "c_void": res = "None" params.insert(0, res) return "{}({})".format(f, ", ".join(params))
def build(obj, db, Types={}): for subtype in (obj.subtypes.values() or []): if subtype is None: continue build(subtype, db, Types) if obj._is_typedef: t = c_type(obj) Types[obj.identifier] = mk_ctypes(t, Types) return Types[obj.identifier] if obj._is_macro: v = obj.strip() try: v = int(v, base=0) except ValueError: pass globals()[obj.identifier] = v return v x = str(obj.identifier.replace('?_', '').replace(' ', '_')) if obj._is_enum: Types[x] = ctypes.c_int globals()[x] = {}.update(obj) elif obj._is_struct or obj._is_union: parent = ctypes.Structure if obj._is_union: parent = ctypes.Union Types[x] = type(x, (parent, ), {}) fmt = [] anon = [] for t, n, c in iter(obj): r = c_type(t) if '?_' in r.lbase: anon.append(n) if not n and not r.lbase.startswith('union '): continue bfw = r.lbfw r = mk_ctypes(r, Types) if bfw > 0: fmt.append((str(n), r, bfw)) else: fmt.append((str(n), r)) if len(anon) > 0: Types[x]._anonymous_ = tuple(anon) Types[x]._fields_ = fmt elif obj._is_class: x = obj.as_cStruct(db) x.unfold(db) return build(x, db) else: raise NotImplementedError return Types[x]
def cStruct_ctypes(obj, db, recursive): if isinstance(recursive, set): Q = True recursive.update(struct_letters) recursive.add(obj.identifier) else: Q = None name = id_ctypes(c_type(obj.identifier)) cls = 'Union' if obj._is_union else 'Structure' R = ["{0} = type('{0}',({1},),{{}})\n".format(name, cls)] anon = [] S = [] fld = '%s._fields_ = [' % name S.append(fld) pad = ' ' * len(fld) padded = False for i in obj: t, n, c = i r = c_type(t) if not n and not r.lbase.startswith('union '): continue if Q and (r.lbase not in recursive): q = (where('id') == r.lbase) if '?_' in r.lbase: anon.append('"%s"' % n) q &= (where('src') == obj.identifier) if db.contains(q): x = obj.from_db(db.get(q)).show(db, recursive, form='ctypes') x = x.split('\n') for xrl in x: if (xrl + '\n' in R) and not xrl.startswith(' '): continue if xrl: R.append(xrl + '\n') recursive.add(r.lbase) else: secho('identifier %s not found' % r.lbase, fg='red', err=True) t = id_ctypes(r) if r.lbfw: t += ', %d' % r.lbfw S.append('("{}", {}),\n'.format(n, t) + pad) padded = True if padded: S.append(S.pop().strip()[:-1]) S.append(']') if len(anon) > 0: S.insert(0, '%s._anonymous_ = (%s,)\n' % (name, ','.join(anon))) return ''.join(R) + '\n' + ''.join(S)
def get_c_or_cxx_type(x): if not ('&' in x): try: t = c_type(x) except pp.ParseException: pass else: return t t = cxx_type(x) return t
def cTypedef_ctypes(obj, db, recursive): pre = "" t = c_type(obj) if isinstance(recursive, set) and (t.lbase not in struct_letters): Q = db.tag & (where("id") == t.lbase) if db.contains(Q): x = obj.from_db(db.get(Q)) pre = x.show(db, recursive, form="ctypes") pre += "\n\n" else: secho("identifier %s not found" % t.lbase, fg="red", err=True) return u"{}{} = {}".format(pre, obj.identifier, id_ctypes(t))
def cTypedef_ctypes(obj, db, recursive): pre = '' t = c_type(obj) if isinstance(recursive, set) and (t.lbase not in struct_letters): Q = (where('id') == t.lbase) if db.contains(Q): x = obj.from_db(db.get(Q)) pre = x.show(db, recursive, form='ctypes') pre += '\n\n' else: secho("identifier %s not found" % t.lbase, fg='red', err=True) return u'{}{} = {}'.format(pre, obj.identifier, id_ctypes(t))
def unfold(self, db, limit=None, ctx=None): if self.subtypes is None: self.subtypes = OrderedDict() ctype = c_type(self) if limit != None: if limit <= 0 and ctype.is_ptr: return self elt = ctype.lbase if elt not in struct_letters: if limit: limit -= 1 self.add_subtype(db, elt, limit) return self
def unfold(self, db, limit=None): if self.subtypes is None: self.subtypes = OrderedDict() T = list(struct_letters.keys()) rett = self.restype() args = self.argtypes() args.insert(0, rett) for t in args: elt = c_type(t).lbase if (elt not in T): T.append(elt) self.add_subtype(db, elt) return self
def cStruct_amoco(obj, db, recursive): if isinstance(recursive, set): if obj.identifier in recursive: return "" Q = True recursive.update(tostruct) recursive.add(obj.identifier) else: Q = None name = id_amoco(obj.identifier) cls = "UnionDefine" if obj._is_union else "StructDefine" R = [] S = ['@{}("""\n'.format(cls)] for i in obj: t, n, c = i r = c_type(t) if not n and not r.lbase.startswith("union "): continue if Q and (r.lbase not in recursive): q = db.tag & (where("id") == r.lbase) if r.lbase.startswith("?_"): q &= where("src") == obj.identifier if db.contains(q): x = obj.from_db(db.get(q)) if x._is_typedef: pass x = x.show(db, recursive, form="amoco") x = x.split("\n") for xrl in x: if xrl: R.append(xrl + "\n") recursive.add(r.lbase) else: secho("identifier %s not found" % r.lbase, fg="red", err=True) rt, t = fieldformat(r) if rt: t = rt if c and c.count("\n") > 0: c = None S.append("{} : {} ;{}\n".format(t, n, c or "")) if len(R) > 0: R.append("\n") S.append('""")\nclass %s(StructFormatter):' % name) # add methods: S.append( """ def __init__(self,data="",offset=0): if data: self.unpack(data,offset) """ ) return "".join(R) + "".join(S)
def cFunc_ctypes(obj, db, recursive): f = 'CFUNCTYPE' pre = '' res = obj.restype() args = obj.argtypes() if isinstance(recursive, set): for t in [res] + args: t = c_type(t) if t.lbase not in struct_letters: Q = (where('id') == t.lbase) if db.contains(Q): x = obj.from_db(db.get(Q)) pre = x.show(db, recursive, form='ctypes') pre += '\n\n' else: secho("identifier %s not found" % t.lbase, fg='red', err=True) params = [id_ctypes(c_type(x)) for x in args] res = id_ctypes(c_type(res)) if res == 'c_void': res = 'None' params.insert(0, res) return '{} = {}({})'.format(obj.identifier, f, ', '.join(params))
def cTypedef_amoco(obj, db, recursive): pre = "" t = c_type(obj) if isinstance(recursive, set) and (t.lbase not in tostruct): recursive.add(obj.identifier) Q = db.tag & (where("id") == t.lbase) if db.contains(Q): x = obj.from_db(db.get(Q)) pre = x.show(db, recursive, form="amoco") pre += "\n\n" else: secho("identifier {} not found".format(t.lbase), fg="red", err=True) rn, n = fieldformat(t) return u"{}TypeDefine('{}','{}')".format(pre, obj.identifier, rn or n)
def cFunc_ctypes(obj, db, recursive): f = "CFUNCTYPE" pre = "" res = obj.restype() args = obj.argtypes() if isinstance(recursive, set): for t in [res] + args: t = c_type(t) if t.lbase not in struct_letters: Q = db.tag & (where("id") == t.lbase) if db.contains(Q): x = obj.from_db(db.get(Q)) pre = x.show(db, recursive, form="ctypes") pre += "\n\n" else: secho("identifier %s not found" % t.lbase, fg="red", err=True) params = [id_ctypes(c_type(x)) for x in args] res = id_ctypes(c_type(res)) if res == "c_void": res = "None" params.insert(0, res) return "{} = {}({})".format(obj.identifier, f, ", ".join(params))
def unfold(self, db, limit=None): if self.subtypes is None: self.subtypes = OrderedDict() T = list(struct_letters.keys()) T.append(self.identifier) for (t, n, c) in self: ctype = c_type(t) if limit != None: if limit <= 0 and ctype.is_ptr: continue elt = ctype.lbase if (elt not in T): T.append(elt) if limit: limit -= 1 self.add_subtype(db, elt, limit) return self
def cTypedef_C(obj, db, recursive): pre = '' t = c_type(obj) if isinstance(recursive, set) and (t.lbase not in struct_letters): Q = (where('id') == t.lbase) if db.contains(Q): x = obj.from_db(db.get(Q)) pre = x.show(db, recursive, form='C') + '\n' else: secho('identifier %s not found' % t.lbase, fg='red', err=True) # if t base is an anonymous type, we replace its anon name # by its struct/union definition in t: if recursive and '?_' in t.lbase: pre = pre.split('\n\n') t.lbase = pre.pop().strip(';\n') pre.append('') pre = '\n\n'.join(pre) return u'{}typedef {};'.format(pre, t.show(obj.identifier))
def cTypedef_C(obj, db, recursive): pre = "" t = c_type(obj) if isinstance(recursive, set) and (t.lbase not in struct_letters): recursive.add(obj.identifier) Q = db.tag & (where("id") == t.lbase) if db.contains(Q): x = obj.from_db(db.get(Q)) pre = x.show(db, recursive, form="C") + "\n" else: secho("identifier %s not found" % t.lbase, fg="red", err=True) # if t base is an anonymous type, we replace its anon name # by its struct/union definition in t: if recursive and "?_" in t.lbase: pre = pre.split("\n\n") t.lbase = pre.pop().strip(";\n") pre.append("") pre = "\n\n".join(pre) return u"{}typedef {};".format(pre, t.show(obj.identifier))
def cStruct_amoco(obj, db, recursive): if isinstance(recursive, set): Q = True recursive.update(tostruct) recursive.add(obj.identifier) else: Q = None name = id_amoco(obj.identifier) cls = 'UnionDefine' if obj._is_union else 'StructDefine' R = [] S = ['@{}("""\n'.format(cls)] for i in obj: t, n, c = i r = c_type(t) if not n and not r.lbase.startswith('union '): continue if Q and (r.lbase not in recursive): q = (where('id') == r.lbase) if r.lbase.startswith('?_'): q &= (where('src') == obj.identifier) if db.contains(q): x = obj.from_db(db.get(q)) if x._is_typedef: pass x = x.show(db, recursive, form='amoco') x = x.split('\n') for xrl in x: if xrl: R.append(xrl + '\n') recursive.add(r.lbase) else: secho('identifier %s not found' % r.lbase, fg='red', err=True) rt, t = fieldformat(r) if rt: t = rt S.append('{} : {} ;{}\n'.format(t, n, c or '')) if len(R) > 0: R.append('\n') S.append('""")\nclass %s(StructFormatter):' % name) # add methods: S.append(""" def __init__(self,data="",offset=0): if data: self.unpack(data,offset) """) return ''.join(R) + ''.join(S)
def argtypes(self): t = c_type(self) return t.pstack[-1].args
def restype(self): t = c_type(self) t.pstack.pop() return t.show()
def cStruct_C(obj, db, recursive): #declare structure: name = obj.identifier #prepare query if recursion is needed: if isinstance(recursive, set): Q = True recursive.update(struct_letters) recursive.add(name) else: Q = None tn = 'union ' if obj._is_union else 'struct ' #if anonymous, remove anonymous name: if '?_' in name: name = tn #R holds recursive definition strings needed for obj R = [] #S holds obj title and fields declaration strings S = [u'%s {' % name] #iterate through all fields: for i in obj: #get type, name, comment: t, n, c = i #decompose C-type t into specific parts: r = c_type(t) #get "element base" part of type t: e = r.lbase if not n and not e.startswith('union '): # -> union field are allowed to have no name... continue #query field element base type if recursive: # check if we are about to query the current struct type... if Q and (r.lbase == obj.identifier): R.append('%s;' % r.lbase) elif Q and (r.lbase not in recursive): #prepare query #(deal with the case of querying an anonymous type) q = (where('id') == r.lbase) if '?_' in r.lbase: q &= (where('src') == obj.identifier) #do the query and update R: if db.contains(q): #retreive the field type: x = obj.from_db(db.get(q)).show(db, recursive, form='C') if not '?_' in r.lbase: #if not anonymous, insert it directly in R #R.insert(0,x) R.append(x) recursive.add(r.lbase) else: # anonymous struct/union: we need to transfer # any predefs into R x = x.split('\n\n') r.lbase = x.pop().replace('\n', '\n ').strip(';') if len(x): xr = x[0].split('\n') for xrl in xr: if xrl and xrl not in R: #R.insert(0,xrl) R.append(xrl) else: secho('identifier %s not found' % r.lbase, fg='red', err=True) #finally add field type and name to the structure lines: S.append(u' {};'.format(r.show(n))) #join R and S: if len(R) > 0: R.append('\n') S.append('};') return '\n'.join(R) + '\n'.join(S)
def formatproto(res, proto, Types): params = [mk_ctypes(c_type(x), Types) for x in proto.args] params.insert(0, res) return ctypes.CFUNCTYPE(*params)
def cFunc_C(obj, db, recursive): fptr = c_type(obj["prototype"]) return fptr.show(obj.identifier) + ";"
def formatproto(res, proto): f = 'CFUNCTYPE' params = [id_ctypes(c_type(x)) for x in proto.args] if res == 'c_void': res = 'None' params.insert(0, res) return '{}({})'.format(f, ', '.join(params))
def cFunc_C(obj, db, recursive): fptr = c_type(obj) return fptr.show(obj.identifier) + ';'
def restype(self): t = c_type(self["prototype"]) if len(t.pstack) > 0: t.pstack.pop() return t.show()
def argtypes(self): t = c_type(self["prototype"]) if len(t.pstack) > 0: return t.pstack[-1].args return []
def cStruct_C(obj, db, recursive): # declare structure: name = obj.identifier # prepare query if recursion is needed: if isinstance(recursive, set): # if we are on a loop, just declare the struct name: if name in recursive: return "%s;" % name Q = True recursive.update(struct_letters) recursive.add(name) else: Q = None tn = "union " if obj._is_union else "struct " # if anonymous, remove anonymous name: if "?_" in name: name = tn # R holds recursive definition strings needed for obj R = [] # S holds obj title and fields declaration strings S = [u"%s {" % name] # iterate through all fields: for i in obj: # get type, name, comment: t, n, c = i # decompose C-type t into specific parts: r = c_type(t) # get "element base" part of type t: e = r.lbase if not n and not e.startswith("union "): # -> union field are allowed to have no name... continue # query field element base type if recursive: # check if we are about to query the current struct type... if Q and (r.lbase == obj.identifier): R.append("%s;" % r.lbase) elif Q and (r.lbase not in recursive): # prepare query # (deal with the case of querying an anonymous type) q = db.tag & (where("id") == r.lbase) if "?_" in r.lbase: q &= where("src") == obj.identifier # do the query and update R: if db.contains(q): # retreive the field type: x = obj.from_db(db.get(q)).show(db, recursive, form="C") if not "?_" in r.lbase: # if not anonymous, insert it directly in R # R.insert(0,x) R.append(x) recursive.add(r.lbase) else: # anonymous struct/union: we need to transfer # any predefs into R x = x.split("\n\n") r.lbase = x.pop().replace("\n", "\n ").strip(";") if len(x): xr = x[0].split("\n") for xrl in xr: if xrl and xrl not in R: # R.insert(0,xrl) R.append(xrl) else: secho("identifier %s not found" % r.lbase, fg="red", err=True) # finally add field type and name to the structure lines: S.append(u" {};".format(r.show(n))) # join R and S: if len(R) > 0: R.append("\n") S.append("};") return "\n".join(R) + "\n".join(S)
def struct(ctx, pdef, conds): """Get structured definitions (struct, union or class) from the remote database (or the local database if no remote is found) matching constraints on total size or specific type name or size at given offset within the structure. """ reqs = {} try: for p in conds: off, t = p.split(':') if off == '*': sz = int(t) reqs[off] = sz else: off = int(off) if t[0] == '+': reqs[off] = int(t) elif t[0] == '?': reqs[off] = t else: reqs[off] = c_type(t) except Exception: click.secho('invalid arguments', fg='red', err=True) return db = ctx.obj['db'] Q = ctx.obj.get('select', Query().noop()) L = db.search(Q & ((where('cls') == 'cStruct') | (where('cls') == 'cClass'))) R = [] fails = [] with click.progressbar(L) as pL: for l in pL: x = ccore.from_db(l) ctcls = c_type try: if x._is_class: x = x.as_cStruct(db) t = x.build(db) except Exception: fails.append("can't build %s" % x.identifier) continue F = [] for i, f in enumerate(t._fields_): field = getattr(t, f[0]) F.append((field.offset, field.size, ctcls(x[i][0]))) if F: xsize = F[-1][0] + F[-1][1] if '*' in reqs and reqs['*'] != xsize: continue F = dict(((f[0], f[1:3]) for f in F)) ok = [] for o, s in reqs.items(): if o == '*': continue cond = (o in F) ok.append(cond) if not cond: break if s == '?': continue if s == '*': cond = (F[o][1].is_ptr) elif isinstance(s, c_type): cond = (F[o][1].show() == s.show()) else: cond = (F[o][0] == s) ok.append(cond) if not cond: break if all(ok): if not pdef: res = x.identifier else: res = x.show(db, form='C') R.append(res) if conf.VERBOSE: click.secho(u'\n'.join(fails), fg='red', err=True) if R: click.echo('\n'.join(R))