def add_line(self, line, linenum): for e, action in self.ctx_list: if re.match(e, line): action(self.ctx) for e, cond in self.re_list: if cond is not None and not cond(self.ctx): continue res = re.match(e, line) if not res: continue res = Attributize(res.groupdict()) for k, v in res.items(): for hook in self.hooks[k]: v = hook(v) res[k] = v ins = self.get(res.addr) ins.line = linenum for k, v in res.items(): if k in ins: ins[k] = v break
class YamlStructBuilder: def __init__(self): self.typs = build_core_types() self.typs_to_build = Attributize(key_norm=byte_norm) self.gbl = {} def add_typ(self, name, typ): self.typs[name] = typ def add_yaml(self, s): res = yaml.load(s) res = Attributize.RecursiveImport(res) self.typs_to_build.update(res._elem) def build(self): for k, v in self.typs_to_build.items(): if k == 'global': self.gbl = v continue self.build_typ(k, v) def get_typ(self, typ_name): if typ_name in self.typs: return self.typs[typ_name] if typ_name in self.typs_to_build: return self.build_typ(typ_name, self.typs_to_build[typ_name]) assert typ_name.endswith('*') != -1, 'Bad typ %s' % typ_name base_type = self.get_typ(typ_name[:-1]) ntype = base_type.make_ptr() self.add_typ(typ_name, ntype) return ntype def build_typ(self, name, desc): # prevent loops self.typs[name] = None res = YamlType(name, desc, self) self.add_typ(name, res) return res
class YamlViewBuilder: def __init__(self): self.typs = Attributize(key_norm=byte_norm) self.add_core_types() self.typs_to_build = Attributize(key_norm=byte_norm) def add_core_types(self): for name, typ in types_helper.by_name.items(): self.typs[name] = OpaCoreType(typ) def add_yaml(self, s): res = yaml.load(s) res = Attributize.RecursiveImport(res) self.typs_to_build.update(res._elem) def build(self): for k, v in self.typs_to_build.items(): if k == 'global': continue self.build_typ(k, v) def get_typ(self, typ_name): if typ_name in self.typs: return self.typs[typ_name] assert typ_name in self.typs_to_build return self.build_typ(typ_name, self.typs_to_build[typ_name]) def build_typ(self, name, desc): # prevent loops self.typs[name] = None res = YamlType(name, desc, self) self.typs[name] = res return res @staticmethod def FromYamlFile(): pass
class SyscallData(): def __init__(self, arch): self.arch = arch self.vals = {} self.entries = Attributize() self.by_num = {} self.consts = Attributize() self.builder = StructBuilder() self.builder.content += ''' #include <unistd.h> ''' self.builder.add_extractor( SimpleStructExtractor('asm/signal.h', 'SIG sigset')) self.builder.add_extractor( SimpleStructExtractor('asm/mman.h', 'MAP_ PROT_')) self.builder.add_extractor(SimpleStructExtractor('asm/prctl.h', 'PR_')) self.builder.add_extractor( SimpleStructExtractor('asm/prctl.h', 'ARCH_')) self.builder.add_extractor( SimpleStructExtractor('unistd.h', 'write stat read')) self.builder.add_extractor( SimpleStructExtractor('fcntl.h', 'open openat')) self.builder.setup_includes() def add_syscall_num(self, name, val): self.vals[name] = val def add_entry(self, data): assert data.syscall_name in self.vals, 'Fail for arch={}, func={}'.format( self.arch, data.func_name) data.syscall_num = self.vals[data.syscall_name] data = data._do_clone() self.entries[data.func_name] = data self.entries[data.syscall_name] = data self.by_num[data.syscall_num] = data def build(self): # why is that existing? def build_func_name(name): return name + '__OPA_DECL' to_proc = {} for func_name, entry in self.entries.items(): if len(entry.params_list) == 0: entry.args = [] continue nfunc_name = build_func_name(func_name) self.builder.content.append(''' {return_val} {func_name}({func_args}); '''.format(return_val=entry.return_val, func_name=nfunc_name, func_args=','.join(entry.params_list))) to_proc[nfunc_name] = entry self.builder.build(extra_args=['-std=c++11']) for func_name, func in self.builder.res.functions.items(): # updating entry with args from function func_name = build_func_name(func_name) if not func_name in to_proc: continue entry = to_proc[func_name] entry.args = func.args entry.function = func