comparison tools/fanalyze.c @ 2045:1662730053d0

Implement controllable decimal/hexadecimal formatting for offset display mode.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 30 Nov 2018 08:01:46 +0200
parents 45d9db50d996
children 837c79747ea4
comparison
equal deleted inserted replaced
2044:1b441465ef36 2045:1662730053d0
48 } DMSourceFile; 48 } DMSourceFile;
49 49
50 50
51 enum 51 enum
52 { 52 {
53 DMGV_uint8 = 0, 53 DMGV_UINT8 = 0,
54 DMGV_uint16_le, 54 DMGV_UINT16_LE,
55 DMGV_uint16_be, 55 DMGV_UINT16_BE,
56 DMGV_uint32_le, 56 DMGV_UINT32_LE,
57 DMGV_uint32_be, 57 DMGV_UINT32_BE,
58 58
59 DMGV_last 59 DMGV_last
60 }; 60 };
61 61
62 62
63 enum
64 {
65 DMGS_HEX = 0,
66 DMGS_DEC,
67 DMGS_last
68 };
69
70
63 typedef struct 71 typedef struct
64 { 72 {
65 int type; 73 int type;
74 int disp;
66 Uint32 value; 75 Uint32 value;
67 } DMGrepValue; 76 } DMGrepValue;
68 77
69 78
70 typedef struct 79 typedef struct
71 { 80 {
72 char *name; 81 char *name;
73 Uint32 nmax; 82 Uint32 nmax;
74 unsigned int bsize; 83 unsigned int bsize;
75 } DMGrepDef; 84 } DMGrepType;
76 85
77 86
78 static const DMGrepDef dmGrepTypes[DMGV_last] = 87 static const DMGrepType dmGrepTypes[DMGV_last] =
79 { 88 {
80 { "8bit (byte)" , (1ULL << 8) - 1, 1 }, 89 { "8bit (byte)" , (1ULL << 8) - 1, 1 },
81 { "16bit (word) LE" , (1ULL << 16) - 1, 2 }, 90 { "16bit (word) LE" , (1ULL << 16) - 1, 2 },
82 { "16bit (word) BE" , (1ULL << 16) - 1, 2 }, 91 { "16bit (word) BE" , (1ULL << 16) - 1, 2 },
83 { "32bit (word) LE" , (1ULL << 32) - 1, 4 }, 92 { "32bit (word) LE" , (1ULL << 32) - 1, 4 },
84 { "32bit (word) BE" , (1ULL << 32) - 1, 4 }, 93 { "32bit (word) BE" , (1ULL << 32) - 1, 4 },
85 }; 94 };
86 95
96
97 typedef struct
98 {
99 char *name;
100 char *fmt;
101 } DMGrepDisp;
102
103
104 static const DMGrepDisp dmGrepDisp[DMGS_last] =
105 {
106 { "hex", "x" },
107 { "dec", "d" },
108 };
87 109
88 enum 110 enum
89 { 111 {
90 FA_ANALYZE, 112 FA_ANALYZE,
91 FA_GREP, 113 FA_GREP,
108 static const DMOptArg optList[] = 130 static const DMOptArg optList[] =
109 { 131 {
110 { 0, '?', "help", "Show this help", OPT_NONE }, 132 { 0, '?', "help", "Show this help", OPT_NONE },
111 { 1, 'v', "verbose", "Be more verbose", OPT_NONE }, 133 { 1, 'v', "verbose", "Be more verbose", OPT_NONE },
112 { 2, 'g', "grep", "Binary grep <val>[,<le|be>[8|16|32]]", OPT_ARGREQ }, 134 { 2, 'g', "grep", "Binary grep <val>[,<le|be>[8|16|32]]", OPT_ARGREQ },
113 { 3, 'o', "offset", "Show data in offset <offset>,<le|be>[8|16|32]]", OPT_ARGREQ }, 135 { 3, 'o', "offset", "Show data in offset <offset>,<le|be>[8|16|32][d|x]]", OPT_ARGREQ },
114 }; 136 };
115 137
116 static const int optListN = sizeof(optList) / sizeof(optList[0]); 138 static const int optListN = sizeof(optList) / sizeof(optList[0]);
117 139
118 140
125 147
126 int argParseGrepValue(const char *arg, const int mode) 148 int argParseGrepValue(const char *arg, const int mode)
127 { 149 {
128 const char *sep = strchr(arg, ','); 150 const char *sep = strchr(arg, ',');
129 char *vspec, *vstr; 151 char *vspec, *vstr;
130 int vtype = -1, ret = DMERR_OK; 152 int vdisp = DMGS_HEX, vtype = -1, ret = DMERR_OK;
131 Uint32 vval; 153 Uint32 vval;
132 154
133 if (setMode != FA_ANALYZE && setMode != mode) 155 if (setMode != FA_ANALYZE && setMode != mode)
134 { 156 {
135 dmErrorMsg("Options specifying multiple operating modes can't be used.\n"); 157 dmErrorMsg("Options specifying multiple operating modes can't be used.\n");
167 vendianess = FALSE; 189 vendianess = FALSE;
168 vtmp += 2; 190 vtmp += 2;
169 } 191 }
170 192
171 // Get value bit size 193 // Get value bit size
172 if (strcmp(vtmp, "8") == 0) 194 if (strncmp(vtmp, "8", 1) == 0)
173 vtype = DMGV_uint8; 195 {
196 vtype = DMGV_UINT8;
197 vtmp += 1;
198 }
174 else 199 else
175 if (strcmp(vtmp, "16") == 0) 200 if (strncmp(vtmp, "16", 2) == 0)
176 vtype = vendianess ? DMGV_uint16_le : DMGV_uint16_be; 201 {
202 vtype = vendianess ? DMGV_UINT16_LE : DMGV_UINT16_BE;
203 vtmp += 2;
204 }
177 else 205 else
178 if (strcmp(vtmp, "32") == 0) 206 if (strncmp(vtmp, "32", 2) == 0)
179 vtype = vendianess ? DMGV_uint32_le : DMGV_uint32_be; 207 {
208 vtype = vendianess ? DMGV_UINT32_LE : DMGV_UINT32_BE;
209 vtmp += 2;
210 }
180 else 211 else
181 { 212 {
182 ret = dmError(DMERR_INVALID_ARGS, 213 ret = dmError(DMERR_INVALID_ARGS,
183 "Invalid grep type '%s'.\n", 214 "Invalid grep type '%s'.\n",
184 vspec); 215 vspec);
185 goto out; 216 goto out;
186 } 217 }
218
219 switch (tolower(*vtmp))
220 {
221 case 'd':
222 vdisp = DMGS_DEC;
223 break;
224
225 case 'x': case 'h':
226 vdisp = DMGS_HEX;
227 break;
228
229 case 0:
230 break;
231
232 default:
233 ret = dmError(DMERR_INVALID_ARGS,
234 "Invalid grep view type '%s'.\n",
235 vspec);
236 goto out;
237 }
187 } 238 }
188 239
189 // Get value 240 // Get value
190 if (!dmGetIntVal(vstr, &vval, NULL)) 241 if (!dmGetIntVal(vstr, &vval, NULL))
191 { 242 {
200 // Check if we need to guess size 251 // Check if we need to guess size
201 if (vtype < 0) 252 if (vtype < 0)
202 { 253 {
203 for (int n = DMGV_last; n >= 0; n--) 254 for (int n = DMGV_last; n >= 0; n--)
204 { 255 {
205 const DMGrepDef *def = &dmGrepTypes[n]; 256 const DMGrepType *def = &dmGrepTypes[n];
206 if (vval <= def->nmax) 257 if (vval <= def->nmax)
207 vtype = n; 258 vtype = n;
208 } 259 }
209 } 260 }
210 261
228 } 279 }
229 else 280 else
230 if (mode == FA_OFFSET) 281 if (mode == FA_OFFSET)
231 { 282 {
232 if (vtype < 0) 283 if (vtype < 0)
233 vtype = DMGV_uint8; 284 vtype = DMGV_UINT8;
234 } 285 }
235 286
236 if (nsetGrepValues < SET_MAX_VALUES) 287 if (nsetGrepValues < SET_MAX_VALUES)
237 { 288 {
238 DMGrepValue *node = &setGrepValues[nsetGrepValues++]; 289 DMGrepValue *node = &setGrepValues[nsetGrepValues++];
239 node->type = vtype; 290 node->type = vtype;
291 node->disp = vdisp;
240 node->value = vval; 292 node->value = vval;
241 293
242 dmMsg(1, "Grep value %s : %d / 0x%x\n", 294 dmMsg(1, "Grep value %s : %d / 0x%x\n",
243 dmGrepTypes[vtype].name, 295 dmGrepTypes[vtype].name,
244 vval, vval); 296 vval, vval);
345 return FALSE; 397 return FALSE;
346 } 398 }
347 399
348 switch (type) 400 switch (type)
349 { 401 {
350 case DMGV_uint8: 402 case DMGV_UINT8:
351 *mval = *((uint8_t *) data); 403 *mval = *((Uint8 *) data);
352 break; 404 break;
353 405
354 case DMGV_uint16_le: 406 case DMGV_UINT16_LE:
355 *mval = DM_LE16_TO_NATIVE(*((Uint16 *) data)); 407 *mval = DM_LE16_TO_NATIVE(*((Uint16 *) data));
356 break; 408 break;
357 409
358 case DMGV_uint16_be: 410 case DMGV_UINT16_BE:
359 *mval = DM_BE16_TO_NATIVE(*((Uint16 *) data)); 411 *mval = DM_BE16_TO_NATIVE(*((Uint16 *) data));
360 break; 412 break;
361 413
362 case DMGV_uint32_le: 414 case DMGV_UINT32_LE:
363 *mval = DM_LE32_TO_NATIVE(*((Uint32 *) data)); 415 *mval = DM_LE32_TO_NATIVE(*((Uint32 *) data));
364 break; 416 break;
365 417
366 case DMGV_uint32_be: 418 case DMGV_UINT32_BE:
367 *mval = DM_BE32_TO_NATIVE(*((Uint32 *) data)); 419 *mval = DM_BE32_TO_NATIVE(*((Uint32 *) data));
368 break; 420 break;
369 421
370 default: 422 default:
371 *mval = 0; 423 *mval = 0;
430 dmPrint(0, "\n%s\n", file->filename); 482 dmPrint(0, "\n%s\n", file->filename);
431 483
432 for (int n = 0; n < nsetGrepValues; n++) 484 for (int n = 0; n < nsetGrepValues; n++)
433 { 485 {
434 DMGrepValue *node = &setGrepValues[n]; 486 DMGrepValue *node = &setGrepValues[n];
435 const DMGrepDef *def = &dmGrepTypes[node->type]; 487 const DMGrepType *def = &dmGrepTypes[node->type];
436 488
437 for (size_t offs = 0; offs + def->bsize < file->size; offs++) 489 for (size_t offs = 0; offs + def->bsize < file->size; offs++)
438 { 490 {
439 Uint32 mval; 491 Uint32 mval;
440 dmGetData(node->type, file, offs, &mval); 492 dmGetData(node->type, file, offs, &mval);
468 printf("\n"); 520 printf("\n");
469 521
470 for (int n = 0; n < nsetGrepValues; n++) 522 for (int n = 0; n < nsetGrepValues; n++)
471 { 523 {
472 DMGrepValue *node = &setGrepValues[n]; 524 DMGrepValue *node = &setGrepValues[n];
473 const DMGrepDef *def = &dmGrepTypes[node->type]; 525 const DMGrepType *def = &dmGrepTypes[node->type];
474 printf("%08x : ", node->value); 526 printf("%08x : ", node->value);
475 527
476 for (int nfile = 0; nfile < nsrcFiles; nfile++) 528 for (int nfile = 0; nfile < nsrcFiles; nfile++)
477 { 529 {
478 DMSourceFile *file = &srcFiles[nfile]; 530 DMSourceFile *file = &srcFiles[nfile];
482 534
483 if (dmGetData(node->type, file, node->value, &mval)) 535 if (dmGetData(node->type, file, node->value, &mval))
484 { 536 {
485 char mfmt[16]; 537 char mfmt[16];
486 nwidth = def->bsize * 2; 538 nwidth = def->bsize * 2;
487 snprintf(mfmt, sizeof(mfmt), "%%0%dx", nwidth); 539 snprintf(mfmt, sizeof(mfmt), "%%0%d%s",
540 nwidth, dmGrepDisp[node->disp].fmt);
541
488 snprintf(mstr, sizeof(mstr), mfmt, mval); 542 snprintf(mstr, sizeof(mstr), mfmt, mval);
489 } 543 }
490 else 544 else
491 { 545 {
492 strcpy(mstr, "----"); 546 strcpy(mstr, "----");
500 fputs(mstr, stdout); 554 fputs(mstr, stdout);
501 555
502 for (int q = 0; q < npad; q++) 556 for (int q = 0; q < npad; q++)
503 fputc(' ', stdout); 557 fputc(' ', stdout);
504 } 558 }
505 fputs("\n", stdout); 559
560 printf(" [%s]\n",
561 dmGrepDisp[node->disp].name);
506 } 562 }
507 } 563 }
508 else 564 else
509 if (setMode == FA_ANALYZE) 565 if (setMode == FA_ANALYZE)
510 { 566 {