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 #include "globals.h"
00036 #include "dwarf_names.h"
00037
00038 #ifdef __MINGW32__
00039 #include "translatetypes.h"
00040 #endif
00041
00042
00043
00044
00045
00046
00047
00048
00049 static Dwarf_Unsigned local_dwarf_decode_u_leb128(unsigned char *leb128,
00050 unsigned int
00051 *leb128_length);
00052
00053
00054
00055 static char *regnames[] = {
00056 "cfa", "r1/at", "r2/v0", "r3/v1",
00057 "r4/a0", "r5/a1", "r6/a2", "r7/a3",
00058 "r8/t0", "r9/t1", "r10/t2", "r11/t3",
00059 "r12/t4", "r13/t5", "r14/t6", "r15/t7",
00060 "r16/s0", "r17/s1", "r18/s2", "r19/s3",
00061 "r20/s4", "r21/s5", "r22/s6", "r23/s7",
00062 "r24/t8", "r25/t9", "r26/k0", "r27/k1",
00063 "r28/gp", "r29/sp", "r30/s8", "r31",
00064
00065 "$f0", "$f1",
00066 "$f2", "$f3",
00067 "$f4", "$f5",
00068 "$f6", "$f7",
00069 "$f8", "$f9",
00070 "$f10", "$f11",
00071 "$f12", "$f13",
00072 "$f14", "$f15",
00073 "$f16", "$f17",
00074 "$f18", "$f19",
00075 "$f20", "$f21",
00076 "$f22", "$f23",
00077 "$f24", "$f25",
00078 "$f26", "$f27",
00079 "$f28", "$f29",
00080 "$f30", "$f31",
00081 "ra", "slk",
00082
00083 };
00084 static void printreg(Dwarf_Signed);
00085
00086
00087 Dwarf_Die current_cu_die_for_print_frames;
00088
00089 extern void
00090 print_line_numbers_this_cu(Dwarf_Debug dbg, Dwarf_Die cu_die)
00091 {
00092 Dwarf_Signed linecount;
00093 Dwarf_Line *linebuf;
00094 Dwarf_Signed i;
00095 Dwarf_Addr pc;
00096 Dwarf_Unsigned lineno;
00097 Dwarf_Signed column;
00098 string filename;
00099 Dwarf_Bool newstatement;
00100 Dwarf_Bool lineendsequence;
00101 Dwarf_Bool new_basic_block;
00102 int lres;
00103 int sres;
00104 int ares;
00105 int lires;
00106 int cores;
00107
00108 printf("\nline number info\n");
00109 if (verbose > 1) {
00110 lres = _dwarf_print_lines(cu_die, &err);
00111 if (lres == DW_DLV_ERROR) {
00112 print_error(dbg, "dwarf_srclines details", lres, err);
00113 }
00114 return;
00115 }
00116 lres = dwarf_srclines(cu_die, &linebuf, &linecount, &err);
00117 if (lres == DW_DLV_ERROR) {
00118 print_error(dbg, "dwarf_srclines", lres, err);
00119 } else if (lres == DW_DLV_NO_ENTRY) {
00120
00121 } else {
00122 printf
00123 ("<source>\t[row,column]\t<pc>\t//<new statement or basic block\n");
00124
00125 for (i = 0; i < linecount; i++) {
00126 Dwarf_Line line = linebuf[i];
00127 int nsres;
00128
00129 sres = dwarf_linesrc(line, &filename, &err);
00130 ares = dwarf_lineaddr(line, &pc, &err);
00131 if (sres == DW_DLV_ERROR) {
00132 print_error(dbg, "dwarf_linesrc", sres, err);
00133 }
00134 if (sres == DW_DLV_NO_ENTRY) {
00135 filename = "<unknown>";
00136 }
00137 if (ares == DW_DLV_ERROR) {
00138 print_error(dbg, "dwarf_lineaddr", ares, err);
00139 }
00140 if (ares == DW_DLV_NO_ENTRY) {
00141 pc = 0;
00142 }
00143 lires = dwarf_lineno(line, &lineno, &err);
00144 if (lires == DW_DLV_ERROR) {
00145 print_error(dbg, "dwarf_lineno", lires, err);
00146 }
00147 if (lires == DW_DLV_NO_ENTRY) {
00148 lineno = -1LL;
00149 }
00150 cores = dwarf_lineoff(line, &column, &err);
00151 if (cores == DW_DLV_ERROR) {
00152 print_error(dbg, "dwarf_lineoff", cores, err);
00153 }
00154 if (cores == DW_DLV_NO_ENTRY) {
00155 column = -1LL;
00156 }
00157 printf("%s:\t[%3llu,%2lld]\t%#llx", filename, lineno,
00158 column, pc);
00159 if (sres == DW_DLV_OK)
00160 dwarf_dealloc(dbg, filename, DW_DLA_STRING);
00161
00162 nsres = dwarf_linebeginstatement(line, &newstatement, &err);
00163 if (nsres == DW_DLV_OK) {
00164 if (newstatement) {
00165 printf("\t// new statement");
00166 }
00167 } else if (nsres == DW_DLV_ERROR) {
00168 print_error(dbg, "linebeginstatment failed", nsres,
00169 err);
00170 }
00171 nsres = dwarf_lineblock(line, &new_basic_block, &err);
00172 if (nsres == DW_DLV_OK) {
00173 if (new_basic_block) {
00174 printf("\t// new basic block");
00175 }
00176 } else if (nsres == DW_DLV_ERROR) {
00177 print_error(dbg, "lineblock failed", nsres, err);
00178 }
00179 nsres = dwarf_lineendsequence(line, &lineendsequence, &err);
00180 if (nsres == DW_DLV_OK) {
00181 if (lineendsequence) {
00182 printf("\t// end of text sequence");
00183 }
00184 } else if (nsres == DW_DLV_ERROR) {
00185 print_error(dbg, "lineblock failed", nsres, err);
00186 }
00187 printf("\n");
00188
00189 dwarf_dealloc(dbg, line, DW_DLA_LINE);
00190 }
00191 dwarf_dealloc(dbg, linebuf, DW_DLA_LIST);
00192 }
00193 }
00194
00195
00196
00197
00198
00199
00200
00201 static void
00202 safe_strcpy(char *out, int outlen, char *in, int inlen)
00203 {
00204 if (inlen >= (outlen - 1)) {
00205 strncpy(out, in, outlen - 1);
00206 out[outlen - 1] = 0;
00207 } else {
00208 strcpy(out, in);
00209 }
00210 }
00211
00212
00213
00214
00215
00216
00217
00218 static int
00219 get_proc_name(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr low_pc,
00220 char *proc_name_buf, int proc_name_buf_len)
00221 {
00222 Dwarf_Signed atcnt, i;
00223 Dwarf_Attribute *atlist;
00224 Dwarf_Addr low_pc_die = 0;
00225 int atres;
00226 int funcres = 1;
00227 int funcpcfound = 0;
00228 int funcnamefound = 1;
00229
00230 proc_name_buf[0] = 0;
00231 atres = dwarf_attrlist(die, &atlist, &atcnt, &err);
00232 if (atres == DW_DLV_ERROR) {
00233 print_error(dbg, "dwarf_attrlist", atres, err);
00234 return 0;
00235 }
00236 if (atres == DW_DLV_NO_ENTRY) {
00237 return 0;
00238 }
00239 for (i = 0; i < atcnt; i++) {
00240 Dwarf_Half attr;
00241 int ares;
00242 string temps;
00243 int sres;
00244 int dres;
00245
00246 if (funcnamefound == 1 && funcpcfound == 1) {
00247
00248 break;
00249 }
00250 ares = dwarf_whatattr(atlist[i], &attr, &err);
00251 if (ares == DW_DLV_ERROR) {
00252 print_error(dbg, "get_proc_name whatattr error", ares, err);
00253 } else if (ares == DW_DLV_OK) {
00254 switch (attr) {
00255 case DW_AT_name:
00256 sres = dwarf_formstring(atlist[i], &temps, &err);
00257 if (sres == DW_DLV_ERROR) {
00258 print_error(dbg,
00259 "formstring in get_proc_name failed",
00260 sres, err);
00261 safe_strcpy(proc_name_buf, proc_name_buf_len, "ERROR in dwarf_formstring!", 50
00262
00263
00264
00265
00266
00267 );
00268 } else if (sres == DW_DLV_NO_ENTRY) {
00269 safe_strcpy(proc_name_buf, proc_name_buf_len, "NO ENTRY on dwarf_formstring?!", 50
00270
00271
00272
00273
00274
00275 );
00276 } else {
00277 int len = strlen(temps);
00278
00279 safe_strcpy(proc_name_buf, proc_name_buf_len, temps,
00280 len);
00281 dwarf_dealloc(dbg, temps, DW_DLA_STRING);
00282 }
00283 funcnamefound = 1;
00284 break;
00285 case DW_AT_low_pc:
00286 dres = dwarf_formaddr(atlist[i], &low_pc_die, &err);
00287 if (dres == DW_DLV_ERROR) {
00288 print_error(dbg, "formaddr in get_proc_name failed",
00289 dres, err);
00290 low_pc_die = ~low_pc;
00291
00292 }
00293 funcpcfound = 1;
00294
00295 break;
00296 default:
00297 break;
00298 }
00299 }
00300 }
00301 for (i = 0; i < atcnt; i++) {
00302 dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);
00303 }
00304 dwarf_dealloc(dbg, atlist, DW_DLA_LIST);
00305 if (funcnamefound == 0 || funcpcfound == 0 || low_pc != low_pc_die) {
00306 funcres = 0;
00307 }
00308 return (funcres);
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 static int
00322 get_nested_proc_name(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr low_pc,
00323 char *ret_name_buf, int ret_name_buf_len)
00324 {
00325 char name_buf[BUFSIZ];
00326 Dwarf_Die curdie = die;
00327 int die_locally_gotten = 0;
00328 Dwarf_Die prev_child = 0;
00329 Dwarf_Die newchild = 0;
00330 Dwarf_Die newsibling = 0;
00331 Dwarf_Half tag;
00332 Dwarf_Error err = 0;
00333 int chres = DW_DLV_OK;
00334
00335 ret_name_buf[0] = 0;
00336 while (chres == DW_DLV_OK) {
00337 int tres;
00338
00339 tres = dwarf_tag(curdie, &tag, &err);
00340 newchild = 0;
00341 err = 0;
00342 if (tres == DW_DLV_OK) {
00343 int lchres;
00344
00345 if (tag == DW_TAG_subprogram) {
00346 int proc_name_v;
00347
00348 proc_name_v = get_proc_name(dbg, curdie, low_pc,
00349 name_buf, BUFSIZ);
00350 if (proc_name_v) {
00351
00352 safe_strcpy(ret_name_buf, ret_name_buf_len,
00353 name_buf, strlen(name_buf));
00354 if (die_locally_gotten) {
00355
00356
00357 dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
00358 }
00359 return 1;
00360 }
00361
00362
00363
00364 lchres = dwarf_child(curdie, &newchild, &err);
00365 if (lchres == DW_DLV_OK) {
00366
00367 int newprog =
00368 get_nested_proc_name(dbg, newchild, low_pc,
00369 name_buf, BUFSIZ);
00370 dwarf_dealloc(dbg, newchild, DW_DLA_DIE);
00371 if (newprog) {
00372
00373
00374
00375 safe_strcpy(ret_name_buf, ret_name_buf_len,
00376 name_buf, strlen(name_buf));
00377 return 1;
00378 }
00379 } else if (lchres == DW_DLV_NO_ENTRY) {
00380
00381 } else {
00382 print_error(dbg,
00383 "get_nested_proc_name dwarf_child() failed ",
00384 chres, err);
00385 if (die_locally_gotten) {
00386
00387
00388 dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
00389 }
00390 return 0;
00391 }
00392 }
00393 } else {
00394 print_error(dbg, "no tag on child read ", tres, err);
00395 if (die_locally_gotten) {
00396
00397
00398 dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
00399 }
00400 return 0;
00401 }
00402
00403 prev_child = curdie;
00404 chres = dwarf_siblingof(dbg, curdie, &newsibling, &err);
00405 if (chres == DW_DLV_ERROR) {
00406 print_error(dbg, "dwarf_cu_header On Child read ", chres,
00407 err);
00408 if (die_locally_gotten) {
00409
00410
00411 dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
00412 }
00413 return 0;
00414 } else if (chres == DW_DLV_NO_ENTRY) {
00415 return 0;
00416 } else {
00417 curdie = newsibling;
00418 if (die_locally_gotten) {
00419
00420
00421 dwarf_dealloc(dbg, prev_child, DW_DLA_DIE);
00422 }
00423 prev_child = 0;
00424 die_locally_gotten = 1;
00425 }
00426
00427 }
00428 if (die_locally_gotten) {
00429
00430
00431 dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
00432 }
00433 return 0;
00434 }
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449 string
00450 get_fde_proc_name(Dwarf_Debug dbg, Dwarf_Addr low_pc)
00451 {
00452 static char proc_name[BUFSIZ];
00453 Dwarf_Unsigned cu_header_length;
00454 Dwarf_Unsigned abbrev_offset;
00455 Dwarf_Half version_stamp;
00456 Dwarf_Half address_size;
00457 Dwarf_Unsigned next_cu_offset = 0;
00458 int cures = DW_DLV_OK;
00459 int dres = DW_DLV_OK;
00460 int chres = DW_DLV_OK;
00461 int looping = 0;
00462
00463 if (current_cu_die_for_print_frames == NULL) {
00464 cures
00465 = dwarf_next_cu_header(dbg, &cu_header_length,
00466 &version_stamp, &abbrev_offset,
00467 &address_size, &next_cu_offset,
00468 &err);
00469 if (cures == DW_DLV_ERROR) {
00470 return NULL;
00471 } else if (cures == DW_DLV_NO_ENTRY) {
00472
00473 current_cu_die_for_print_frames = 0;
00474 ++looping;
00475 } else {
00476 dres = dwarf_siblingof(dbg, NULL,
00477 ¤t_cu_die_for_print_frames,
00478 &err);
00479 if (dres == DW_DLV_ERROR) {
00480 return NULL;
00481 }
00482 }
00483 }
00484 if (dres == DW_DLV_OK) {
00485 Dwarf_Die child = 0;
00486
00487 if (current_cu_die_for_print_frames == 0) {
00488
00489 return NULL;
00490 }
00491 chres =
00492 dwarf_child(current_cu_die_for_print_frames, &child, &err);
00493 if (chres == DW_DLV_ERROR) {
00494 print_error(dbg, "dwarf_cu_header on child read ", chres,
00495 err);
00496 } else if (chres == DW_DLV_NO_ENTRY) {
00497 } else {
00498 int gotname =
00499 get_nested_proc_name(dbg, child, low_pc, proc_name,
00500 BUFSIZ);
00501 if (gotname) {
00502 return (proc_name);
00503 }
00504 dwarf_dealloc(dbg, child, DW_DLA_DIE);
00505 child = 0;
00506 }
00507 }
00508 for (;;) {
00509 Dwarf_Die ldie;
00510
00511 cures = dwarf_next_cu_header(dbg, &cu_header_length,
00512 &version_stamp, &abbrev_offset,
00513 &address_size, &next_cu_offset,
00514 &err);
00515
00516 if (cures != DW_DLV_OK) {
00517 break;
00518 }
00519
00520
00521 dres = dwarf_siblingof(dbg, NULL, &ldie, &err);
00522
00523 if (current_cu_die_for_print_frames) {
00524 dwarf_dealloc(dbg, current_cu_die_for_print_frames,
00525 DW_DLA_DIE);
00526 }
00527 current_cu_die_for_print_frames = 0;
00528 if (dres == DW_DLV_ERROR) {
00529 print_error(dbg,
00530 "dwarf_cu_header Child Read finding proc name for .debug_frame",
00531 chres, err);
00532 continue;
00533 } else if (dres == DW_DLV_NO_ENTRY) {
00534 ++looping;
00535 if (looping > 1) {
00536 print_error(dbg, "looping on cu headers!", dres, err);
00537 return NULL;
00538 }
00539 continue;
00540 }
00541
00542 current_cu_die_for_print_frames = ldie;
00543 {
00544 int chres;
00545 Dwarf_Die child;
00546
00547 chres =
00548 dwarf_child(current_cu_die_for_print_frames, &child,
00549 &err);
00550 if (chres == DW_DLV_ERROR) {
00551 print_error(dbg, "dwarf Child Read ", chres, err);
00552 } else if (chres == DW_DLV_NO_ENTRY) {
00553
00554 ;
00555 } else {
00556
00557 int gotname =
00558 get_nested_proc_name(dbg, child, low_pc, proc_name,
00559 BUFSIZ);
00560 if (gotname) {
00561 return (proc_name);
00562 }
00563 dwarf_dealloc(dbg, child, DW_DLA_DIE);
00564 }
00565 }
00566 }
00567 return (NULL);
00568 }
00569
00570 static void
00571 print_frame_inst_bytes(Dwarf_Debug dbg,
00572 Dwarf_Ptr cie_init_inst, Dwarf_Signed len,
00573 Dwarf_Signed data_alignment_factor,
00574 int code_alignment_factor, Dwarf_Half addr_size)
00575 {
00576 unsigned char *instp = (unsigned char *) cie_init_inst;
00577 Dwarf_Unsigned uval;
00578 Dwarf_Unsigned uval2;
00579 unsigned int uleblen;
00580 unsigned int off = 0;
00581 unsigned int loff = 0;
00582 unsigned short u16;
00583 unsigned int u32;
00584 unsigned long long u64;
00585
00586 for (; len > 0;) {
00587 unsigned char ibyte = *instp;
00588 int top = ibyte & 0xc0;
00589 int bottom = ibyte & 0x3f;
00590 int delta;
00591 int reg;
00592
00593 switch (top) {
00594 case DW_CFA_advance_loc:
00595 delta = ibyte & 0x3f;
00596 printf("\t%2u DW_CFA_advance_loc %d", off,
00597 (int) (delta * code_alignment_factor));
00598 if (verbose) {
00599 printf(" (%d * %d)", (int) delta,
00600 (int) code_alignment_factor);
00601 }
00602 printf("\n");
00603 break;
00604 case DW_CFA_offset:
00605 loff = off;
00606 reg = ibyte & 0x3f;
00607 uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
00608 instp += uleblen;
00609 len -= uleblen;
00610 off += uleblen;
00611 printf("\t%2u DW_CFA_offset ", loff);
00612 printreg(reg);
00613 printf(" %lld", (signed long long)
00614 (((Dwarf_Signed) uval) * data_alignment_factor));
00615 if (verbose) {
00616 printf(" (%llu * %d)", (unsigned long long) uval,
00617 (int) data_alignment_factor);
00618 }
00619 printf("\n");
00620 break;
00621
00622 case DW_CFA_restore:
00623 reg = ibyte & 0x3f;
00624 printf("\t%2u DW_CFA_restore \n", off);
00625 printreg(reg);
00626 printf("\n");
00627 break;
00628
00629 default:
00630 loff = off;
00631 switch (bottom) {
00632 case DW_CFA_set_loc:
00633
00634
00635 switch (addr_size) {
00636 case 4:
00637 {
00638 __uint32_t v32;
00639
00640 memcpy(&v32, instp + 1, addr_size);
00641 uval = v32;
00642 }
00643 break;
00644 case 8:
00645 {
00646 __uint64_t v64;
00647
00648 memcpy(&v64, instp + 1, addr_size);
00649 uval = v64;
00650 }
00651 default:
00652 printf
00653 ("Error: Unexpected address size %d in DW_CFA_set_loc!\n",
00654 addr_size);
00655 uval = 0;
00656 }
00657
00658 instp += addr_size;
00659 len -= (Dwarf_Signed) addr_size;
00660 off += addr_size;
00661 printf("\t%2u DW_CFA_set_loc %llu\n",
00662 loff, (unsigned long long) uval);
00663 break;
00664 case DW_CFA_advance_loc1:
00665 delta = (unsigned char) *(instp + 1);
00666 uval2 = delta;
00667 instp += 1;
00668 len -= 1;
00669 off += 1;
00670 printf("\t%2u DW_CFA_advance_loc1 %llu\n",
00671 loff, (unsigned long long) uval2);
00672 break;
00673 case DW_CFA_advance_loc2:
00674 memcpy(&u16, instp + 1, 2);
00675 uval2 = u16;
00676 instp += 2;
00677 len -= 2;
00678 off += 2;
00679 printf("\t%2u DW_CFA_advance_loc2 %llu\n",
00680 loff, (unsigned long long) uval2);
00681 break;
00682 case DW_CFA_advance_loc4:
00683 memcpy(&u32, instp + 1, 4);
00684 uval2 = u32;
00685 instp += 4;
00686 len -= 4;
00687 off += 4;
00688 printf("\t%2u DW_CFA_advance_loc4 %llu\n",
00689 loff, (unsigned long long) uval2);
00690 break;
00691 case DW_CFA_MIPS_advance_loc8:
00692 memcpy(&u64, instp + 1, 8);
00693 uval2 = u64;
00694 instp += 8;
00695 len -= 8;
00696 off += 8;
00697 printf("\t%2u DW_CFA_MIPS_advance_loc8 %llu\n",
00698 loff, (unsigned long long) uval2);
00699 break;
00700 case DW_CFA_offset_extended:
00701 uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
00702 instp += uleblen;
00703 len -= uleblen;
00704 off += uleblen;
00705 uval2 =
00706 local_dwarf_decode_u_leb128(instp + 1, &uleblen);
00707 instp += uleblen;
00708 len -= uleblen;
00709 off += uleblen;
00710 printf("\t%2u DW_CFA_offset_extended ", loff);
00711 printreg(uval);
00712 printf(" %lld", (signed long long)
00713 (((Dwarf_Signed) uval2) *
00714 data_alignment_factor));
00715 if (verbose) {
00716 printf(" (%llu * %d)", (unsigned long long) uval2,
00717 (int) data_alignment_factor);
00718 }
00719 printf("\n");
00720 break;
00721
00722 case DW_CFA_restore_extended:
00723 uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
00724 instp += uleblen;
00725 len -= uleblen;
00726 off += uleblen;
00727 printf("\t%2u DW_CFA_restore_extended ", loff);
00728 printreg(uval);
00729 printf("\n");
00730 break;
00731 case DW_CFA_undefined:
00732 uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
00733 instp += uleblen;
00734 len -= uleblen;
00735 off += uleblen;
00736 printf("\t%2u DW_CFA_undefined ", loff);
00737 printreg(uval);
00738 printf("\n");
00739 break;
00740 case DW_CFA_same_value:
00741 uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
00742 instp += uleblen;
00743 len -= uleblen;
00744 off += uleblen;
00745 printf("\t%2u DW_CFA_same_value ", loff);
00746 printreg(uval);
00747 printf("\n");
00748 break;
00749 case DW_CFA_register:
00750 uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
00751 instp += uleblen;
00752 len -= uleblen;
00753 off += uleblen;
00754 uval2 =
00755 local_dwarf_decode_u_leb128(instp + 1, &uleblen);
00756 instp += uleblen;
00757 len -= uleblen;
00758 off += uleblen;
00759 printf("\t%2u DW_CFA_register ", loff);
00760 printreg(uval);
00761 printf(" = ");
00762 printreg(uval2);
00763 printf("\n");
00764 break;
00765 case DW_CFA_remember_state:
00766 printf("\t%2u DW_CFA_remember_state\n", loff);
00767 break;
00768 case DW_CFA_restore_state:
00769 printf("\t%2u DW_CFA_restore_state\n", loff);
00770 break;
00771 case DW_CFA_def_cfa:
00772 uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
00773 instp += uleblen;
00774 len -= uleblen;
00775 off += uleblen;
00776 uval2 =
00777 local_dwarf_decode_u_leb128(instp + 1, &uleblen);
00778 instp += uleblen;
00779 len -= uleblen;
00780 off += uleblen;
00781 printf("\t%2u DW_CFA_def_cfa ", loff);
00782 printreg(uval);
00783 printf(" %llu", (unsigned long long) uval2);
00784 printf("\n");
00785 break;
00786 case DW_CFA_def_cfa_register:
00787 uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
00788 instp += uleblen;
00789 len -= uleblen;
00790 off += uleblen;
00791 printf("\t%2u DW_CFA_def_cfa_register ", loff);
00792 printreg(uval);
00793 printf("\n");
00794 break;
00795 case DW_CFA_def_cfa_offset:
00796 uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
00797 instp += uleblen;
00798 len -= uleblen;
00799 off += uleblen;
00800 printf("\t%2u DW_CFA_def_cfa_offset %llu\n",
00801 loff, (unsigned long long) uval);
00802 break;
00803
00804 case DW_CFA_nop:
00805 printf("\t%2u DW_CFA_nop\n", loff);
00806 break;
00807
00808 case DW_CFA_def_cfa_expression :
00809 break;
00810 case DW_CFA_expression :
00811 break;
00812 #ifdef KEY
00813 case DW_CFA_offset_extended_sf :
00814 #else
00815 case DW_CFA_cfa_offset_extended_sf :
00816 #endif
00817 break;
00818 case DW_CFA_def_cfa_sf :
00819 break;
00820 case DW_CFA_def_cfa_offset_sf :
00821 break;
00822
00823 #ifdef DW_CFA_GNU_window_save
00824 case DW_CFA_GNU_window_save:{
00825
00826
00827
00828 printf("\t%2u DW_CFA_GNU_window_save \n", loff);
00829 break;
00830 }
00831 #endif
00832 #ifdef DW_CFA_GNU_args_size
00833
00834
00835 case DW_CFA_GNU_args_size:{
00836 Dwarf_Unsigned lreg;
00837
00838 lreg =
00839 local_dwarf_decode_u_leb128(instp + 1,
00840 &uleblen);
00841 printf
00842 ("\t%2u DW_CFA_GNU_args_size arg size: %llu\n",
00843 loff, (unsigned long long) lreg);
00844 instp += uleblen;
00845 len -= uleblen;
00846 off += uleblen;
00847
00848 break;
00849 }
00850 #endif
00851
00852 default:
00853 printf
00854 ("\t%u Unexpected op 0x%x: unable to print more\n",
00855 loff, (unsigned int) bottom);
00856 len = 0;
00857 break;
00858 }
00859 }
00860 instp++;
00861 len--;
00862 off++;
00863 }
00864 }
00865
00866
00867 extern void
00868 print_frames(Dwarf_Debug dbg)
00869 {
00870 Dwarf_Cie *cie_data;
00871 Dwarf_Signed cie_element_count;
00872 Dwarf_Fde *fde_data;
00873 Dwarf_Signed fde_element_count;
00874 Dwarf_Signed i, j, k;
00875 Dwarf_Addr low_pc;
00876 Dwarf_Unsigned func_length;
00877 Dwarf_Ptr fde_bytes;
00878 Dwarf_Unsigned fde_bytes_length;
00879 Dwarf_Off cie_offset;
00880 Dwarf_Signed cie_index;
00881 Dwarf_Off fde_offset;
00882 Dwarf_Signed reg;
00883 Dwarf_Signed offset;
00884 Dwarf_Signed eh_table_offset;
00885 Dwarf_Addr row_pc;
00886 int fres;
00887 Dwarf_Half address_size;
00888 int offres;
00889 int framed = 0;
00890
00891 fres = dwarf_get_address_size(dbg, &address_size, &err);
00892 if (fres != DW_DLV_OK) {
00893 print_error(dbg, "dwarf_get_address_size", fres, err);
00894 }
00895 for (framed = 0; framed < 2; ++framed) {
00896 char *framename = 0;
00897 int silent_if_missing = 0;
00898
00899 if (framed == 0) {
00900 framename = ".debug_frame";
00901
00902
00903
00904
00905
00906
00907
00908 fres =
00909 dwarf_get_fde_list(dbg, &cie_data, &cie_element_count,
00910 &fde_data, &fde_element_count, &err);
00911 } else {
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929 silent_if_missing = 1;
00930 framename = ".eh_frame";
00931 fres =
00932 dwarf_get_fde_list_eh(dbg, &cie_data,
00933 &cie_element_count, &fde_data,
00934 &fde_element_count, &err);
00935 }
00936 if (fres == DW_DLV_ERROR) {
00937 printf("\n%s\n", framename);
00938 print_error(dbg, "dwarf_get_fde_list", fres, err);
00939 } else if (fres == DW_DLV_NO_ENTRY) {
00940 if (!silent_if_missing)
00941 printf("\n%s\n", framename);
00942
00943 } else {
00944
00945 printf("\n%s\n", framename);
00946 printf("\nfde:\n");
00947
00948 for (i = 0; i < fde_element_count; i++) {
00949 string temps = 0;
00950 int fres;
00951
00952 fres = dwarf_get_fde_range(fde_data[i],
00953 &low_pc, &func_length,
00954 &fde_bytes,
00955 &fde_bytes_length,
00956 &cie_offset, &cie_index,
00957 &fde_offset, &err);
00958 if (fres == DW_DLV_ERROR) {
00959 print_error(dbg, "dwarf_get_fde_range", fres, err);
00960 }
00961 if (fres == DW_DLV_NO_ENTRY) {
00962 continue;
00963 }
00964 if (cu_name_flag &&
00965 fde_offset_for_cu_low != DW_DLV_BADOFFSET &&
00966 (fde_offset < fde_offset_for_cu_low ||
00967 fde_offset > fde_offset_for_cu_high)) {
00968 continue;
00969 }
00970 fres = dwarf_get_fde_exception_info(fde_data[i],
00971 &eh_table_offset,
00972 &err);
00973 if (fres == DW_DLV_ERROR) {
00974 print_error(dbg, "dwarf_get_fde_exception_info",
00975 fres, err);
00976 }
00977 temps = get_fde_proc_name(dbg, low_pc);
00978 printf
00979 ("<%3lld><%#llx:%#llx><%s><fde offset 0x%llx length: 0x%llx>",
00980 cie_index, low_pc, (low_pc + func_length),
00981 temps ? temps : "", fde_offset, fde_bytes_length);
00982
00983 if (eh_table_offset == DW_DLX_NO_EH_OFFSET) {
00984 printf("<eh offset %s>\n", "none");
00985 } else if (eh_table_offset ==
00986 DW_DLX_EH_OFFSET_UNAVAILABLE) {
00987 printf("<eh offset %s>\n", "unknown");
00988 } else {
00989 printf("<eh offset 0x%llx>\n", eh_table_offset);
00990 }
00991
00992
00993 for (j = low_pc; j < low_pc + func_length; j++) {
00994 for (k = 0; k < DW_FRAME_LAST_REG_NUM; k++) {
00995 Dwarf_Signed offset_relevant;
00996 int fires;
00997
00998 fires = dwarf_get_fde_info_for_reg(fde_data[i],
00999 (Dwarf_Half)
01000 k,
01001 (Dwarf_Addr)
01002 j,
01003 &offset_relevant,
01004 ®,
01005 &offset,
01006 &row_pc,
01007 &err);
01008 if (fires == DW_DLV_ERROR) {
01009 print_error(dbg,
01010 "dwarf_get_fde_info_for_reg",
01011 fires, err);
01012 }
01013 if (fires == DW_DLV_NO_ENTRY) {
01014 continue;
01015 }
01016 if (row_pc != j) {
01017
01018 break;
01019 }
01020 if (k == 0)
01021 printf(" %08llx:\t", j);
01022 switch (reg) {
01023 case DW_FRAME_UNDEFINED_VAL:
01024 printreg(k);
01025 printf("=u ");
01026 break;
01027 case DW_FRAME_SAME_VAL:
01028 break;
01029 default:
01030 printreg(k);
01031 printf("=");
01032 if (offset_relevant == 0) {
01033 printreg(reg);
01034 printf(" ");
01035 } else {
01036 printf("%02lld", offset);
01037 printf("(");
01038 printreg(reg);
01039 printf(") ");
01040 }
01041 break;
01042 }
01043 if (k == DW_FRAME_LAST_REG_NUM - 1) {
01044 printf("\n");
01045 }
01046 }
01047 }
01048 if (verbose > 1) {
01049 Dwarf_Off fde_off;
01050 Dwarf_Off cie_off;
01051
01052
01053
01054 Dwarf_Ptr instrs;
01055 Dwarf_Unsigned ilen;
01056 int res;
01057
01058 res = dwarf_get_fde_instr_bytes(fde_data[i],
01059 &instrs, &ilen,
01060 &err);
01061 offres =
01062 _dwarf_fde_section_offset(dbg, fde_data[i],
01063 &fde_off, &cie_off,
01064 &err);
01065 if (offres == DW_DLV_OK) {
01066 printf("\tfde sec. offset %llu 0x%llx"
01067 " cie offset for fde: %llu 0x%llx\n",
01068 (unsigned long long) fde_off,
01069 (unsigned long long) fde_off,
01070 (unsigned long long) cie_off,
01071 (unsigned long long) cie_off);
01072
01073 }
01074
01075
01076 if (res == DW_DLV_OK) {
01077 int cires;
01078 Dwarf_Unsigned cie_length;
01079 Dwarf_Small version;
01080 string augmenter;
01081 Dwarf_Unsigned code_alignment_factor;
01082 Dwarf_Signed data_alignment_factor;
01083 Dwarf_Half return_address_register_rule;
01084 Dwarf_Ptr initial_instructions;
01085 Dwarf_Unsigned initial_instructions_length;
01086
01087 cires = dwarf_get_cie_info(cie_data[cie_index],
01088 &cie_length,
01089 &version,
01090 &augmenter,
01091 &code_alignment_factor,
01092 &data_alignment_factor,
01093 &return_address_register_rule,
01094 &initial_instructions,
01095 &initial_instructions_length,
01096 &err);
01097 if (cires == DW_DLV_ERROR) {
01098 printf
01099 ("Bad cie index %lld with fde index %lld!\n",
01100 (long long) cie_index, (long long) i);
01101 print_error(dbg, "dwarf_get_cie_info",
01102 cires, err);
01103 }
01104 if (cires == DW_DLV_NO_ENTRY) {
01105 ;
01106 } else {
01107
01108
01109 print_frame_inst_bytes(dbg, instrs, ilen,
01110 data_alignment_factor,
01111 code_alignment_factor,
01112 address_size);
01113 }
01114 } else if (res == DW_DLV_NO_ENTRY) {
01115 printf
01116 ("Impossible: no instr bytes for fde index %d?\n",
01117 (int) i);
01118 } else {
01119
01120 printf
01121 ("Error: on gettinginstr bytes for fde index %d?\n",
01122 (int) i);
01123 print_error(dbg, "dwarf_get_fde_instr_bytes",
01124 res, err);
01125 }
01126
01127 }
01128 }
01129
01130
01131 if (verbose) {
01132 printf("\ncie:\n");
01133 for (i = 0; i < cie_element_count; i++) {
01134 int cires;
01135 Dwarf_Unsigned cie_length;
01136 Dwarf_Small version;
01137 string augmenter;
01138 Dwarf_Unsigned code_alignment_factor;
01139 Dwarf_Signed data_alignment_factor;
01140 Dwarf_Half return_address_register_rule;
01141 Dwarf_Ptr initial_instructions;
01142 Dwarf_Unsigned initial_instructions_length;
01143 Dwarf_Off cie_off;
01144
01145 cires = dwarf_get_cie_info(cie_data[i],
01146 &cie_length,
01147 &version,
01148 &augmenter,
01149 &code_alignment_factor,
01150 &data_alignment_factor,
01151 &return_address_register_rule,
01152 &initial_instructions,
01153 &initial_instructions_length,
01154 &err);
01155 if (cires == DW_DLV_ERROR) {
01156 print_error(dbg, "dwarf_get_cie_info", cires,
01157 err);
01158 }
01159 if (cires == DW_DLV_NO_ENTRY) {
01160 ;
01161 }
01162 if (verbose) {
01163 printf("<%3lld>\tversion\t\t\t\t%d\n", i,
01164 version);
01165 cires =
01166 _dwarf_cie_section_offset(dbg, cie_data[i],
01167 &cie_off, &err);
01168 if (cires == DW_DLV_OK) {
01169 printf("\tcie sec. offset %llu 0x%llx\n",
01170 (unsigned long long) cie_off,
01171 (unsigned long long) cie_off);
01172
01173 }
01174
01175 printf("\taugmentation\t\t\t%s\n", augmenter);
01176 printf("\tcode_alignment_factor\t\t%llu\n",
01177 code_alignment_factor);
01178 printf("\tdata_alignment_factor\t\t%lld\n",
01179 data_alignment_factor);
01180 printf("\treturn_address_register\t\t%d\n",
01181 return_address_register_rule);
01182 printf
01183 ("\tbytes of initial instructions:\t%lld\n",
01184 (long long) initial_instructions_length);
01185 printf("\tcie length :\t\t\t%lld\n",
01186 (long long) cie_length);
01187 print_frame_inst_bytes(dbg,
01188 initial_instructions,
01189 initial_instructions_length,
01190 data_alignment_factor,
01191 code_alignment_factor,
01192 address_size);
01193 }
01194 }
01195 }
01196 dwarf_dealloc(dbg, cie_data, DW_DLA_LIST);
01197 dwarf_dealloc(dbg, fde_data, DW_DLA_LIST);
01198 }
01199 }
01200 }
01201
01202
01203 extern void
01204 print_pubnames(Dwarf_Debug dbg)
01205 {
01206 Dwarf_Global *globbuf;
01207 Dwarf_Signed count;
01208 Dwarf_Signed i;
01209 Dwarf_Die die;
01210 Dwarf_Off die_off;
01211 Dwarf_Off die_CU_off;
01212 Dwarf_Die cu_die;
01213 Dwarf_Off cu_off;
01214 char *name;
01215 int res;
01216
01217 printf("\n.debug_pubnames\n");
01218 res = dwarf_get_globals(dbg, &globbuf, &count, &err);
01219 if (res == DW_DLV_ERROR) {
01220 print_error(dbg, "dwarf_get_globals", res, err);
01221 } else if (res == DW_DLV_NO_ENTRY) {
01222
01223
01224 } else {
01225 for (i = 0; i < count; i++) {
01226 int nres;
01227 int dres;
01228 int ddres;
01229 int cudres;
01230
01231 nres = dwarf_global_name_offsets(globbuf[i],
01232 &name, &die_off, &cu_off,
01233 &err);
01234 if (nres != DW_DLV_OK) {
01235 print_error(dbg, "dwarf_global_name_offsets",
01236 nres, err);
01237 }
01238
01239
01240 dres = dwarf_offdie(dbg, die_off, &die, &err);
01241 if (dres != DW_DLV_OK)
01242 print_error(dbg, "dwarf_offdie", dres, err);
01243
01244
01245 ddres = dwarf_die_CU_offset(die, &die_CU_off, &err);
01246 if (ddres != DW_DLV_OK) {
01247 print_error(dbg, "dwarf_die_CU_offset", ddres, err);
01248 }
01249
01250
01251 cudres = dwarf_offdie(dbg, cu_off, &cu_die, &err);
01252 if (cudres != DW_DLV_OK) {
01253 print_error(dbg, "dwarf_offdie", cudres, err);
01254 }
01255 printf("global %-15s die %lld, cu-die %lld,"
01256 " off-in-cu %lld, cu %lld",
01257 name, (long long) die_off, (long long) cu_off,
01258
01259 (long long) die_CU_off,
01260
01261
01262 (long long) (die_off - die_CU_off));
01263 {
01264
01265
01266 Dwarf_Off off = 0;
01267 int cures3 = dwarf_global_cu_offset(globbuf[i],
01268 &off, &err);
01269
01270 if (cures3 != DW_DLV_OK) {
01271 print_error(dbg, "dwarf_global_cu_offset", cudres,
01272 err);
01273 }
01274 if ((die_off - die_CU_off) != off) {
01275 printf(" error: real cuhdr %llu", off);
01276 exit(1);
01277 }
01278
01279 }
01280 printf("\n");
01281 dwarf_dealloc(dbg, name, DW_DLA_STRING);
01282
01283
01284 if (check_pubname_attr) {
01285 Dwarf_Bool has_attr;
01286 int ares;
01287
01288 ares =
01289 dwarf_hasattr(die, DW_AT_external, &has_attr, &err);
01290 if (ares == DW_DLV_ERROR) {
01291 print_error(dbg, "hassattr on DW_AT_external", ares,
01292 err);
01293 }
01294 pubname_attr_result.checks++;
01295 if (ares == DW_DLV_OK && has_attr) {
01296
01297 } else {
01298 pubname_attr_result.errors++;
01299 DWARF_CHECK_ERROR2(name,
01300 "pubname does not have DW_AT_external")
01301 }
01302 }
01303
01304 dwarf_dealloc(dbg, globbuf[i], DW_DLA_GLOBAL);
01305 }
01306 dwarf_dealloc(dbg, globbuf, DW_DLA_LIST);
01307 }
01308 }
01309
01310
01311 struct macro_counts_s {
01312 long mc_start_file;
01313 long mc_end_file;
01314 long mc_define;
01315 long mc_undef;
01316 long mc_extension;
01317 long mc_code_zero;
01318 long mc_unknown;
01319 };
01320
01321 static void
01322 print_one_macro_entry_detail(long i,
01323 char *type,
01324 struct Dwarf_Macro_Details_s *mdp)
01325 {
01326
01327 if(mdp->dmd_macro) {
01328 printf( "%3ld %s: %6llu %2lld [%4lld] \"%s\" \n",
01329 i,
01330 type,
01331 mdp->dmd_offset,
01332 mdp->dmd_fileindex,
01333 mdp->dmd_lineno,
01334 mdp->dmd_macro);
01335 }else {
01336 printf( "%3ld %s: %6llu %2lld [%4lld] 0\n",
01337 i,
01338 type,
01339 mdp->dmd_offset,
01340 mdp->dmd_fileindex,
01341 mdp->dmd_lineno );
01342 }
01343
01344 }
01345
01346 static void
01347 print_one_macro_entry(long i,
01348 struct Dwarf_Macro_Details_s *mdp,
01349 struct macro_counts_s*counts)
01350 {
01351
01352 switch (mdp->dmd_type) {
01353 case 0:
01354 counts->mc_code_zero++;
01355 print_one_macro_entry_detail(i,"DW_MACINFO_type-code-0",mdp);
01356 break;
01357
01358 case DW_MACINFO_start_file :
01359 counts->mc_start_file++;
01360 print_one_macro_entry_detail(i,"DW_MACINFO_start_file",mdp);
01361 break;
01362
01363 case DW_MACINFO_end_file :
01364 counts->mc_end_file++;
01365 print_one_macro_entry_detail(i,"DW_MACINFO_end_file ",mdp);
01366 break;
01367
01368 case DW_MACINFO_vendor_ext :
01369 counts->mc_extension++;
01370 print_one_macro_entry_detail(i,"DW_MACINFO_vendor_ext",mdp);
01371 break;
01372
01373 case DW_MACINFO_define:
01374 counts->mc_define++;
01375 print_one_macro_entry_detail(i,"DW_MACINFO_define ",mdp);
01376 break;
01377
01378 case DW_MACINFO_undef:
01379 counts->mc_undef++;
01380 print_one_macro_entry_detail(i,"DW_MACINFO_undef ",mdp);
01381 break;
01382
01383 default:
01384 {
01385 char create_type[50];
01386 counts->mc_unknown++;
01387 snprintf(create_type,sizeof(create_type),
01388 "DW_MACINFO_0x%x", mdp->dmd_type);
01389 print_one_macro_entry_detail(i,create_type,mdp);
01390 }
01391 break;
01392 }
01393 }
01394
01395
01396
01397
01398
01399 extern void
01400 print_macinfo(Dwarf_Debug dbg)
01401 {
01402 Dwarf_Off offset = 0;
01403 Dwarf_Unsigned max = 0;
01404 Dwarf_Signed count;
01405 long group = 0;
01406 Dwarf_Macro_Details *maclist;
01407 int lres;
01408
01409 printf("\n.debug_macinfo\n");
01410
01411 while ((lres = dwarf_get_macro_details(dbg, offset,
01412 max, &count, &maclist,
01413 &err)) == DW_DLV_OK) {
01414 long i;
01415 struct macro_counts_s counts;
01416
01417
01418 memset(&counts, 0,sizeof(counts));
01419
01420 printf("\n");
01421 printf("compilation-unit .debug_macinfo # %ld\n",group);
01422 printf("num name section-offset file-index [line] \"string\"\n");
01423 for (i = 0; i < count; i++) {
01424 struct Dwarf_Macro_Details_s *mdp = &
01425 maclist[i];
01426 print_one_macro_entry(i,mdp,&counts);
01427 }
01428
01429 if(counts.mc_start_file == 0) {
01430 printf("DW_MACINFO file count of zero is invalid DWARF2/3\n");
01431 }
01432 if(counts.mc_start_file != counts.mc_end_file) {
01433 printf("Counts of DW_MACINFO file (%ld) end_file (%ld) "
01434 "do not match!.\n",
01435 counts.mc_start_file,counts.mc_end_file);
01436 }
01437 if(counts.mc_code_zero < 1) {
01438 printf("Count of zeros in macro group should be non-zero "
01439 "(1 preferred), count is %ld\n",
01440 counts.mc_code_zero );
01441 }
01442 printf("Macro counts: start file %ld, "
01443 "end file %ld, "
01444 "define %ld, "
01445 "undef %ld "
01446 "ext %ld, "
01447 "code-zero %ld, "
01448 "unknown %ld\n",
01449 counts.mc_start_file,
01450 counts.mc_end_file,
01451 counts.mc_define,
01452 counts.mc_undef,
01453 counts.mc_extension,
01454 counts.mc_code_zero,
01455 counts.mc_unknown);
01456
01457
01458
01459
01460
01461 offset = maclist[count - 1].dmd_offset + 1;
01462 dwarf_dealloc(dbg, maclist, DW_DLA_STRING);
01463 ++group;
01464 }
01465 if (lres == DW_DLV_ERROR) {
01466 print_error(dbg, "dwarf_get_macro_details", lres, err);
01467 }
01468 }
01469
01470
01471 extern void
01472 print_locs(Dwarf_Debug dbg)
01473 {
01474 Dwarf_Unsigned offset = 0;
01475 Dwarf_Addr hipc_offset;
01476 Dwarf_Addr lopc_offset;
01477 Dwarf_Ptr data;
01478 Dwarf_Unsigned entry_len;
01479 Dwarf_Unsigned next_entry;
01480 int lres;
01481
01482 printf("\n.debug_loc format <o b e l> means "
01483 "section-offset begin-addr end-addr length-of-block-entry\n");
01484 while ((lres = dwarf_get_loclist_entry(dbg, offset,
01485 &hipc_offset, &lopc_offset,
01486 &data, &entry_len,
01487 &next_entry,
01488 &err)) == DW_DLV_OK) {
01489 printf("\t <obel> 0x%08llx 0x%09llx " "0x%08llx " "%8lld\n",
01490 (long long) offset, (long long) lopc_offset,
01491 (long long) hipc_offset, (long long) entry_len);
01492 offset = next_entry;
01493 }
01494 if (lres == DW_DLV_ERROR) {
01495 print_error(dbg, "dwarf_get_loclist_entry", lres, err);
01496 }
01497 }
01498
01499
01500 extern void
01501 print_abbrevs(Dwarf_Debug dbg)
01502 {
01503 Dwarf_Abbrev ab;
01504 Dwarf_Unsigned offset = 0;
01505 Dwarf_Unsigned length;
01506 Dwarf_Unsigned attr_count;
01507 Dwarf_Half tag;
01508 Dwarf_Half attr;
01509 Dwarf_Signed form;
01510 Dwarf_Off off;
01511 Dwarf_Unsigned i;
01512 string child_name;
01513 Dwarf_Unsigned abbrev_num = 1;
01514 Dwarf_Signed child_flag;
01515 int abres;
01516 int tres;
01517 int acres;
01518 Dwarf_Unsigned abbrev_code = 0;
01519
01520 printf("\n.debug_abbrev\n");
01521 while ((abres = dwarf_get_abbrev(dbg, offset, &ab,
01522 &length, &attr_count,
01523 &err)) == DW_DLV_OK) {
01524
01525 if (attr_count == 0) {
01526
01527 if (dense) {
01528 printf("<%lld><%lld><%lld><%s>\n",
01529 abbrev_num,
01530 offset, (signed long long) 0,
01531 "null .debug_abbrev entry");
01532 } else {
01533 printf("<%4lld><%5lld><code: %2lld> %-20s\n",
01534 abbrev_num,
01535 offset, (signed long long) 0,
01536 "null .debug_abbrev entry");
01537 }
01538
01539 offset += length;
01540 ++abbrev_num;
01541 continue;
01542 }
01543 tres = dwarf_get_abbrev_tag(ab, &tag, &err);
01544 if (tres != DW_DLV_OK) {
01545 print_error(dbg, "dwarf_get_abbrev_tag", tres, err);
01546 }
01547 tres = dwarf_get_abbrev_code(ab, &abbrev_code, &err);
01548 if (tres != DW_DLV_OK) {
01549 print_error(dbg, "dwarf_get_abbrev_code", tres, err);
01550 }
01551 if (dense)
01552 printf("<%lld><%lld><%lld><%s>", abbrev_num,
01553 offset, abbrev_code, get_TAG_name(dbg, tag));
01554 else
01555 printf("<%4lld><%5lld><code: %2lld> %-20s", abbrev_num,
01556 offset, abbrev_code, get_TAG_name(dbg, tag));
01557 ++abbrev_num;
01558 acres = dwarf_get_abbrev_children_flag(ab, &child_flag, &err);
01559 if (acres == DW_DLV_ERROR) {
01560 print_error(dbg, "dwarf_get_abbrev_children_flag", acres,
01561 err);
01562 }
01563 if (acres == DW_DLV_NO_ENTRY) {
01564 child_flag = 0;
01565 }
01566 child_name = get_children_name(dbg, child_flag);
01567 if (dense)
01568 printf(" %s", child_name);
01569 else
01570 printf("%s\n", child_name);
01571
01572
01573
01574 for (i = 0; i < attr_count; i++) {
01575 int aeres;
01576
01577 aeres =
01578 dwarf_get_abbrev_entry(ab, i, &attr, &form, &off, &err);
01579 if (aeres == DW_DLV_ERROR) {
01580 print_error(dbg, "dwarf_get_abbrev_entry", aeres, err);
01581 }
01582 if (aeres == DW_DLV_NO_ENTRY) {
01583 attr = -1LL;
01584 form = -1LL;
01585 }
01586 if (dense)
01587 printf(" <%ld>%s<%s>", (unsigned long) off,
01588 get_AT_name(dbg, attr),
01589 get_FORM_name(dbg, form));
01590 else
01591 printf(" <%5ld>\t%-28s%s\n",
01592 (unsigned long) off, get_AT_name(dbg, attr),
01593 get_FORM_name(dbg, form));
01594 }
01595 offset += length;
01596 if (dense)
01597 printf("\n");
01598 }
01599 if (abres == DW_DLV_ERROR) {
01600 print_error(dbg, "dwarf_get_abbrev", abres, err);
01601 }
01602 }
01603
01604
01605 extern void
01606 print_strings(Dwarf_Debug dbg)
01607 {
01608 Dwarf_Signed length;
01609 string name;
01610 Dwarf_Off offset = 0;
01611 int sres;
01612
01613 printf("\n.debug_string\n");
01614 while ((sres = dwarf_get_str(dbg, offset, &name, &length, &err))
01615 == DW_DLV_OK) {
01616 printf("name at offset %lld, length %lld is %s\n",
01617 offset, length, name);
01618 offset += length + 1;
01619 }
01620 if (sres == DW_DLV_ERROR) {
01621 print_error(dbg, "get_str failure", sres, err);
01622 }
01623 }
01624
01625
01626 extern void
01627 print_aranges(Dwarf_Debug dbg)
01628 {
01629 Dwarf_Signed count;
01630 Dwarf_Signed i;
01631 Dwarf_Arange *arange_buf;
01632 Dwarf_Addr start;
01633 Dwarf_Unsigned length;
01634 Dwarf_Off cu_die_offset;
01635 Dwarf_Die cu_die;
01636 int ares;
01637 int aires;
01638
01639 printf("\n.debug_aranges\n");
01640 ares = dwarf_get_aranges(dbg, &arange_buf, &count, &err);
01641 if (ares == DW_DLV_ERROR) {
01642 print_error(dbg, "dwarf_get_aranges", ares, err);
01643 } else if (ares == DW_DLV_NO_ENTRY) {
01644
01645 } else {
01646 for (i = 0; i < count; i++) {
01647 aires = dwarf_get_arange_info(arange_buf[i],
01648 &start, &length,
01649 &cu_die_offset, &err);
01650 if (aires != DW_DLV_OK) {
01651 print_error(dbg, "dwarf_get_arange_info", aires, err);
01652 } else {
01653 int dres;
01654
01655 dres = dwarf_offdie(dbg, cu_die_offset, &cu_die, &err);
01656 if (dres != DW_DLV_OK) {
01657 print_error(dbg, "dwarf_offdie", dres, err);
01658 } else {
01659 if (cu_name_flag) {
01660 Dwarf_Half tag;
01661 Dwarf_Attribute attrib;
01662 Dwarf_Half theform;
01663 int tres;
01664 int dares;
01665 int fres;
01666
01667 tres = dwarf_tag(cu_die, &tag, &err);
01668 if (tres != DW_DLV_OK) {
01669 print_error(dbg, "dwarf_tag in aranges",
01670 tres, err);
01671 }
01672 dares =
01673 dwarf_attr(cu_die, DW_AT_name, &attrib,
01674 &err);
01675 if (dares != DW_DLV_OK) {
01676 print_error(dbg, "dwarf_attr arange"
01677 " derived die has no name",
01678 dres, err);
01679 }
01680 fres = dwarf_whatform(attrib, &theform, &err);
01681 if (fres == DW_DLV_OK) {
01682 if (theform == DW_FORM_string
01683 || theform == DW_FORM_strp) {
01684 string temps;
01685 int sres;
01686
01687 sres =
01688 dwarf_formstring(attrib, &temps,
01689 &err);
01690 if (sres == DW_DLV_OK) {
01691 string p = temps;
01692
01693 if (cu_name[0] != '/') {
01694 p = strrchr(temps, '/');
01695 if (p == NULL) {
01696 p = temps;
01697 } else {
01698 p++;
01699 }
01700 }
01701 if (!strcmp(cu_name, p)) {
01702 dwarf_dealloc(dbg, temps,
01703 DW_DLA_STRING);
01704 } else {
01705 dwarf_dealloc(dbg, temps,
01706 DW_DLA_STRING);
01707 continue;
01708 }
01709 } else {
01710 print_error(dbg,
01711 "arange: string missing",
01712 sres, err);
01713 }
01714 }
01715 } else {
01716 print_error(dbg,
01717 "dwarf_whatform unexpected value",
01718 fres, err);
01719 }
01720 dwarf_dealloc(dbg, attrib, DW_DLA_ATTR);
01721 }
01722 printf("\narange starts at %llx, "
01723 "length of %lld, cu_die_offset = %lld",
01724 start, length, cu_die_offset);
01725
01726
01727 {
01728 Dwarf_Off off = 0;
01729 int cures3 =
01730 dwarf_get_arange_cu_header_offset(arange_buf
01731 [i],
01732 &off,
01733 &err);
01734 if (cures3 != DW_DLV_OK) {
01735 print_error(dbg, "dwarf_get_cu_hdr_offset",
01736 cures3, err);
01737 }
01738 if (verbose)
01739 printf(" cuhdr %llu", off);
01740 }
01741 printf("\n");
01742 print_one_die(dbg, cu_die, (boolean) TRUE,
01743 0,
01744 0);
01745
01746 dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
01747 }
01748 }
01749
01750 dwarf_dealloc(dbg, arange_buf[i], DW_DLA_ARANGE);
01751 }
01752 dwarf_dealloc(dbg, arange_buf, DW_DLA_LIST);
01753 }
01754 }
01755
01756
01757 extern void
01758 print_static_funcs(Dwarf_Debug dbg)
01759 {
01760 Dwarf_Func *funcbuf;
01761 Dwarf_Signed count;
01762 Dwarf_Signed i;
01763 Dwarf_Die die;
01764 Dwarf_Off die_off;
01765 Dwarf_Off die_CU_off;
01766 Dwarf_Die cu_die;
01767 Dwarf_Off cu_off;
01768 char *name;
01769 int gfres;
01770
01771 printf("\n.debug_static_func\n");
01772 gfres = dwarf_get_funcs(dbg, &funcbuf, &count, &err);
01773 if (gfres == DW_DLV_ERROR) {
01774 print_error(dbg, "dwarf_get_funcs", gfres, err);
01775 } else if (gfres == DW_DLV_NO_ENTRY) {
01776
01777 } else {
01778 for (i = 0; i < count; i++) {
01779 int fnres;
01780 int ores;
01781 int cures;
01782 int dores;
01783
01784 fnres =
01785 dwarf_func_name_offsets(funcbuf[i], &name, &die_off,
01786 &cu_off, &err);
01787 if (fnres != DW_DLV_OK) {
01788 print_error(dbg, "dwarf_func_name_offsets", fnres, err);
01789 }
01790 ores = dwarf_offdie(dbg, die_off, &die, &err);
01791 if (ores != DW_DLV_OK)
01792 print_error(dbg, "dwarf_offdie on statics", ores, err);
01793 cures = dwarf_die_CU_offset(die, &die_CU_off, &err);
01794 if (cures != DW_DLV_OK) {
01795 print_error(dbg, "dwarf_die_CU_offset", cures, err);
01796 }
01797 dores = dwarf_offdie(dbg, cu_off, &cu_die, &err);
01798 if (dores != DW_DLV_OK) {
01799 print_error(dbg, "dwarf_offdie2", dores, err);
01800 }
01801 printf("static-func %-15s die %lld, cu-die %lld,"
01802 " off-in-cu %lld, cu %lld",
01803 name, (long long) die_off, (long long) cu_off,
01804
01805 (long long) die_CU_off,
01806
01807
01808 (long long) (die_off - die_CU_off));
01809 if (verbose) {
01810 Dwarf_Off off = 0;
01811 int cures3 = dwarf_func_cu_offset(funcbuf[i],
01812 &off, &err);
01813
01814 if (cures3 != DW_DLV_OK) {
01815 print_error(dbg, "dwarf_arange_cu_offset",
01816 cures3, err);
01817 }
01818 if (((die_off - die_CU_off)) != off) {
01819 printf(" error: real cuhdr %llu", off);
01820 exit(1);
01821 }
01822 }
01823 printf("\n");
01824 dwarf_dealloc(dbg, name, DW_DLA_STRING);
01825
01826 dwarf_dealloc(dbg, funcbuf[i], DW_DLA_FUNC);
01827 }
01828 dwarf_dealloc(dbg, funcbuf, DW_DLA_LIST);
01829 }
01830 }
01831
01832
01833 extern void
01834 print_static_vars(Dwarf_Debug dbg)
01835 {
01836 Dwarf_Var *varbuf;
01837 Dwarf_Signed count;
01838 Dwarf_Signed i;
01839 Dwarf_Die die;
01840 Dwarf_Off die_off;
01841 Dwarf_Off die_CU_off;
01842 Dwarf_Die cu_die;
01843 Dwarf_Off cu_off;
01844 char *name;
01845 int gvres;
01846
01847 printf("\n.debug_static_vars\n");
01848 gvres = dwarf_get_vars(dbg, &varbuf, &count, &err);
01849 if (gvres == DW_DLV_ERROR) {
01850 print_error(dbg, "dwarf_get_vars", gvres, err);
01851 } else if (gvres == DW_DLV_NO_ENTRY) {
01852
01853 } else {
01854 for (i = 0; i < count; i++) {
01855 int vnres;
01856 int ores;
01857 int cures;
01858 int dores;
01859
01860 vnres =
01861 dwarf_var_name_offsets(varbuf[i], &name, &die_off,
01862 &cu_off, &err);
01863 if (vnres != DW_DLV_OK) {
01864 print_error(dbg, "dwarf_var_name_offsets", vnres, err);
01865 }
01866 ores = dwarf_offdie(dbg, die_off, &die, &err);
01867 if (ores != DW_DLV_OK)
01868 print_error(dbg, "dwarf_offdie", ores, err);
01869 cures = dwarf_die_CU_offset(die, &die_CU_off, &err);
01870 if (cures != DW_DLV_OK) {
01871 print_error(dbg, "dwarf_die_CU_offset", cures, err);
01872 }
01873 dores = dwarf_offdie(dbg, cu_off, &cu_die, &err);
01874 if (dores != DW_DLV_OK) {
01875 print_error(dbg, "dwarf_offdie2", dores, err);
01876 }
01877 printf("static-var %-15s die %lld, cu-die %lld,"
01878 " off-in-cu %lld, cu %lld",
01879 name, (long long) die_off, (long long) cu_off,
01880
01881 (long long) die_CU_off,
01882
01883
01884 (long long) (die_off - die_CU_off));
01885 {
01886 Dwarf_Off off = 0;
01887 int cures3 = dwarf_var_cu_offset(varbuf[i],
01888 &off, &err);
01889
01890 if (cures3 != DW_DLV_OK) {
01891 print_error(dbg, "dwarf_arange_cu_offset",
01892 cures3, err);
01893 }
01894 if ((die_off - die_CU_off) != off) {
01895 printf(" error: real cuhdr %llu", off);
01896 exit(1);
01897 }
01898 if (verbose) {
01899 printf(" cuhdr %llu", off);
01900 }
01901 }
01902 printf("\n");
01903
01904
01905 dwarf_dealloc(dbg, name, DW_DLA_STRING);
01906
01907 dwarf_dealloc(dbg, varbuf[i], DW_DLA_VAR);
01908 }
01909 dwarf_dealloc(dbg, varbuf, DW_DLA_LIST);
01910 }
01911 }
01912
01913
01914 extern void
01915 print_types(Dwarf_Debug dbg)
01916 {
01917 Dwarf_Type *typebuf;
01918 Dwarf_Signed count;
01919 Dwarf_Signed i;
01920 Dwarf_Die die;
01921 Dwarf_Off die_off;
01922 Dwarf_Off die_CU_off;
01923 Dwarf_Die cu_die;
01924 Dwarf_Off cu_off;
01925 char *name;
01926 int gtres;
01927
01928 printf("\n.debug_types\n");
01929 gtres = dwarf_get_types(dbg, &typebuf, &count, &err);
01930 if (gtres == DW_DLV_ERROR) {
01931 print_error(dbg, "dwarf_get_types", gtres, err);
01932 } else if (gtres == DW_DLV_NO_ENTRY) {
01933
01934 } else {
01935 for (i = 0; i < count; i++) {
01936 int tnres;
01937 int ores;
01938 int cures;
01939 int dores;
01940
01941 tnres = dwarf_type_name_offsets(typebuf[i], &name,
01942 &die_off, &cu_off, &err);
01943 if (tnres != DW_DLV_OK) {
01944 print_error(dbg, "dwarf_type_name_offsets", tnres, err);
01945 }
01946 ores = dwarf_offdie(dbg, die_off, &die, &err);
01947 if (ores != DW_DLV_OK)
01948 print_error(dbg, "dwarf_offdie", ores, err);
01949 cures = dwarf_die_CU_offset(die, &die_CU_off, &err);
01950 if (cures != DW_DLV_OK) {
01951 print_error(dbg, "dwarf_die_CU_offset", cures, err);
01952 }
01953 dores = dwarf_offdie(dbg, cu_off, &cu_die, &err);
01954 if (dores != DW_DLV_OK) {
01955 print_error(dbg, "dwarf_offdie2", dores, err);
01956 }
01957 printf("type %-15s die %lld, cu-die %lld,"
01958 " off-in-cu %lld, cu %lld",
01959 name, (long long) die_off, (long long) cu_off,
01960
01961 (long long) die_CU_off,
01962
01963
01964 (long long) (die_off - die_CU_off));
01965 {
01966 Dwarf_Off off = 0;
01967 int cures3 = dwarf_type_cu_offset(typebuf[i],
01968 &off, &err);
01969
01970 if (cures3 != DW_DLV_OK) {
01971 print_error(dbg, "dwarf_arange_cu_offset",
01972 cures3, err);
01973 }
01974 if ((die_off - die_CU_off) != off) {
01975 printf(" error: real cuhdr %llu", off);
01976 exit(1);
01977 }
01978 if (verbose)
01979 printf(" cuhdr %llu", off);
01980
01981 }
01982 printf("\n");
01983
01984 dwarf_dealloc(dbg, name, DW_DLA_STRING);
01985
01986 dwarf_dealloc(dbg, typebuf[i], DW_DLA_TYPENAME);
01987 }
01988 dwarf_dealloc(dbg, typebuf, DW_DLA_LIST);
01989 }
01990 }
01991
01992
01993 extern void
01994 print_weaknames(Dwarf_Debug dbg)
01995 {
01996 Dwarf_Weak *weaknamebuf;
01997 Dwarf_Signed count;
01998 Dwarf_Signed i;
01999 Dwarf_Die die;
02000 Dwarf_Off die_off;
02001 Dwarf_Off die_CU_off;
02002 Dwarf_Die cu_die;
02003 Dwarf_Off cu_off;
02004 char *name;
02005 int wkres;
02006
02007 printf("\n.debug_weaknames\n");
02008 wkres = dwarf_get_weaks(dbg, &weaknamebuf, &count, &err);
02009 if (wkres == DW_DLV_ERROR) {
02010 print_error(dbg, "dwarf_get_weaks", wkres, err);
02011 } else if (wkres == DW_DLV_NO_ENTRY) {
02012
02013 } else {
02014 for (i = 0; i < count; i++) {
02015 int tnres;
02016 int ores;
02017 int cures;
02018 int dores;
02019
02020 tnres = dwarf_weak_name_offsets(weaknamebuf[i],
02021 &name, &die_off, &cu_off,
02022 &err);
02023 if (tnres != DW_DLV_OK) {
02024 print_error(dbg, "dwarf_weak_name_offsets", tnres, err);
02025 }
02026 ores = dwarf_offdie(dbg, die_off, &die, &err);
02027 if (ores != DW_DLV_OK)
02028 print_error(dbg, "dwarf_offdie", ores, err);
02029 cures = dwarf_die_CU_offset(die, &die_CU_off, &err);
02030 if (cures != DW_DLV_OK) {
02031 print_error(dbg, "dwarf_die_CU_offset", cures, err);
02032 }
02033 dores = dwarf_offdie(dbg, cu_off, &cu_die, &err);
02034 if (dores != DW_DLV_OK) {
02035 print_error(dbg, "dwarf_offdie2", dores, err);
02036 }
02037 printf("weakname %-15s die %lld, cu-die %lld,"
02038 " off-in-cu %lld, cu %lld",
02039 name, (long long) die_off, (long long) cu_off,
02040
02041 (long long) die_CU_off,
02042
02043
02044 (long long) (die_off - die_CU_off));
02045
02046 {
02047 Dwarf_Off off = 0;
02048 int cures3 = dwarf_weak_cu_offset(weaknamebuf[i],
02049 &off, &err);
02050
02051 if (cures3 != DW_DLV_OK) {
02052 print_error(dbg, "dwarf_arange_cu_offset",
02053 cures3, err);
02054 }
02055 if ((die_off - die_CU_off) != off) {
02056 printf(" error: real cuhdr %llu", off);
02057 exit(1);
02058 }
02059 if (verbose)
02060 printf(" cuhdr %llu", off);
02061
02062 }
02063 printf("\n");
02064
02065
02066 dwarf_dealloc(dbg, name, DW_DLA_STRING);
02067
02068 dwarf_dealloc(dbg, weaknamebuf[i], DW_DLA_WEAK);
02069 }
02070 dwarf_dealloc(dbg, weaknamebuf, DW_DLA_LIST);
02071 }
02072 }
02073
02074 static void
02075 printreg(Dwarf_Signed reg)
02076 {
02077 printf("%s", regnames[reg]);
02078 }
02079
02080
02081
02082
02083
02084 static Dwarf_Unsigned
02085 local_dwarf_decode_u_leb128(unsigned char *leb128,
02086 unsigned int *leb128_length)
02087 {
02088 unsigned char byte;
02089 Dwarf_Unsigned number;
02090 unsigned int shift;
02091 unsigned int byte_length;
02092
02093 number = 0;
02094 shift = 0;
02095 byte_length = 1;
02096 byte = *leb128;
02097 for (;;) {
02098 number |= (byte & 0x7f) << shift;
02099 shift += 7;
02100
02101 if ((byte & 0x80) == 0) {
02102 if (leb128_length != NULL)
02103 *leb128_length = byte_length;
02104 return (number);
02105 }
02106
02107 byte_length++;
02108 byte = *(++leb128);
02109 }
02110 }