def condition(self): """Return the isomorphism condition.""" conds = list(self.__conds) for rep_map in self.__repmaps.itervalues(): distinct = [] for reps in rep_map.itervalues(): reps = list(reps) # Require each representative group to be distinct distinct.append(reps[0]) # Require all expressions within the representative # group to be equal conds.append(simsym.symeq(*reps)) if len(distinct) > 1: conds.append(simsym.distinct(*distinct)) return simsym.symand(conds)
def setup_proc(self, pid, fdmap, vamap, pipe_end_fds): emit = self.emit emit('int fd __attribute__((unused));', 'int r __attribute__((unused));') for fd, (symfd, inode) in fdmap.items(): if symfd.ispipe: pipe_setup_fd = self.pipes[symfd.pipeid] if symfd.pipewriter: pipe_setup_fd += 1 emit('r = dup2(%d, %d);' % (pipe_setup_fd, fd), 'if (r < 0) setup_error("dup2");') else: emit('fd = open("%s", O_RDWR);' % self.inums[symfd.inum].fname, 'if (fd < 0) setup_error("open");', 'r = lseek(fd, %d, SEEK_SET);' % (inode.offsets[symfd.off]), 'if (fd >= 0 && r < 0) setup_error("lseek");', 'r = dup2(fd, %d);' % fd, 'if (fd >= 0 && r < 0) setup_error("dup2");', 'close(fd);') # There may be other FDs open to pipes that never came up in the # test, but that matter to keep the pipe open. Check for this # possibility for every pipe end. for (_, pipewriter), (pipeid, pidcounts) in pipe_end_fds.items(): # How many of this end are already set up in this process? knowncount = pidcounts[pid] # Try to find > knowncount distinct instances of this end in # this process. conds = [] distinct = [] sym_fd_map = self.fs.getproc(pid).fd_map for i in range(knowncount + 1): ofdnum = fs_module.SFdNum.var() ofd = sym_fd_map._map[ofdnum] conds.extend([sym_fd_map._valid[ofdnum], ofd.ispipe, ofd.pipeid == pipeid, ofd.pipewriter == pipewriter]) distinct.append(ofdnum) if len(distinct) > 1: conds.append(simsym.distinct(*distinct)) # XXX I've tried to *prove* that the path condition implies # there *must* be more FDs for this pipe end, so the decision # will stand regardless of choices made by model completion, but # I just can't get it to work: # prove(simsym.implies(self.constraint, # simsym.exists(ofdnums, simsym.symand(conds)))) result = simsym.check(simsym.symand([self.constraint] + conds)) if result.is_unknown: print 'Warning: Unable to check pipe FD existence:', result.reason elif result.is_sat: # Open up another pipe end pipe_setup_fd = self.pipes[pipeid] if pipewriter: pipe_setup_fd += 1 emit('r = dup(%d);' % pipe_setup_fd, 'if (r < 0) setup_error("dup");') for va, vainfo in vamap.items(): if vainfo.anon: emit('init_map_anon(%#x, %d, %d);' % (va, vainfo.writable.val, self.datavals[vainfo.anondata].first_byte)) else: inode = self.inums[vainfo.inum] emit('init_map_file(%#x, %d, "%s", %#x);' % (va, vainfo.writable.val, inode.fname, inode.offsets[vainfo.off]))
def setup_proc(self, pid, fdmap, vamap, pipe_end_fds): emit = self.emit emit("int fd __attribute__((unused));", "int r __attribute__((unused));") for fd, (symfd, inode) in fdmap.items(): if symfd.ispipe: pipe_setup_fd = self.pipes[symfd.pipeid] if symfd.pipewriter: pipe_setup_fd += 1 emit("r = dup2(%d, %d);" % (pipe_setup_fd, fd), 'if (r < 0) setup_error("dup2");') else: emit( 'fd = open("%s", O_RDWR);' % self.inums[symfd.inum].fname, 'if (fd < 0) setup_error("open");', "r = lseek(fd, %d, SEEK_SET);" % (inode.offsets[symfd.off]), 'if (fd >= 0 && r < 0) setup_error("lseek");', "r = dup2(fd, %d);" % fd, 'if (fd >= 0 && r < 0) setup_error("dup2");', "close(fd);", ) # There may be other FDs open to pipes that never came up in the # test, but that matter to keep the pipe open. Check for this # possibility for every pipe end. for (_, pipewriter), (pipeid, pidcounts) in pipe_end_fds.items(): # How many of this end are already set up in this process? knowncount = pidcounts[pid] # Try to find > knowncount distinct instances of this end in # this process. conds = [] distinct = [] sym_fd_map = self.fs.getproc(pid).fd_map for i in range(knowncount + 1): ofdnum = fs_module.SFdNum.var() ofd = sym_fd_map._map[ofdnum] conds.extend( [sym_fd_map._valid[ofdnum], ofd.ispipe, ofd.pipeid == pipeid, ofd.pipewriter == pipewriter] ) distinct.append(ofdnum) if len(distinct) > 1: conds.append(simsym.distinct(*distinct)) # XXX I've tried to *prove* that the path condition implies # there *must* be more FDs for this pipe end, so the decision # will stand regardless of choices made by model completion, but # I just can't get it to work: # prove(simsym.implies(self.constraint, # simsym.exists(ofdnums, simsym.symand(conds)))) result = simsym.check(simsym.symand([self.constraint] + conds)) if result.is_unknown: print "Warning: Unable to check pipe FD existence:", result.reason elif result.is_sat: # Open up another pipe end pipe_setup_fd = self.pipes[pipeid] if pipewriter: pipe_setup_fd += 1 emit("r = dup(%d);" % pipe_setup_fd, 'if (r < 0) setup_error("dup");') for va, vainfo in vamap.items(): if vainfo.anon: emit( "init_map_anon(%#x, %d, %d);" % (va, vainfo.writable.val, self.datavals[vainfo.anondata].first_byte) ) else: inode = self.inums[vainfo.inum] emit( 'init_map_file(%#x, %d, "%s", %#x);' % (va, vainfo.writable.val, inode.fname, inode.offsets[vainfo.off]) )