func (st *State) addInput(mgr *Manager, input []byte) { if _, err := prog.CallSet(input); err != nil { Logf(0, "manager %v: failed to extract call set: %v, program:\n%v", mgr.name, err, string(input)) return } sig := hash.Hash(input) mgr.Corpus[sig] = true fname := filepath.Join(mgr.dir, "corpus", sig.String()) writeFile(fname, nil) if st.Corpus[sig] == nil { st.Corpus[sig] = &Input{ seq: st.seq, prog: input, } fname := filepath.Join(st.dir, "corpus", fmt.Sprintf("%v-%v", sig.String(), st.seq)) writeFile(fname, input) } }
func (st *State) pendingInputs(mgr *Manager) ([][]byte, error) { if mgr.seq == st.seq { return nil, nil } var inputs [][]byte for sig, inp := range st.Corpus { if mgr.seq > inp.seq || mgr.Corpus[sig] { continue } calls, err := prog.CallSet(inp.prog) if err != nil { return nil, fmt.Errorf("failed to extract call set: %v\nprogram: %v", err, string(inp.prog)) } if !managerSupportsAllCalls(mgr.Calls, calls) { continue } inputs = append(inputs, inp.prog) } mgr.seq = st.seq writeFile(filepath.Join(mgr.dir, "seq"), []byte(fmt.Sprint(mgr.seq))) return inputs, nil }
// Make creates State and initializes it from dir. func Make(dir string) (*State, error) { st := &State{ dir: dir, Corpus: make(map[hash.Sig]*Input), Managers: make(map[string]*Manager), } corpusDir := filepath.Join(st.dir, "corpus") os.MkdirAll(corpusDir, 0700) inputs, err := ioutil.ReadDir(corpusDir) if err != nil { return nil, fmt.Errorf("failed to read %v dir: %v", corpusDir, err) } for _, inp := range inputs { data, err := ioutil.ReadFile(filepath.Join(corpusDir, inp.Name())) if err != nil { return nil, err } if _, err := prog.CallSet(data); err != nil { return nil, err } parts := strings.Split(inp.Name(), "-") if len(parts) != 2 { return nil, fmt.Errorf("bad file in corpus: %v", inp.Name()) } seq, err := strconv.ParseUint(parts[1], 10, 64) if err != nil { return nil, fmt.Errorf("bad file in corpus: %v", inp.Name()) } sig := hash.Hash(data) if sig.String() != parts[0] { return nil, fmt.Errorf("bad file in corpus: %v, want hash %v", inp.Name(), sig.String()) } st.Corpus[sig] = &Input{ seq: seq, prog: data, } if st.seq < seq { st.seq = seq } } managersDir := filepath.Join(st.dir, "manager") os.MkdirAll(managersDir, 0700) managers, err := ioutil.ReadDir(managersDir) if err != nil { return nil, fmt.Errorf("failed to read %v dir: %v", managersDir, err) } for _, manager := range managers { mgr := &Manager{ name: manager.Name(), } st.Managers[mgr.name] = mgr mgr.dir = filepath.Join(managersDir, mgr.name) seqStr, _ := ioutil.ReadFile(filepath.Join(mgr.dir, "seq")) mgr.seq, _ = strconv.ParseUint(string(seqStr), 10, 64) if st.seq < mgr.seq { st.seq = mgr.seq } mgr.Corpus = make(map[hash.Sig]bool) corpusDir := filepath.Join(mgr.dir, "corpus") os.MkdirAll(corpusDir, 0700) corpus, err := ioutil.ReadDir(corpusDir) if err != nil { return nil, fmt.Errorf("failed to read %v dir: %v", corpusDir, err) } for _, input := range corpus { sig, err := hash.FromString(input.Name()) if err != nil { return nil, fmt.Errorf("bad file in corpus: %v", input.Name()) } mgr.Corpus[sig] = true } } return st, err }