| 247 | } |
| 248 | |
| 249 | int CollectDataFlow(const std::string &DFTBinary, const std::string &DirPath, |
| 250 | const std::vector<SizedFile> &CorporaFiles) { |
| 251 | Printf("INFO: collecting data flow: bin: %s dir: %s files: %zd\n", |
| 252 | DFTBinary.c_str(), DirPath.c_str(), CorporaFiles.size()); |
| 253 | if (CorporaFiles.empty()) { |
| 254 | Printf("ERROR: can't collect data flow without corpus provided."); |
| 255 | return 1; |
| 256 | } |
| 257 | |
| 258 | static char DFSanEnv[] = "DFSAN_OPTIONS=warn_unimplemented=0"; |
| 259 | putenv(DFSanEnv); |
| 260 | MkDir(DirPath); |
| 261 | for (auto &F : CorporaFiles) { |
| 262 | // For every input F we need to collect the data flow and the coverage. |
| 263 | // Data flow collection may fail if we request too many DFSan tags at once. |
| 264 | // So, we start from requesting all tags in range [0,Size) and if that fails |
| 265 | // we then request tags in [0,Size/2) and [Size/2, Size), and so on. |
| 266 | // Function number => DFT. |
| 267 | auto OutPath = DirPlusFile(DirPath, Hash(FileToVector(F.File))); |
| 268 | std::unordered_map<size_t, std::vector<uint8_t>> DFTMap; |
| 269 | std::unordered_set<std::string> Cov; |
| 270 | Command Cmd; |
| 271 | Cmd.addArgument(DFTBinary); |
| 272 | Cmd.addArgument(F.File); |
| 273 | Cmd.addArgument(OutPath); |
| 274 | Printf("CMD: %s\n", Cmd.toString().c_str()); |
| 275 | ExecuteCommand(Cmd); |
| 276 | } |
| 277 | // Write functions.txt if it's currently empty or doesn't exist. |
| 278 | auto FunctionsTxtPath = DirPlusFile(DirPath, kFunctionsTxt); |
| 279 | if (FileToString(FunctionsTxtPath).empty()) { |
| 280 | Command Cmd; |
| 281 | Cmd.addArgument(DFTBinary); |
| 282 | Cmd.setOutputFile(FunctionsTxtPath); |
| 283 | ExecuteCommand(Cmd); |
| 284 | } |
| 285 | return 0; |
| 286 | } |
| 287 | |
| 288 | } // namespace fuzzer |
no test coverage detected