Mercurial > hg > dmlib
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 { |