| 1 | // ========== Copyright Header Begin ========================================== |
| 2 | // |
| 3 | // OpenSPARC T2 Processor File: trconv.C |
| 4 | // Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. |
| 5 | // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. |
| 6 | // |
| 7 | // The above named program is free software; you can redistribute it and/or |
| 8 | // modify it under the terms of the GNU General Public |
| 9 | // License version 2 as published by the Free Software Foundation. |
| 10 | // |
| 11 | // The above named program is distributed in the hope that it will be |
| 12 | // useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 14 | // General Public License for more details. |
| 15 | // |
| 16 | // You should have received a copy of the GNU General Public |
| 17 | // License along with this work; if not, write to the Free Software |
| 18 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. |
| 19 | // |
| 20 | // ========== Copyright Header End ============================================ |
| 21 | /* Copyright (C) 2006 Sun Microsystems, Inc. |
| 22 | * All Rights Reserved |
| 23 | */ |
| 24 | |
| 25 | #pragma ident "@(#) trconv.C 1.6: 11/01/07 14:57:38 @(#)" |
| 26 | #include <ctype.h> |
| 27 | #include <limits.h> |
| 28 | #include <stdlib.h> |
| 29 | #include <string.h> |
| 30 | |
| 31 | #include "read_symbols.h" |
| 32 | #include "trconv.H" |
| 33 | |
| 34 | Globals_T gbl; |
| 35 | |
| 36 | // allocating space... |
| 37 | Tmaster64 Trace::this_master = {0}; |
| 38 | |
| 39 | char version_string[] = "(Version 1.5)"; |
| 40 | |
| 41 | char switch_error_string[] = "Invalid %s passed to %s: %d\n"; |
| 42 | |
| 43 | char usage_string[] = |
| 44 | "Usage: %s [flags] [input-file]\n" |
| 45 | "\n" |
| 46 | "%s " |
| 47 | "Prints and converts various trace formats.\n" |
| 48 | "\n" |
| 49 | "Format flags:\n" |
| 50 | " -from FX = assume input data is in format FX\n" |
| 51 | " -to FX = generate output format FX\n" |
| 52 | " where FX is one of the following: \n" |
| 53 | " shade5 = Shade5 format\n" |
| 54 | " shade6x32 = Shade6 format, using 32 bit addresses\n" |
| 55 | " shade6x64 = Shade6 format, using 64 bit addresses\n" |
| 56 | " rtf99 = a deprecated format\n" |
| 57 | " rst = (RQ's) really simple trace format (Default -from)\n" |
| 58 | " null = (only for \"-to FX\"), do not convert (Default -to)\n" |
| 59 | "Selection flags:\n" |
| 60 | " -n N = stop after processing N records\n" |
| 61 | " -n Ni = stop after processing N instructions\n" |
| 62 | " -s N = skip the first N records\n" |
| 63 | " -s Ni = skip the first N instructions\n" |
| 64 | " -pc=pc1[,pc2] = only process instructions w/ pc=pc1 (or [pc1,pc2])\n" |
| 65 | " -ea=ea1[,ea2] = only process instructions w/ ea=ea1 (or [ea1,ea2])\n" |
| 66 | " -cpu=cpu1[,cpu2,...] = only process records from selected cpu's\n" |
| 67 | " Example: -cpu=m,n-q,p selects records from \n" |
| 68 | " cpu's m, p, and all cpu's from n through q\n" |
| 69 | "Printing flags:\n" |
| 70 | " -a = print in trace record field format\n" |
| 71 | " -d = print in instruction disassembly format (Default)\n" |
| 72 | " -x = print verbose output format\n" |
| 73 | " -nid = suppress trace index in output\n" |
| 74 | " -c = only count records from the trace file\n" |
| 75 | #ifdef _PRINT_PA |
| 76 | " -pa = print both VA and PA of effective address\n" |
| 77 | #endif // _PRINT_PA |
| 78 | " -sym [file] = read and use symbols from 'file'\n" |
| 79 | #ifdef _VALUE_TRACE |
| 80 | " -vt = print registers in value trace format\n" |
| 81 | #endif // _VALUE_TRACE |
| 82 | "Verification flags:\n" |
| 83 | " -nv = do not verify pc values in trace file\n" |
| 84 | " -e = only check for ihash errors\n" |
| 85 | " -fast = turn off all verification and patching options\n" |
| 86 | "RST flags:\n" |
| 87 | " -i = only process RST instruction records\n" |
| 88 | " -ic = like -i, but counts only instructions\n" |
| 89 | " -ni = do not process any RST instruction records\n" |
| 90 | " -nic = like -ni, but counts only non-instructions\n" |
| 91 | " -rstdump || -r = macro for: -from rst -to null -d (Default)\n" |
| 92 | " -nobranch = do not verify branch ea's against disassembly\n" |
| 93 | " -nopc_pavadiff = do not verify rstf_pavadiffT.pc_pa_va field\n" |
| 94 | " -noea_pavadiff = do not verify rstf_pavadiffT.ea_pa_va field\n" |
| 95 | " -pstate_am 0|1 = set initial PSTATE.AM bit to 0 or 1 (Default: 0)\n" |
| 96 | "Patching flags:\n" |
| 97 | " -patchcleanrst = clean up \"dirty\" ea value to be RSTF_NOADDR " |
| 98 | "in RST trace\n" |
| 99 | " -patchihash = forces ihash value generation\n" |
| 100 | "Output flags:\n" |
| 101 | " -stdout = output to standard out (Default)\n" |
| 102 | " -o File = output to File\n" |
| 103 | "Miscellaneous:\n" |
| 104 | " -help || -h = print this message and exit\n" |
| 105 | " -version || -v = print version and exit\n" |
| 106 | "\n" |
| 107 | "Default flags are: -from rst -to null -d -stdout.\n" |
| 108 | "(By default Spix5 ihash values are assumed for all trace formats\n" |
| 109 | "*including* Shade6 traces...)\n" |
| 110 | "\n" |
| 111 | "Examples:\n" |
| 112 | " %% %s < rstfile\n" |
| 113 | " (print disassembled RST trace instructions)\n" |
| 114 | "\n" |
| 115 | " %% %s -from rst [-to null] -s 1000i -patchihash rstfile\n" |
| 116 | " (print trace records, skip first 1000 instructions)\n" |
| 117 | "\n" |
| 118 | " %% %s -r -pc=0x12345678,0x22222222 rstfile\n" |
| 119 | " (print disassembled RST trace instructions with pc values within \n" |
| 120 | " [0x12345678 0x22222222])\n\n"; |
| 121 | |
| 122 | void usage(char progName[]) { |
| 123 | fprintf(stderr, usage_string, progName, version_string, |
| 124 | progName, progName, progName); |
| 125 | } |
| 126 | |
| 127 | // initializes user_options |
| 128 | void parse_args(int argc, char *argv[], bool debug) { |
| 129 | int i; |
| 130 | char* a; |
| 131 | char* b; |
| 132 | |
| 133 | // parse arguments |
| 134 | for (i = 1; i < argc; i++) { |
| 135 | a = argv[i]; |
| 136 | b = (i < argc) ? argv[i+1] : NULL; |
| 137 | |
| 138 | if (streq(a, "-from")) { |
| 139 | if (streq(b, "null")) { |
| 140 | usage(argv[0]); |
| 141 | fprintf(stderr, "Invalid input format. Type %s -help\n", argv[0]); |
| 142 | exit(1); |
| 143 | } else { |
| 144 | gbl.fromtype = format2int(b); |
| 145 | } |
| 146 | i++; |
| 147 | } else if (streq(a, "-to")) { |
| 148 | if (streq(b, "null")) { |
| 149 | gbl.totype = NONE; |
| 150 | } else { |
| 151 | gbl.totype = format2int(b); |
| 152 | } |
| 153 | i++; |
| 154 | |
| 155 | } else if (streq(a, "-n")) { |
| 156 | gbl.maxRecs = strtoll(b, NULL, 10); |
| 157 | if (b[strlen(b) - 1] == 'i') { |
| 158 | gbl.maxInstrs = gbl.maxRecs; |
| 159 | gbl.maxRecs = INT64_MAX; |
| 160 | } |
| 161 | i++; |
| 162 | } else if (streq(a, "-syms")) { |
| 163 | if (b == NULL) { |
| 164 | usage(argv[0]); |
| 165 | fprintf(stderr, "Could not open file for writing: %s\n", b); |
| 166 | exit(1); |
| 167 | } |
| 168 | else { |
| 169 | if (gbl.symbol_table.read_symbol_file(b) == false) { |
| 170 | fprintf(stderr, "Read of symbol table file '%s' failed\n", |
| 171 | b); |
| 172 | exit(1); |
| 173 | } |
| 174 | } |
| 175 | gbl.show_syms = true; |
| 176 | i++; |
| 177 | } else if (streq(a, "-s")) { |
| 178 | gbl.skipRecs = strtoll(b, NULL, 10); |
| 179 | if (b[strlen(b) - 1] == 'i') { |
| 180 | gbl.skipInstrs = gbl.skipRecs; |
| 181 | gbl.skipRecs = 0; |
| 182 | } |
| 183 | i++; |
| 184 | } else if (streqprefix(a, "-pc")) { |
| 185 | get_range(a, &gbl.frompc, &gbl.topc); |
| 186 | } else if (streqprefix(a, "-ea")) { |
| 187 | get_range(a, &gbl.fromea, &gbl.toea); |
| 188 | } else if (streqprefix(a, "-cpu")) { |
| 189 | get_cpu_range(a); |
| 190 | |
| 191 | } else if (streq(a, "-a")) { |
| 192 | gbl.disassembly = false; |
| 193 | gbl.record = true; |
| 194 | gbl.verbose = false; |
| 195 | } else if (streq(a, "-d")) { |
| 196 | gbl.disassembly = true; |
| 197 | gbl.record = false; |
| 198 | gbl.verbose = false; |
| 199 | } else if (streq(a, "-x")) { |
| 200 | gbl.disassembly = false; |
| 201 | gbl.record = false; |
| 202 | gbl.verbose = true; |
| 203 | } else if (streq(a, "-nid")) { |
| 204 | gbl.showIdx = false; |
| 205 | } else if (streq(a, "-c")) { |
| 206 | gbl.countOnly = true; |
| 207 | #ifdef _PRINT_PA |
| 208 | } else if (streq(a, "-pa")) { |
| 209 | gbl.printPA = true; |
| 210 | #endif // _PRINT_PA |
| 211 | #ifdef _VALUE_TRACE |
| 212 | } else if (streq(a, "-vt")) { |
| 213 | gbl.valueTrace = true; |
| 214 | #endif // _VALUE_TRACE |
| 215 | |
| 216 | } else if (streq(a, "-nv")) { |
| 217 | gbl.verify = false; |
| 218 | } else if (streq(a, "-e")) { |
| 219 | gbl.checkError = true; |
| 220 | } else if (streq(a, "-fast")) { |
| 221 | gbl.fast = true; |
| 222 | |
| 223 | } else if (streq(a, "-i")) { |
| 224 | gbl.onlyIns = true; |
| 225 | } else if (streq(a, "-ic")) { |
| 226 | gbl.onlyIns = true; |
| 227 | gbl.reorderIns = true; |
| 228 | } else if (streq(a, "-ni")) { |
| 229 | gbl.noIns = true; |
| 230 | } else if (streq(a, "-nic")) { |
| 231 | gbl.noIns = true; |
| 232 | gbl.reorderNoIns = true; |
| 233 | } else if (streq(a, "-rstdump") || streq(a, "-r")) { |
| 234 | gbl.fromtype = RST; |
| 235 | gbl.totype = NONE; |
| 236 | } else if (streq(a, "-nobranch")) { |
| 237 | gbl.branch = false; |
| 238 | } else if (streq(a, "-nopc_pavadiff")) { |
| 239 | gbl.pc_pavadiff = false; |
| 240 | } else if (streq(a, "-noea_pavadiff")) { |
| 241 | gbl.ea_pavadiff = false; |
| 242 | } else if (streq(a, "-pstate_am")) { |
| 243 | unsigned am = atoi(b) << 3; |
| 244 | int j; |
| 245 | |
| 246 | for (j = 0; j < MAX_CPUID + 1; j++) { |
| 247 | gbl.pstate[j] = am; |
| 248 | } |
| 249 | |
| 250 | i++; |
| 251 | |
| 252 | } else if (streq(a, "-patchcleanrst")) { |
| 253 | gbl.clean = true; |
| 254 | } else if (streq(a, "-patchihash")) { |
| 255 | gbl.genIHash = true; |
| 256 | |
| 257 | } else if (streq(a, "-stdout")) { |
| 258 | gbl.outfp = stdout; |
| 259 | } else if (streq(a, "-o")) { |
| 260 | gbl.outfp = fopen(b, "w"); |
| 261 | if (gbl.outfp == NULL) { |
| 262 | usage(argv[0]); |
| 263 | fprintf(stderr, "Could not open file for writing: %s\n", b); |
| 264 | exit(1); |
| 265 | } |
| 266 | i++; |
| 267 | |
| 268 | } else if (streq(a, "-help") || streq(a, "-h")) { |
| 269 | usage(argv[0]); |
| 270 | exit(0); |
| 271 | } else if (streq(a, "-version") || streq(a, "-v")) { |
| 272 | fprintf(stderr, "%s %s\n", argv[0], version_string); |
| 273 | exit(0); |
| 274 | |
| 275 | } else if (a[0] == '-') { |
| 276 | usage(argv[0]); |
| 277 | fprintf(stderr, "Unknown flag: %s\n", a); |
| 278 | exit(1); |
| 279 | } else if (i < argc - 1) { |
| 280 | usage(argv[0]); |
| 281 | fprintf(stderr, "Unknown flag: %s\n", a); |
| 282 | exit(1); |
| 283 | } else if (i == argc - 1) { |
| 284 | gbl.infile = a; |
| 285 | |
| 286 | gbl.infp = fopen(a, "r"); |
| 287 | if (gbl.infp == NULL) { |
| 288 | usage(argv[0]); |
| 289 | fprintf(stderr, "Could not open input file: %s\n", a); |
| 290 | exit(1); |
| 291 | } |
| 292 | } |
| 293 | } |
| 294 | |
| 295 | if (gbl.fast) { |
| 296 | gbl.verify = false; |
| 297 | gbl.checkError = false; |
| 298 | gbl.branch = false; |
| 299 | gbl.pc_pavadiff = false; |
| 300 | gbl.ea_pavadiff = false; |
| 301 | gbl.clean = false; |
| 302 | gbl.genIHash = false; |
| 303 | gbl.checkIHash = false; |
| 304 | } |
| 305 | |
| 306 | gbl.fromsize = format2size(gbl.fromtype); |
| 307 | gbl.tosize = format2size(gbl.totype); |
| 308 | |
| 309 | if (debug) { |
| 310 | for (i = 0; i < argc; i++) { |
| 311 | fprintf(gbl.msgfp, "%s ", argv[i]); |
| 312 | } |
| 313 | fprintf(gbl.msgfp, "\n\n"); |
| 314 | |
| 315 | // format options |
| 316 | fprintf(gbl.msgfp, "fromtype = %d\n", gbl.fromtype); |
| 317 | fprintf(gbl.msgfp, "totype = %d\n", gbl.totype); |
| 318 | fprintf(gbl.msgfp, "\n"); |
| 319 | |
| 320 | // selection options |
| 321 | fprintf(gbl.msgfp, "maxRecs = %llu\n", gbl.maxRecs); |
| 322 | fprintf(gbl.msgfp, "maxInstrs = %llu\n", gbl.maxInstrs); |
| 323 | fprintf(gbl.msgfp, "skipRecs = %llu\n", gbl.skipRecs); |
| 324 | fprintf(gbl.msgfp, "skipInstrs = %llu\n", gbl.skipInstrs); |
| 325 | fprintf(gbl.msgfp, "frompc = 0x%llx\n", gbl.frompc); |
| 326 | fprintf(gbl.msgfp, "topc = 0x%llx\n", gbl.topc); |
| 327 | fprintf(gbl.msgfp, "fromea = 0x%llx\n", gbl.fromea); |
| 328 | fprintf(gbl.msgfp, "toea = 0x%llx\n", gbl.toea); |
| 329 | fprintf(gbl.msgfp, "\n"); |
| 330 | |
| 331 | // priting options |
| 332 | fprintf(gbl.msgfp, "record = %d\n", gbl.record); |
| 333 | fprintf(gbl.msgfp, "disassembly = %d\n", gbl.disassembly); |
| 334 | fprintf(gbl.msgfp, "verbose = %d\n", gbl.verbose); |
| 335 | fprintf(gbl.msgfp, "showIdx = %d\n", gbl.showIdx); |
| 336 | fprintf(gbl.msgfp, "countOnly = %d\n", gbl.countOnly); |
| 337 | #ifdef _PRINT_PA |
| 338 | fprintf(gbl.msgfp, "print PA = %d\n", gbl.printPA); |
| 339 | #endif // _PRINT_PA |
| 340 | #ifdef _VALUE_TRACE |
| 341 | fprintf(gbl.msgfp, "valueTrace = %d\n", gbl.valueTrace); |
| 342 | #endif // _VALUE_TRACE |
| 343 | fprintf(gbl.msgfp, "msgfp = 0x%x\n", gbl.msgfp); |
| 344 | fprintf(gbl.msgfp, "\n"); |
| 345 | |
| 346 | // verification options |
| 347 | fprintf(gbl.msgfp, "verify = %d\n", gbl.verify); |
| 348 | fprintf(gbl.msgfp, "checkError = %d\n", gbl.checkError); |
| 349 | fprintf(gbl.msgfp, "fast = %d\n", gbl.fast); |
| 350 | fprintf(gbl.msgfp, "\n"); |
| 351 | |
| 352 | // rsttrace options |
| 353 | fprintf(gbl.msgfp, "onlyIns = %d\n", gbl.onlyIns); |
| 354 | fprintf(gbl.msgfp, "reorderIns = %d\n", gbl.reorderIns); |
| 355 | fprintf(gbl.msgfp, "noIns = %d\n", gbl.noIns); |
| 356 | fprintf(gbl.msgfp, "reorderNoIns = %d\n", gbl.reorderNoIns); |
| 357 | fprintf(gbl.msgfp, "branch = %d\n", gbl.branch); |
| 358 | fprintf(gbl.msgfp, "pc_pavadiff = %d\n", gbl.pc_pavadiff); |
| 359 | fprintf(gbl.msgfp, "ea_pavadiff = %d\n", gbl.ea_pavadiff); |
| 360 | fprintf(gbl.msgfp, "\n"); |
| 361 | |
| 362 | // patching options |
| 363 | fprintf(gbl.msgfp, "clean = %d\n", gbl.clean); |
| 364 | fprintf(gbl.msgfp, "genIHash = %d\n", gbl.genIHash); |
| 365 | fprintf(gbl.msgfp, "\n"); |
| 366 | |
| 367 | // output options |
| 368 | fprintf(gbl.msgfp, "infp = 0x%x\n", gbl.infp); |
| 369 | fprintf(gbl.msgfp, "outfp = 0x%x\n", gbl.outfp); |
| 370 | fprintf(gbl.msgfp, "\n"); |
| 371 | |
| 372 | // convenient variables |
| 373 | fprintf(gbl.msgfp, "progname = %s\n", gbl.progname); |
| 374 | fprintf(gbl.msgfp, "infile = %s\n", gbl.infile); |
| 375 | fprintf(gbl.msgfp, "fromsize = %d bytes\n", gbl.fromsize); |
| 376 | fprintf(gbl.msgfp, "tosize = %d bytes\n", gbl.tosize); |
| 377 | |
| 378 | fflush(gbl.msgfp); |
| 379 | } |
| 380 | } // parse_args |
| 381 | |
| 382 | void init_globals(char *argv[]) { |
| 383 | // format options |
| 384 | gbl.fromtype = RST; // -from |
| 385 | gbl.totype = NONE; // -to |
| 386 | |
| 387 | // selection options |
| 388 | gbl.maxRecs = INT64_MAX; // -n |
| 389 | gbl.maxInstrs = INT64_MAX; // -n i |
| 390 | gbl.skipRecs = 0; // -s |
| 391 | gbl.skipInstrs = 0; // -s i |
| 392 | gbl.frompc = 0; // -frompc |
| 393 | gbl.topc = 0; // -topc |
| 394 | gbl.fromea = 0; // -fromea |
| 395 | gbl.toea = 0; // -toea |
| 396 | for (int i = 0; i < MAX_CPUID; i++) { |
| 397 | gbl.cpu[i] = 1; // -cpu |
| 398 | } |
| 399 | |
| 400 | // printing options |
| 401 | gbl.record = false; // -a |
| 402 | gbl.disassembly = true; // -d |
| 403 | gbl.verbose = false; // -x |
| 404 | gbl.countOnly = false; // -c |
| 405 | gbl.showIdx = true; // -nid |
| 406 | #ifdef _PRINT_PA |
| 407 | gbl.printPA = false; // -pa |
| 408 | #endif // _PRINT_PA |
| 409 | #ifdef _VALUE_TRACE |
| 410 | gbl.valueTrace = false; // -vt |
| 411 | #endif // _VALUE_TRACE |
| 412 | gbl.show_syms = false; // -syms |
| 413 | |
| 414 | // verification options |
| 415 | gbl.verify = true; // -nv |
| 416 | gbl.checkError = false; // -e |
| 417 | gbl.fast = false; // -fast |
| 418 | |
| 419 | // rsttrace options |
| 420 | gbl.onlyIns = false; // -i |
| 421 | gbl.reorderIns = false; // -ic |
| 422 | gbl.noIns = false; // -ni |
| 423 | gbl.reorderNoIns = false; // -nic |
| 424 | gbl.branch = true; // -nobranch |
| 425 | gbl.pc_pavadiff = true; // -nopc_pavadiff |
| 426 | gbl.ea_pavadiff = true; // -noea_pavadiff |
| 427 | gbl.msgfp = stderr; // -msg |
| 428 | |
| 429 | // patching options |
| 430 | gbl.clean = false; // -patchcleanrst |
| 431 | gbl.genIHash = false; // -patchihash |
| 432 | |
| 433 | // output options |
| 434 | gbl.infp = stdin; // [input-file] |
| 435 | gbl.outfp = stdout; // -stdout || -o |
| 436 | |
| 437 | // convenient variables |
| 438 | gbl.progname = argv[0]; |
| 439 | gbl.infile = (char*) malloc(8); |
| 440 | if (gbl.infile == NULL) { |
| 441 | fprintf(stderr, "Could not allocate 8 bytes for " |
| 442 | "infile in init_globals()\n"); |
| 443 | exit(1); |
| 444 | } |
| 445 | strcpy(gbl.infile, "stdin"); |
| 446 | |
| 447 | gbl.checkIHash = true; // check ihash until nonzero value confirmed |
| 448 | |
| 449 | gbl.icount = 0; |
| 450 | gbl.rcount = 0; |
| 451 | gbl.skipInstrsRecs = 0; |
| 452 | |
| 453 | for (int i = 0; i < MAX_CPUID + 1; i++) { |
| 454 | gbl.pstate[i] = 0; // assume 64bit addresses by default |
| 455 | } |
| 456 | |
| 457 | // rst-related |
| 458 | gbl.rstf_pre212 = false; |
| 459 | |
| 460 | // rst types |
| 461 | gbl.headercount = 0; |
| 462 | //gbl.asicount = 0; |
| 463 | gbl.tlbcount = 0; |
| 464 | gbl.threadcount = 0; |
| 465 | gbl.trapcount = 0; |
| 466 | gbl.trapexitcount = 0; |
| 467 | gbl.regvalcount = 0; |
| 468 | gbl.cpucount = 0; |
| 469 | gbl.pregcount = 0; |
| 470 | gbl.dmacount = 0; |
| 471 | gbl.stringcount = 0; |
| 472 | gbl.delimcount = 0; |
| 473 | gbl.physaddrcount = 0; |
| 474 | gbl.pavadiffcount = 0; |
| 475 | gbl.filemarkercount = 0; |
| 476 | gbl.snoopcount = 0; |
| 477 | |
| 478 | gbl.unknowncount = 0; |
| 479 | |
| 480 | #ifdef _PRINT_PA |
| 481 | for(int initCpuId=0; initCpuId<MAX_INSTR_CPUID; initCpuId++) { |
| 482 | gbl.ea_pavadiff_valid[initCpuId] = false; |
| 483 | gbl.ea_pavadiff_value[initCpuId] = 0; |
| 484 | gbl.pc_pavadiff_valid[initCpuId] = false; |
| 485 | gbl.pc_pavadiff_value[initCpuId] = 0; |
| 486 | } |
| 487 | #endif // _PRINT_PA |
| 488 | } |
| 489 | |
| 490 | int format2int(const char str[]) { |
| 491 | if (streq(str, "shade5") ) { |
| 492 | return SHADE5; |
| 493 | } else if (streq(str, "shade6x32") ) { |
| 494 | return SHADE6x32; |
| 495 | } else if (streq(str, "shade6x64") ) { |
| 496 | return SHADE6x64; |
| 497 | } else if (streq(str, "rtf99") ) { |
| 498 | return RTF99; |
| 499 | } else if (streq(str, "master") ){ |
| 500 | return MASTER64; |
| 501 | } else if (streq(str, "rst") ){ |
| 502 | return RST; |
| 503 | } else if (streq(str, "null") ) { |
| 504 | return NONE; |
| 505 | } else { |
| 506 | usage(gbl.progname); |
| 507 | fprintf(stderr, "Invalid data format: \"%s\"\n", str); |
| 508 | exit(1); |
| 509 | } |
| 510 | } |
| 511 | |
| 512 | int format2size(int format) { |
| 513 | int size; |
| 514 | |
| 515 | switch (format) { |
| 516 | case RTF99: |
| 517 | size = sizeof(Trtf99); |
| 518 | break; |
| 519 | case SHADE5: |
| 520 | size = sizeof(Tshade5); |
| 521 | break; |
| 522 | case SHADE6x32: |
| 523 | size = sizeof(Tshade6x32); |
| 524 | break; |
| 525 | case SHADE6x64: |
| 526 | size = sizeof(Tshade6x64); |
| 527 | break; |
| 528 | case MASTER64: |
| 529 | size = sizeof(Tmaster64); |
| 530 | break; |
| 531 | case RST: |
| 532 | size = sizeof(rstf_unionT); |
| 533 | break; |
| 534 | case NONE: |
| 535 | size = 0; |
| 536 | break; |
| 537 | default: |
| 538 | fprintf(stderr, switch_error_string, "format", "format2size", format); |
| 539 | exit(2); |
| 540 | } |
| 541 | |
| 542 | return size; |
| 543 | } |
| 544 | |
| 545 | bool streq(const char* a, const char* b) { |
| 546 | return (strcmp(a, b) == 0); |
| 547 | } |
| 548 | |
| 549 | bool streqprefix(const char* a, const char* b) { |
| 550 | return (strncmp(a, b, strlen(b) ) == 0); |
| 551 | } |
| 552 | |
| 553 | void get_range(char* str, uint64_t *from, uint64_t* to) { |
| 554 | char* from_str; |
| 555 | char* to_str; |
| 556 | |
| 557 | from_str = strstr(str, "="); |
| 558 | if (from_str == NULL) { |
| 559 | usage(gbl.progname); |
| 560 | fprintf(stderr, "Invalid pc/ea given to -pc/-ea flag.\n"); |
| 561 | exit(1); |
| 562 | } else { |
| 563 | *from = strtoull(from_str + 1, NULL, 16); |
| 564 | } |
| 565 | |
| 566 | to_str = strstr(str, ","); |
| 567 | if (to_str != NULL) { |
| 568 | *to = strtoull(to_str + 1, NULL, 16); |
| 569 | } |
| 570 | } |
| 571 | |
| 572 | int is_valid_cpu(int cpuid) { |
| 573 | return (cpuid >= 0 && cpuid <= MAX_CPUID); |
| 574 | } |
| 575 | |
| 576 | void get_cpu_range(char* str) { |
| 577 | int cpuid, prev_cpuid; |
| 578 | int i; |
| 579 | |
| 580 | for (i = 0; i <= MAX_CPUID; i++) { |
| 581 | gbl.cpu[i] = 0; // -cpu |
| 582 | } |
| 583 | |
| 584 | str = strchr(str, '='); |
| 585 | if (str == NULL) { |
| 586 | usage(gbl.progname); |
| 587 | fprintf(stderr, "Error: invalid -cpu id given.\n"); |
| 588 | exit(1); |
| 589 | } |
| 590 | |
| 591 | str++; |
| 592 | while (isdigit(str[0])) { |
| 593 | cpuid = strtol(str, &str, 10); |
| 594 | if (is_valid_cpu(cpuid) == 0) { |
| 595 | fprintf(stderr, "Error: invalid cpuid %d.\n", cpuid); |
| 596 | exit(1); |
| 597 | } |
| 598 | prev_cpuid = cpuid; |
| 599 | |
| 600 | if (str[0] == '-') { |
| 601 | str++; |
| 602 | if (isdigit(str[0])) { |
| 603 | cpuid = strtol(str, &str, 10); |
| 604 | if (is_valid_cpu(cpuid) == 0) { |
| 605 | fprintf(stderr, "Error: invalid cpuid %d.\n", cpuid); |
| 606 | exit(1); |
| 607 | } |
| 608 | } |
| 609 | } |
| 610 | |
| 611 | for (i = prev_cpuid; i <= cpuid; i++) { |
| 612 | gbl.cpu[i] = 1; |
| 613 | } |
| 614 | |
| 615 | str++; |
| 616 | } |
| 617 | } |
| 618 | |
| 619 | // range_ok(pc, frompc, topc); |
| 620 | // range_ok(ea, fromea, toea); |
| 621 | bool in_range(const uint64_t x, const uint64_t a, const uint64_t b) { |
| 622 | if (a == 0 && b == 0) { // process all records |
| 623 | return true; |
| 624 | } else if (x == RSTF_NOADDR) { |
| 625 | return false; // invalid x (address) |
| 626 | } else { |
| 627 | if (a != 0 && b == 0) { // process only x=a |
| 628 | if (x == a) { |
| 629 | return true; |
| 630 | } |
| 631 | } else if (a != 0 && b != 0) { // process a<=x<=b |
| 632 | if (x >= a && x <= b) { |
| 633 | return true; |
| 634 | } |
| 635 | } else if (a == 0 && b != 0) { // error |
| 636 | // should never get here though... |
| 637 | fprintf(stderr, "Invalid pc/ea given to -pc/-ea flag.\n"); |
| 638 | exit(1); |
| 639 | } |
| 640 | } |
| 641 | |
| 642 | return false; |
| 643 | } |
| 644 | |
| 645 | void print_counts(FILE* outfp) { |
| 646 | if (gbl.skipInstrs) { |
| 647 | gbl.rcount += gbl.skipInstrsRecs; |
| 648 | } |
| 649 | |
| 650 | fprintf(outfp, "\n"); |
| 651 | if (gbl.rcount == gbl.icount) { |
| 652 | fprintf(outfp, "Counted: %lld instructions\n", gbl.icount); |
| 653 | } else { |
| 654 | fprintf(outfp, "Counted: %lld records\n\n", gbl.rcount); |
| 655 | |
| 656 | fprintf(outfp, " %lld instruction recs\n", gbl.icount); |
| 657 | fprintf(outfp, " %lld header recs\n", gbl.headercount); |
| 658 | fprintf(outfp, " %lld traceinfo recs\n", gbl.traceinfocount); |
| 659 | fprintf(outfp, " %lld tlb recs\n", gbl.tlbcount); |
| 660 | fprintf(outfp, " %lld thread recs\n", gbl.threadcount); |
| 661 | fprintf(outfp, " %lld preg recs\n", gbl.pregcount); |
| 662 | fprintf(outfp, " %lld trap recs\n", gbl.trapcount); |
| 663 | fprintf(outfp, " %lld trapexit recs\n", gbl.trapexitcount); |
| 664 | fprintf(outfp, " %lld cpu recs\n", gbl.cpucount); |
| 665 | fprintf(outfp, " %lld dma recs\n", gbl.dmacount); |
| 666 | fprintf(outfp, " %lld snoop recs\n", gbl.snoopcount); |
| 667 | fprintf(outfp, " %lld delim recs\n", gbl.delimcount); |
| 668 | fprintf(outfp, " %lld physaddr recs\n", gbl.physaddrcount); |
| 669 | fprintf(outfp, " %lld pavadiff recs\n", gbl.pavadiffcount); |
| 670 | fprintf(outfp, " %lld rfs_sechdr recs\n", gbl.rfs_section_header_count); |
| 671 | fprintf(outfp, " %lld rfs_cachewarming recs\n", gbl.cachewarming_count); |
| 672 | fprintf(outfp, " %lld rfs_bpwarming recs\n", gbl.bpwarming_count); |
| 673 | fprintf(outfp, " %lld filemarker recs\n", gbl.filemarkercount); |
| 674 | fprintf(outfp, " %lld recnum recs\n", gbl.recnumcount); |
| 675 | fprintf(outfp, " %lld string recs\n", gbl.stringcount); |
| 676 | fprintf(outfp, " %lld status recs\n", gbl.statuscount); |
| 677 | fprintf(outfp, " %lld patch recs\n", gbl.patchcount); |
| 678 | fprintf(outfp, " %lld regval recs\n", gbl.regvalcount); |
| 679 | fprintf(outfp, " %lld memval64 recs\n", gbl.memval64count); |
| 680 | fprintf(outfp, " %lld memval128 recs\n", gbl.memval128count); |
| 681 | fprintf(outfp, " %lld bustrace recs\n", gbl.bustracecount); |
| 682 | fprintf(outfp, " %lld process recs\n", gbl.processcount); |
| 683 | fprintf(outfp, " %lld devidstr recs\n", gbl.devidstrcount); |
| 684 | fprintf(outfp, " %lld timesync recs\n", gbl.timesynccount); |
| 685 | fprintf(outfp, " %lld zero recs\n", gbl.zerocount); |
| 686 | } |
| 687 | |
| 688 | if (gbl.unknowncount) { |
| 689 | fprintf(outfp, " %lld unknown recs\n\n", gbl.unknowncount); |
| 690 | } else { |
| 691 | fprintf(outfp, "\n"); |
| 692 | } |
| 693 | |
| 694 | if (gbl.skipRecs) { |
| 695 | fprintf(outfp, " %lld recs skipped (not counted)\n", gbl.skipRecs); |
| 696 | } |
| 697 | if (gbl.skipInstrs) { |
| 698 | fprintf(outfp, " %lld instruction recs skipped (counted)\n", |
| 699 | gbl.skipInstrs); |
| 700 | } |
| 701 | } |
| 702 | |