comparison tools/fanalyze.c @ 2586:9807ae37ad69

Require stdbool.h, we require C11 now.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 08 Dec 2022 15:59:22 +0200
parents 9f26a93d7e70
children 81f45b2fa118
comparison
equal deleted inserted replaced
2585:ef6c826c5b7a 2586:9807ae37ad69
49 { 49 {
50 char *filename; 50 char *filename;
51 Uint8 *data; 51 Uint8 *data;
52 size_t size; 52 size_t size;
53 DMStats stats; 53 DMStats stats;
54 BOOL analyzed; 54 bool analyzed;
55 size_t index; 55 size_t index;
56 } DMSourceFile; 56 } DMSourceFile;
57 57
58 58
59 typedef struct 59 typedef struct
98 { 98 {
99 int type; 99 int type;
100 int disp; 100 int disp;
101 int nvalues; 101 int nvalues;
102 Uint32 values[SET_MAX_GREP_LIST]; 102 Uint32 values[SET_MAX_GREP_LIST];
103 BOOL vwildcards[SET_MAX_GREP_LIST]; 103 bool vwildcards[SET_MAX_GREP_LIST];
104 } DMGrepValue; 104 } DMGrepValue;
105 105
106 106
107 typedef struct 107 typedef struct
108 { 108 {
154 DMSourceFile srcFiles[SET_MAX_FILES]; // Source file names 154 DMSourceFile srcFiles[SET_MAX_FILES]; // Source file names
155 DMStats totalStats; 155 DMStats totalStats;
156 int nsetGrepValues = 0; 156 int nsetGrepValues = 0;
157 DMGrepValue setGrepValues[SET_MAX_GREP_VALUES]; 157 DMGrepValue setGrepValues[SET_MAX_GREP_VALUES];
158 size_t optMinMatchLen = 8; 158 size_t optMinMatchLen = 8;
159 BOOL optOffsetMode = FALSE; 159 bool optOffsetMode = false;
160 160
161 DMMatchSeq dmSequences[SET_MAX_SEQUENCES]; 161 DMMatchSeq dmSequences[SET_MAX_SEQUENCES];
162 int ndmSequences = 0; 162 int ndmSequences = 0;
163 163
164 164
202 "under development.\n" 202 "under development.\n"
203 ); 203 );
204 } 204 }
205 205
206 206
207 BOOL dmGetData(const int type, const DMSourceFile *file, const size_t offs, Uint32 *mval) 207 bool dmGetData(const int type, const DMSourceFile *file, const size_t offs, Uint32 *mval)
208 { 208 {
209 Uint8 *data = file->data + offs; 209 Uint8 *data = file->data + offs;
210 if (offs + dmGrepTypes[type].bsize >= file->size) 210 if (offs + dmGrepTypes[type].bsize >= file->size)
211 { 211 {
212 *mval = 0; 212 *mval = 0;
213 return FALSE; 213 return false;
214 } 214 }
215 215
216 switch (type) 216 switch (type)
217 { 217 {
218 case DMGV_UINT8: 218 case DMGV_UINT8:
235 *mval = DM_BE32_TO_NATIVE(*((Uint32 *) data)); 235 *mval = DM_BE32_TO_NATIVE(*((Uint32 *) data));
236 break; 236 break;
237 237
238 default: 238 default:
239 *mval = 0; 239 *mval = 0;
240 return FALSE; 240 return false;
241 } 241 }
242 return TRUE; 242 return true;
243 } 243 }
244 244
245 245
246 void dmPrintGrepValueList(FILE *fh, const DMGrepValue *node, const BOOL match, DMSourceFile *file, const size_t offs) 246 void dmPrintGrepValueList(FILE *fh, const DMGrepValue *node, const bool match, DMSourceFile *file, const size_t offs)
247 { 247 {
248 char mfmt[16]; 248 char mfmt[16];
249 unsigned int bsize = dmGrepTypes[node->type].bsize; 249 unsigned int bsize = dmGrepTypes[node->type].bsize;
250 250
251 snprintf(mfmt, sizeof(mfmt), "%%%s%d%s%%s", 251 snprintf(mfmt, sizeof(mfmt), "%%%s%d%s%%s",
278 { 278 {
279 const char *specsep = strchr(arg, ':'); 279 const char *specsep = strchr(arg, ':');
280 char *vspec, *vstr, *vsep; 280 char *vspec, *vstr, *vsep;
281 DMGrepValue val; 281 DMGrepValue val;
282 int ret = DMERR_OK; 282 int ret = DMERR_OK;
283 BOOL more; 283 bool more;
284 284
285 memset(&val, 0, sizeof(val)); 285 memset(&val, 0, sizeof(val));
286 286
287 if (setMode != FA_ANALYZE && setMode != mode) 287 if (setMode != FA_ANALYZE && setMode != mode)
288 { 288 {
304 } 304 }
305 305
306 // Parse spec if any 306 // Parse spec if any
307 if (vspec != NULL) 307 if (vspec != NULL)
308 { 308 {
309 BOOL vendianess = TRUE; 309 bool vendianess = true;
310 char *vtmp = vspec; 310 char *vtmp = vspec;
311 311
312 // Get endianess specifier, if any 312 // Get endianess specifier, if any
313 if (strncasecmp(vtmp, "le", 2) == 0) 313 if (strncasecmp(vtmp, "le", 2) == 0)
314 { 314 {
315 vendianess = TRUE; 315 vendianess = true;
316 vtmp += 2; 316 vtmp += 2;
317 } 317 }
318 else 318 else
319 if (strncasecmp(vtmp, "be", 2) == 0) 319 if (strncasecmp(vtmp, "be", 2) == 0)
320 { 320 {
321 vendianess = FALSE; 321 vendianess = false;
322 vtmp += 2; 322 vtmp += 2;
323 } 323 }
324 324
325 // Get value bit size 325 // Get value bit size
326 if (strncmp(vtmp, "8", 1) == 0) 326 if (strncmp(vtmp, "8", 1) == 0)
382 } 382 }
383 383
384 if ((vsep = strchr(vtmp, ',')) != NULL) 384 if ((vsep = strchr(vtmp, ',')) != NULL)
385 { 385 {
386 *vsep = 0; 386 *vsep = 0;
387 more = TRUE; 387 more = true;
388 } 388 }
389 else 389 else
390 more = FALSE; 390 more = false;
391 391
392 if (vtmp[0] == '#' || vtmp[0] == '?') 392 if (vtmp[0] == '#' || vtmp[0] == '?')
393 { 393 {
394 val.vwildcards[val.nvalues] = TRUE; 394 val.vwildcards[val.nvalues] = true;
395 if (mode == FA_OFFSET) 395 if (mode == FA_OFFSET)
396 { 396 {
397 ret = dmError(DMERR_INVALID_ARGS, 397 ret = dmError(DMERR_INVALID_ARGS,
398 "Offset mode does not allow wildcard values.\n"); 398 "Offset mode does not allow wildcard values.\n");
399 goto out; 399 goto out;
469 if (mode == FA_GREP) 469 if (mode == FA_GREP)
470 { 470 {
471 printf("Grep %s: ", 471 printf("Grep %s: ",
472 dmGrepTypes[val.type].desc); 472 dmGrepTypes[val.type].desc);
473 473
474 dmPrintGrepValueList(stdout, node, FALSE, NULL, 0); 474 dmPrintGrepValueList(stdout, node, false, NULL, 0);
475 printf("\n"); 475 printf("\n");
476 } 476 }
477 } 477 }
478 else 478 else
479 { 479 {
487 dmFree(vstr); 487 dmFree(vstr);
488 return ret; 488 return ret;
489 } 489 }
490 490
491 491
492 BOOL argHandleOpt(const int optN, char *optArg, char *currArg) 492 bool argHandleOpt(const int optN, char *optArg, char *currArg)
493 { 493 {
494 switch (optN) 494 switch (optN)
495 { 495 {
496 case 0: 496 case 0:
497 argShowHelp(); 497 argShowHelp();
521 optMinMatchLen = atoi(optArg); 521 optMinMatchLen = atoi(optArg);
522 if (optMinMatchLen < 2 || optMinMatchLen > 16*1024) 522 if (optMinMatchLen < 2 || optMinMatchLen > 16*1024)
523 { 523 {
524 dmErrorMsg("Invalid minimum match length '%s'.\n", 524 dmErrorMsg("Invalid minimum match length '%s'.\n",
525 optArg); 525 optArg);
526 return FALSE; 526 return false;
527 } 527 }
528 return TRUE; 528 return true;
529 529
530 case 18: 530 case 18:
531 optOffsetMode = TRUE; 531 optOffsetMode = true;
532 break; 532 break;
533 533
534 default: 534 default:
535 dmErrorMsg("Unknown argument '%s'.\n", currArg); 535 dmErrorMsg("Unknown argument '%s'.\n", currArg);
536 return FALSE; 536 return false;
537 } 537 }
538 538
539 return TRUE; 539 return true;
540 } 540 }
541 541
542 542
543 BOOL argHandleNonOpt(char *currArg) 543 bool argHandleNonOpt(char *currArg)
544 { 544 {
545 if (nsrcFiles < SET_MAX_FILES) 545 if (nsrcFiles < SET_MAX_FILES)
546 { 546 {
547 DMSourceFile *file = &srcFiles[nsrcFiles]; 547 DMSourceFile *file = &srcFiles[nsrcFiles];
548 file->filename = currArg; 548 file->filename = currArg;
549 file->index = nsrcFiles; 549 file->index = nsrcFiles;
550 nsrcFiles++; 550 nsrcFiles++;
551 return TRUE; 551 return true;
552 } 552 }
553 else 553 else
554 { 554 {
555 dmErrorMsg("Maximum number of input files exceeded (%d).\n", 555 dmErrorMsg("Maximum number of input files exceeded (%d).\n",
556 SET_MAX_FILES); 556 SET_MAX_FILES);
557 return TRUE; 557 return true;
558 } 558 }
559 } 559 }
560 560
561 561
562 void dmInitStats(DMStats *stats) 562 void dmInitStats(DMStats *stats)
589 } 589 }
590 printf("\n\n"); 590 printf("\n\n");
591 } 591 }
592 592
593 593
594 BOOL dmAddMatchSequence(Uint8 *data, const size_t len, DMSourceFile *file, size_t offs) 594 bool dmAddMatchSequence(Uint8 *data, const size_t len, DMSourceFile *file, size_t offs)
595 { 595 {
596 DMMatchSeq *seq = NULL; 596 DMMatchSeq *seq = NULL;
597 597
598 // Check for existing match sequence 598 // Check for existing match sequence
599 for (int n = 0; n < ndmSequences; n++) 599 for (int n = 0; n < ndmSequences; n++)
611 { 611 {
612 // No sequence found, add a new one 612 // No sequence found, add a new one
613 if (ndmSequences + 1 >= SET_MAX_SEQUENCES) 613 if (ndmSequences + 1 >= SET_MAX_SEQUENCES)
614 { 614 {
615 dmErrorMsg("Too many matching sequences found.\n"); 615 dmErrorMsg("Too many matching sequences found.\n");
616 return FALSE; 616 return false;
617 } 617 }
618 618
619 seq = &dmSequences[ndmSequences++]; 619 seq = &dmSequences[ndmSequences++];
620 } 620 }
621 else 621 else
624 for (int n = 0; n < seq->nplaces; n++) 624 for (int n = 0; n < seq->nplaces; n++)
625 { 625 {
626 DMMatchPlace *place = &seq->places[n]; 626 DMMatchPlace *place = &seq->places[n];
627 if (place->file == file && 627 if (place->file == file &&
628 place->offs + seq->len == offs + len) 628 place->offs + seq->len == offs + len)
629 return TRUE; 629 return true;
630 } 630 }
631 } 631 }
632 632
633 seq->data = data; 633 seq->data = data;
634 seq->len = len; 634 seq->len = len;
638 { 638 {
639 DMMatchPlace *place = &seq->places[seq->nplaces++]; 639 DMMatchPlace *place = &seq->places[seq->nplaces++];
640 place->file = file; 640 place->file = file;
641 place->offs = offs; 641 place->offs = offs;
642 642
643 return TRUE; 643 return true;
644 } 644 }
645 else 645 else
646 return FALSE; 646 return false;
647 } 647 }
648 648
649 649
650 int dmCompareMatchPlaces(const void *pa, const void *pb) 650 int dmCompareMatchPlaces(const void *pa, const void *pb)
651 { 651 {
658 658
659 int main(int argc, char *argv[]) 659 int main(int argc, char *argv[])
660 { 660 {
661 DMCompElem *compBuf = NULL; 661 DMCompElem *compBuf = NULL;
662 size_t compBufSize = 0, totalSize = 0, fileFlagsSize; 662 size_t compBufSize = 0, totalSize = 0, fileFlagsSize;
663 BOOL *fileFlags = NULL; 663 bool *fileFlags = NULL;
664 int res; 664 int res;
665 665
666 memset(&dmSequences, 0, sizeof(dmSequences)); 666 memset(&dmSequences, 0, sizeof(dmSequences));
667 667
668 dmInitProg("fanalyze", 668 dmInitProg("fanalyze",
684 "No input file(s) specified.\n"); 684 "No input file(s) specified.\n");
685 goto out; 685 goto out;
686 } 686 }
687 687
688 // Allocate file flags 688 // Allocate file flags
689 fileFlagsSize = sizeof(BOOL) * nsrcFiles; 689 fileFlagsSize = sizeof(bool) * nsrcFiles;
690 if ((fileFlags = dmMalloc(fileFlagsSize)) == NULL) 690 if ((fileFlags = dmMalloc(fileFlagsSize)) == NULL)
691 { 691 {
692 dmErrorMsg("Could not allocate %" DM_PRIu_SIZE_T " bytes of memory for file flag array.\n", 692 dmErrorMsg("Could not allocate %" DM_PRIu_SIZE_T " bytes of memory for file flag array.\n",
693 fileFlagsSize); 693 fileFlagsSize);
694 goto out; 694 goto out;
728 728
729 for (int n = 0; n < nsetGrepValues; n++) 729 for (int n = 0; n < nsetGrepValues; n++)
730 { 730 {
731 DMGrepValue *node = &setGrepValues[n]; 731 DMGrepValue *node = &setGrepValues[n];
732 const DMGrepType *def = &dmGrepTypes[node->type]; 732 const DMGrepType *def = &dmGrepTypes[node->type];
733 BOOL sep = FALSE; 733 bool sep = false;
734 734
735 if (optOffsetMode) 735 if (optOffsetMode)
736 { 736 {
737 printf("%s %s -o ", 737 printf("%s %s -o ",
738 argv[0], file->filename); 738 argv[0], file->filename);
739 } 739 }
740 740
741 for (size_t offs = 0; offs + (def->bsize * node->nvalues) < file->size; offs++) 741 for (size_t offs = 0; offs + (def->bsize * node->nvalues) < file->size; offs++)
742 { 742 {
743 BOOL match = TRUE; 743 bool match = true;
744 for (int n = 0; n < node->nvalues; n++) 744 for (int n = 0; n < node->nvalues; n++)
745 if (!node->vwildcards[n]) 745 if (!node->vwildcards[n])
746 { 746 {
747 Uint32 mval; 747 Uint32 mval;
748 dmGetData(node->type, file, offs + n * def->bsize, &mval); 748 dmGetData(node->type, file, offs + n * def->bsize, &mval);
749 749
750 if (mval != node->values[n]) 750 if (mval != node->values[n])
751 { 751 {
752 match = FALSE; 752 match = false;
753 break; 753 break;
754 } 754 }
755 } 755 }
756 756
757 if (match) 757 if (match)
758 { 758 {
759 if (optOffsetMode) 759 if (optOffsetMode)
760 { 760 {
761 printf("%s0x%" DM_PRIx_SIZE_T, sep ? "," : "", offs); 761 printf("%s0x%" DM_PRIx_SIZE_T, sep ? "," : "", offs);
762 sep = TRUE; 762 sep = true;
763 } 763 }
764 else 764 else
765 printf("%08" DM_PRIx_SIZE_T, offs); 765 printf("%08" DM_PRIx_SIZE_T, offs);
766 766
767 if (!optOffsetMode) 767 if (!optOffsetMode)
768 { 768 {
769 if (dmVerbosity >= 1) 769 if (dmVerbosity >= 1)
770 { 770 {
771 printf(" : "); 771 printf(" : ");
772 dmPrintGrepValueList(stdout, node, TRUE, file, offs); 772 dmPrintGrepValueList(stdout, node, true, file, offs);
773 } 773 }
774 printf("\n"); 774 printf("\n");
775 } 775 }
776 } 776 }
777 } 777 }
900 // Display results 900 // Display results
901 // 901 //
902 for (size_t offs = 0, n = 0; offs < compBufSize; offs++) 902 for (size_t offs = 0, n = 0; offs < compBufSize; offs++)
903 { 903 {
904 DMCompElem *el = &compBuf[offs]; 904 DMCompElem *el = &compBuf[offs];
905 BOOL var = el->variants > 1; 905 bool var = el->variants > 1;
906 906
907 if (n == 0) 907 if (n == 0)
908 printf("%08" DM_PRIx_SIZE_T " | ", offs); 908 printf("%08" DM_PRIx_SIZE_T " | ", offs);
909 909
910 if (var) 910 if (var)
983 if (setMode == FA_DIFF) 983 if (setMode == FA_DIFF)
984 { 984 {
985 // 985 //
986 // Attempt to find matching sequences of N+ 986 // Attempt to find matching sequences of N+
987 // 987 //
988 BOOL slow = FALSE; 988 bool slow = false;
989 int ss = 0; 989 int ss = 0;
990 printf("Attempting to find matching sequences of %" DM_PRIu_SIZE_T " bytes or more.\n", 990 printf("Attempting to find matching sequences of %" DM_PRIu_SIZE_T " bytes or more.\n",
991 optMinMatchLen); 991 optMinMatchLen);
992 992
993 if (totalSize > 32*1024) 993 if (totalSize > 32*1024)
994 { 994 {
995 dmPrint(0, 995 dmPrint(0,
996 "WARNING! Total data size is large, and the matching \"algorithm\"\n" 996 "WARNING! Total data size is large, and the matching \"algorithm\"\n"
997 "used is horribly inefficient. This will be quite slow ...\n"); 997 "used is horribly inefficient. This will be quite slow ...\n");
998 slow = TRUE; 998 slow = true;
999 } 999 }
1000 1000
1001 for (int nfile1 = 0; nfile1 < nsrcFiles; nfile1++) 1001 for (int nfile1 = 0; nfile1 < nsrcFiles; nfile1++)
1002 { 1002 {
1003 DMSourceFile *file1 = &srcFiles[nfile1]; 1003 DMSourceFile *file1 = &srcFiles[nfile1];
1040 1040
1041 if (cnt < optMinMatchLen) 1041 if (cnt < optMinMatchLen)
1042 moffs1++; 1042 moffs1++;
1043 } 1043 }
1044 } 1044 }
1045 file1->analyzed = TRUE; 1045 file1->analyzed = true;
1046 } 1046 }
1047 1047
1048 done: 1048 done:
1049 1049
1050 if (slow) 1050 if (slow)
1069 for (int nplace = 0; nplace < seq->nplaces; nplace++) 1069 for (int nplace = 0; nplace < seq->nplaces; nplace++)
1070 { 1070 {
1071 DMMatchPlace *place = &seq->places[nplace]; 1071 DMMatchPlace *place = &seq->places[nplace];
1072 if (!fileFlags[place->file->index]) 1072 if (!fileFlags[place->file->index])
1073 { 1073 {
1074 fileFlags[place->file->index] = TRUE; 1074 fileFlags[place->file->index] = true;
1075 seq->nfiles++; 1075 seq->nfiles++;
1076 } 1076 }
1077 } 1077 }
1078 } 1078 }
1079 1079