00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include <elf_abi.h>
00046 #include <elf_mips.h>
00047 #include <sys/types.h>
00048 #include <sys/syssgi.h>
00049 #include <stdio.h>
00050 #include <leb128.h>
00051 #include "events.h"
00052
00053
00054
00055
00056 static char *event_string0[16] = {
00057
00058 "EK_NULL",
00059 "EK_ADDR_RESET",
00060 "EK_INCR_LOC_EXT",
00061 "EK_ENTRY",
00062 "EK_IF_ENTRY",
00063 "EK_EXIT",
00064 "EK_PEND",
00065 "EK_SWITCH_32",
00066 "EK_SWITCH_64",
00067 "EK_DUMMY",
00068 "EK_BB_START",
00069 "EK_INCR_LOC_UNALIGNED",
00070 "EK_GP_PROLOG_HI",
00071 "EK_GP_PROLOG_LO",
00072 "EK_GOT_PAGE",
00073 "EK_GOT_OFST"
00074 };
00075
00076 static char *event_string1[16] = {
00077
00078 "EK_HI",
00079 "EK_LO",
00080 "EK_64_HIGHEST",
00081 "EK_64_HIGHER",
00082 "EK_64_HIGH",
00083 "EK_64_LOW",
00084 "EK_GPREL",
00085 "EK_DEF",
00086 "EK_FCALL_LOCAL",
00087 "EK_FCALL_EXTERN",
00088 "EK_FCALL_EXTERN_BIG",
00089 "EK_FCALL_MULT",
00090 "EK_FCALL_MULT_PARTIAL",
00091 "EK_LTR_FCALL",
00092 "EK_PCREL_GOT0",
00093 "0x1f"
00094 };
00095
00096 static char *event_string3[16] = {
00097
00098 "CK_DEFAULT",
00099 "CK_ALIGN",
00100 "CK_INSTR",
00101 "CK_DATA",
00102 "CK_SADDR_32",
00103 "CK_GADDR_32",
00104 "CK_CADDR_32",
00105 "CK_SADDR_64",
00106 "CK_GADDR_64",
00107 "CK_CADDR_64",
00108 "CK_NO_XFORM",
00109 "CK_NO_REORDER",
00110 "CK_GP_GROUP",
00111 "CK_STUBS",
00112 "0x3e",
00113 "0x3f"
00114 };
00115
00116 static char *event_string5[16] = {
00117
00118 "EK_CK_UNUSED_NONE_0",
00119 "EK_CK_UNUSED_NONE_1",
00120 "EK_CK_UNUSED_NONE_2",
00121 "EK_CK_UNUSED_NONE_3",
00122 "EK_CK_UNUSED_NONE_4",
00123 "EK_CK_UNUSED_16BIT_0",
00124 "EK_CK_UNUSED_16BIT_1",
00125 "EK_CK_UNUSED_16BIT_2",
00126 "EK_CK_UNUSED_16BIT_3",
00127 "EK_CK_UNUSED_16BIT_4",
00128 "EK_CK_UNUSED_32BIT_0",
00129 "EK_CK_UNUSED_32BIT_1",
00130 "EK_CK_UNUSED_32BIT_2",
00131 "EK_CK_UNUSED_64BIT_0",
00132 "EK_CK_UNUSED_64BIT_1",
00133 "EK_CK_UNUSED_64BIT_2"
00134 };
00135
00136 static char *event_string6[16] = {
00137
00138 "EK_CK_UNUSED_64BIT_3",
00139 "EK_CK_UNUSED_64BIT_4",
00140 "EK_CK_UNUSED_ULEB128_0",
00141 "EK_CK_UNUSED_ULEB128_1",
00142 "EK_CK_UNUSED_ULEB128_2",
00143 "EK_CK_UNUSED_ULEB128_3",
00144 "EK_CK_UNUSED_ULEB128_4",
00145 "EK_CK_UNUSED_ULEB128_5",
00146 "EK_CK_UNUSED_ULEB128_6",
00147 "EK_CK_UNUSED_ULEB128_7",
00148 "EK_CK_UNUSED_ULEB128_8",
00149 "EK_CK_UNUSED_ULEB128_9",
00150 "0x6c",
00151 "0x6d",
00152 "0x6e",
00153 "0x6f"
00154 };
00155
00156 static char event_buf[20];
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 char *event_kind_string(__uint32_t kind)
00168 {
00169 __uint32_t range = kind / 16;
00170 __uint32_t index = kind & 0xf;
00171
00172 switch (range) {
00173 case 0:
00174 return(event_string0[index]);
00175 case 1:
00176 return(event_string1[index]);
00177 case 3:
00178 return(event_string3[index]);
00179 case 5:
00180 return(event_string5[index]);
00181 case 6:
00182 return(event_string6[index]);
00183
00184 default:
00185 sprintf(event_buf, "0x%x", kind);
00186 return(event_buf);
00187 }
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 __uint64_t
00199 event_get_word64(char *p)
00200 {
00201 __uint64_t i;
00202 union {
00203 __uint64_t u;
00204 char a[8];
00205 }x;
00206
00207 for (i = 0; i < 8; i++)
00208 x.a[i] = p[i];
00209
00210 return(x.u);
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 __uint32_t
00222 event_get_word32(char *p)
00223 {
00224 __uint32_t i;
00225 union {
00226 __uint32_t u;
00227 char a[4];
00228 }x;
00229
00230 for (i = 0; i<4; i++)
00231 x.a[i] = p[i];
00232
00233 return(x.u);
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243 unsigned short
00244 event_get_word16(char *p)
00245 {
00246 __uint32_t i;
00247 union {
00248 unsigned short u;
00249 char a[2];
00250 }x;
00251
00252 for (i = 0; i<2; i++)
00253 x.a[i] = p[i];
00254
00255 return(x.u);
00256 }
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 char *
00267 event_get_next_rec(
00268 char *p_event,
00269 __uint32_t offset,
00270 Full_Events *p_full)
00271 {
00272 int len;
00273 int temp_offset;
00274 unsigned char type, ubyte;
00275 unsigned short ushort;
00276 short sshort;
00277 __uint32_t uword;
00278
00279 p_full->fevnt_arg1 = 0;
00280 p_full->fevnt_arg2 = 0;
00281 p_full->fevnt_arg3 = 0;
00282 p_full->fevnt_pre_arg1 = 0;
00283 p_full->fevnt_pre_arg2 = 0;
00284 p_full->fevnt_pre_arg3 = 0;
00285
00286 type = *p_event++;
00287
00288
00289
00290
00291
00292 if (type & EK_INCR_LOC) {
00293 p_full->fevnt_pre_arg1 = (type & 0x7f);
00294 p_full->fevnt_arg1 = (type & 0x7f) << 2;
00295 offset += (type & 0x7f) << 2;
00296 p_full->fevnt_type = EK_INCR_LOC;
00297 p_full->fevnt_offset = offset;
00298 return (p_event);
00299 }
00300
00301
00302 switch((int)type) {
00303
00304
00305
00306
00307
00308
00309
00310
00311 case EK_ADDR_RESET:
00312
00313 offset = event_get_word32(p_event);
00314 p_full->fevnt_arg1 = offset;
00315 p_full->fevnt_pre_arg1 = offset;
00316 p_event += 4;
00317
00318 ushort = event_get_word16(p_event);
00319 p_full->fevnt_arg2 = ushort;
00320 p_full->fevnt_pre_arg2 = ushort;
00321 p_event += 2;
00322 break;
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 case EK_INCR_LOC_EXT:
00334
00335
00336 len = _leb128_unsigned_decode32(p_event,&uword);
00337 p_event += len;
00338 p_full->fevnt_arg1 = uword<<2;
00339 offset += uword<<2;
00340 p_full->fevnt_pre_arg1 = uword;
00341 break;
00342
00343
00344
00345
00346
00347 case EK_INCR_LOC_UNALIGNED:
00348 len = _leb128_unsigned_decode32(p_event,&uword);
00349 p_event += len;
00350 p_full->fevnt_arg1 = uword;
00351 offset += uword;
00352 p_full->fevnt_pre_arg1 = uword;
00353 break;
00354
00355
00356
00357
00358
00359
00360 case EK_GP_PROLOG_HI:
00361
00362
00363
00364
00365
00366 case EK_GP_PROLOG_LO:
00367
00368
00369
00370
00371
00372 case EK_GOT_PAGE:
00373
00374
00375
00376
00377
00378 case EK_GOT_OFST:
00379
00380
00381
00382
00383 case EK_HI:
00384
00385
00386
00387
00388 case EK_LO:
00389
00390
00391
00392
00393
00394 case EK_PCREL_GOT0:
00395
00396 case EK_CK_UNUSED_16BIT_0:
00397 case EK_CK_UNUSED_16BIT_1:
00398 case EK_CK_UNUSED_16BIT_2:
00399 case EK_CK_UNUSED_16BIT_3:
00400 case EK_CK_UNUSED_16BIT_4:
00401
00402 sshort = (short)event_get_word16(p_event);
00403 p_full->fevnt_arg1 = sshort;
00404 p_full->fevnt_pre_arg1 = sshort;
00405 p_event += 2;
00406 break;
00407
00408
00409
00410
00411
00412 case EK_64_HIGHEST:
00413 case EK_64_HIGHER:
00414 case EK_64_HIGH:
00415 case EK_64_LOW:
00416 case EK_CK_UNUSED_64BIT_0:
00417 case EK_CK_UNUSED_64BIT_1:
00418 case EK_CK_UNUSED_64BIT_2:
00419 case EK_CK_UNUSED_64BIT_3:
00420 case EK_CK_UNUSED_64BIT_4:
00421
00422 p_full->fevnt_arg1 = event_get_word64(p_event);
00423 p_full->fevnt_pre_arg1 = p_full->fevnt_arg1;
00424 p_event += 8;
00425 break;
00426
00427
00428
00429
00430
00431
00432 case EK_SWITCH_32:
00433 p_full->fevnt_arg1 = *p_event++;
00434 p_full->fevnt_arg2 = event_get_word32 (p_event);
00435 p_event += 4;
00436 len = _leb128_unsigned_decode32(p_event,&uword);
00437 p_event += len;
00438 p_full->fevnt_arg3 = uword;
00439 break;
00440
00441
00442
00443
00444
00445
00446 case EK_SWITCH_64:
00447 p_full->fevnt_arg1 = *p_event++;
00448 p_full->fevnt_arg2 = event_get_word64 (p_event);
00449 p_event += 8;
00450 len = _leb128_unsigned_decode32(p_event,&uword);
00451 p_event += len;
00452 p_full->fevnt_arg3 = uword;
00453 break;
00454
00455
00456
00457
00458
00459
00460
00461 case CK_ALIGN:
00462 len = _leb128_unsigned_decode32(p_event,&uword);
00463 p_event += len;
00464 p_full->fevnt_arg1 = uword;
00465 p_full->fevnt_pre_arg1 = uword;
00466 ubyte = *p_event++;
00467 p_full->fevnt_arg2 = ubyte;
00468 break;
00469
00470 case CK_DEFAULT:
00471 ubyte = *p_event++;
00472 p_full->fevnt_arg2 = ubyte;
00473 break;
00474
00475 case CK_INSTR:
00476 case CK_DATA:
00477 case CK_SADDR_32:
00478 case CK_GADDR_32:
00479 case CK_CADDR_32:
00480 case CK_SADDR_64:
00481 case CK_GADDR_64:
00482 case CK_CADDR_64:
00483 case CK_NO_XFORM:
00484 case CK_NO_REORDER:
00485 case CK_STUBS:
00486 case EK_FCALL_MULT:
00487 case EK_FCALL_MULT_PARTIAL:
00488 case EK_CK_UNUSED_ULEB128_0:
00489 case EK_CK_UNUSED_ULEB128_1:
00490 case EK_CK_UNUSED_ULEB128_2:
00491 case EK_CK_UNUSED_ULEB128_3:
00492 case EK_CK_UNUSED_ULEB128_4:
00493 case EK_CK_UNUSED_ULEB128_5:
00494 case EK_CK_UNUSED_ULEB128_6:
00495 case EK_CK_UNUSED_ULEB128_7:
00496 case EK_CK_UNUSED_ULEB128_8:
00497 case EK_CK_UNUSED_ULEB128_9:
00498 len = _leb128_unsigned_decode32(p_event,&uword);
00499 p_event += len;
00500 p_full->fevnt_arg1 = uword;
00501 p_full->fevnt_pre_arg1 = uword;
00502 break;
00503
00504 case EK_BB_START:
00505 case EK_NULL:
00506 case EK_ENTRY:
00507 case EK_EXIT:
00508 case EK_PEND:
00509 case EK_GPREL:
00510 case EK_CK_UNUSED_NONE_0:
00511 case EK_CK_UNUSED_NONE_1:
00512 case EK_CK_UNUSED_NONE_2:
00513 case EK_CK_UNUSED_NONE_3:
00514 case EK_CK_UNUSED_NONE_4:
00515 break;
00516
00517
00518
00519
00520
00521 case CK_GP_GROUP:
00522
00523 len = _leb128_unsigned_decode32(p_event,&uword);
00524 p_event += len;
00525 p_full->fevnt_arg1 = uword;
00526 p_full->fevnt_pre_arg1 = uword;
00527
00528 p_full->fevnt_arg2 = event_get_word32 (p_event);
00529 p_event += 4;
00530
00531 break;
00532
00533
00534
00535
00536
00537 case EK_IF_ENTRY:
00538 case EK_LTR_FCALL:
00539 case EK_FCALL_LOCAL:
00540 case EK_CK_UNUSED_32BIT_0:
00541 case EK_CK_UNUSED_32BIT_1:
00542 case EK_CK_UNUSED_32BIT_2:
00543
00544 temp_offset = event_get_word32(p_event);
00545 p_full->fevnt_arg1 = temp_offset;
00546 p_full->fevnt_pre_arg1 = temp_offset;
00547 p_event += 4;
00548 break;
00549
00550 case EK_FCALL_EXTERN_BIG:
00551 ushort = event_get_word16(p_event);
00552 p_full->fevnt_arg1 = ushort;
00553 p_full->fevnt_pre_arg1 = ushort;
00554 p_event += 2;
00555 ushort = event_get_word16(p_event);
00556 p_full->fevnt_arg2 = ushort;
00557 p_full->fevnt_pre_arg2 = ushort;
00558 p_event += 2;
00559 break;
00560
00561
00562
00563
00564 case EK_FCALL_EXTERN:
00565 ushort = event_get_word16(p_event);
00566 p_full->fevnt_arg1 = ushort;
00567 p_full->fevnt_pre_arg1 = ushort;
00568 p_event += 2;
00569 break;
00570
00571 default:
00572
00573 break;
00574 }
00575
00576 p_full->fevnt_offset = offset;
00577 p_full->fevnt_type = type;
00578
00579 return(p_event);
00580 }
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595 __uint32_t
00596 event_find_record(
00597 char *p_event,
00598 Full_Events *p_full,
00599 __uint32_t type,
00600 char *p_end)
00601 {
00602
00603 while (p_event < p_end) {
00604 p_event = event_get_next_rec(p_event, p_full->fevnt_offset, p_full);
00605 if (p_full->fevnt_type == type)
00606 return((__uint32_t)type);
00607
00608 }
00609
00610 return (EK_NULL);
00611 }
00612