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 #include <stdlib.h>
00043 #include <stdio.h>
00044 #include <elf.h>
00045 #include <sys/unwind.h>
00046
00047
00048
00049
00050
00051 static __uint64_t unwind_dump_header_desc(FILE *fp, __uint64_t *rlen,
00052 char *ptr, __uint64_t size) {
00053 __uint64_t count = 0L, ret, val;
00054 unsigned char loc;
00055
00056 if (__UNW_IS_R1(*ptr)) {
00057 count = 1;
00058 fprintf(fp, "\tR1: 0x%02x (desc_size=%llu)\n",
00059 (unsigned char)*ptr,
00060 (unsigned long long)count);
00061 *rlen = (__uint64_t)((*ptr) & 0x1f);
00062 if (0x00 == (*ptr & 0x20)) {
00063 fprintf(fp, "\t\tPrologue header, size %llu\n",
00064 (unsigned long long)*rlen);
00065 } else {
00066 fprintf(fp, "\t\tBody header, size %llu\n",
00067 (unsigned long long)*rlen);
00068 }
00069 } else if (__UNW_IS_R2(*ptr)) {
00070 count = 2;
00071 fprintf(fp, "\tR2: 0x%02x 0x%02x ",
00072 (unsigned char)*ptr, (unsigned char)*(ptr+1));
00073 ret = __leb128_decode(ptr+count, size, &val);
00074 count += ret;
00075 *rlen = val;
00076 fprintf(fp, "rlen=%llu (desc_size=%llu)\n",
00077 (unsigned long long)*rlen,
00078 (unsigned long long)count);
00079 loc = (unsigned char)(*ptr & 0x07);
00080 loc <<= 1;
00081 loc |= ((*(ptr+1) & 0x80) >> 7);
00082 fprintf(fp, "\t\tPrologue header, size %llu, ",
00083 (unsigned long long)*rlen);
00084 fprintf(fp, "mask (rp, ar.pfs, psp, predicates) %01x, grsave %u\n",
00085 loc, (unsigned char)(*(ptr+1) & 0x7f));
00086 } else if (__UNW_IS_R3(*ptr)) {
00087 count = 1;
00088 fprintf(fp, "\tR3: 0x%02x ", (unsigned char)*ptr);
00089 ret = __leb128_decode(ptr+count, size, &val);
00090 count += ret;
00091 *rlen = val;
00092 fprintf(fp, "rlen=%llu (desc_size=%llu)\n",
00093 (unsigned long long)*rlen,
00094 (unsigned long long)count);
00095 if (0x00 == (*ptr & 0x03)) {
00096 fprintf(fp, "\t\tPrologue header, size %llu\n",
00097 (unsigned long long)*rlen);
00098 } else {
00099 fprintf(fp, "\t\tBody header, size %llu\n",
00100 (unsigned long long)*rlen);
00101 }
00102 } else {
00103 fprintf(fp, "\tInvalid header descriptor\n");
00104 }
00105 return count;
00106 }
00107
00108
00109
00110
00111
00112 static __uint64_t unwind_dump_prologue_desc(FILE *fp, __uint64_t rlen,
00113 char *ptr, __uint64_t size) {
00114 __uint64_t count = 0L, ret, val, i;
00115 unsigned char loc;
00116
00117 if (__UNW_IS_P1(*ptr)) {
00118 count = 1;
00119 fprintf(fp, "\tP1: 0x%02x (desc_size=%llu)\n",
00120 (unsigned char)*ptr,
00121 (unsigned long long)count);
00122 fprintf(fp, "\t\tType br_mem, brmask 0x%02x\n",
00123 (unsigned char)(*ptr & 0x1f));
00124 } else if (__UNW_IS_P2(*ptr)) {
00125 count = 2;
00126 fprintf(fp, "\tP2: 0x%02x 0x%02x (desc_size=%llu)\n",
00127 (unsigned char)*ptr, (unsigned char)*(ptr+1),
00128 (unsigned long long)count);
00129 loc = (unsigned char)(*ptr & 0x0f);
00130 loc <<= 1;
00131 loc |= ((*(ptr+1) & 0x80) >> 7);
00132 fprintf(fp, "\t\tType br_gr, brmask 0x%02x, gr %u\n",
00133 loc, (unsigned char)(*(ptr+1) & 0x7f));
00134 } else if (__UNW_IS_P3(*ptr)) {
00135 char *type = "unknown";
00136 char *reg = "gr/br";
00137
00138 count = 2;
00139 fprintf(fp, "\tP3: 0x%02x 0x%02x (desc_size=%llu)\n",
00140 (unsigned char)*ptr, (unsigned char)*(ptr+1),
00141 (unsigned long long)count);
00142 loc = (unsigned char)(*ptr & 0x07);
00143 loc <<= 1;
00144 loc |= ((*(ptr+1) & 0x80) >> 7);
00145 switch (loc) {
00146 case 0:
00147 type = "psp_gr";
00148 reg = "gr";
00149 break;
00150 case 1:
00151 type = "rp_gr";
00152 reg = "gr";
00153 break;
00154 case 2:
00155 type = "pfs_gr";
00156 reg = "gr";
00157 break;
00158 case 3:
00159 type = "pred_gr";
00160 reg = "gr";
00161 break;
00162 case 4:
00163 type = "unat_gr";
00164 reg = "gr";
00165 break;
00166 case 5:
00167 type = "lc_gr";
00168 reg = "gr";
00169 break;
00170 case 6:
00171 type = "rp_br";
00172 reg = "br";
00173 break;
00174 case 7:
00175 type = "rnat_gr";
00176 reg = "gr";
00177 break;
00178 case 8:
00179 type = "bsp_gr";
00180 reg = "gr";
00181 break;
00182 case 9:
00183 type = "bspstore_gr";
00184 reg = "gr";
00185 break;
00186 case 10:
00187 type = "fpsr_gr";
00188 reg = "gr";
00189 break;
00190 case 11:
00191 type = "priunat_gr";
00192 reg = "gr";
00193 break;
00194 default:
00195 break;
00196 }
00197 fprintf(fp, "\t\tType %s, %s %u\n", type, reg,
00198 (unsigned char)(*(ptr+1) & 0x7f));
00199 } else if (__UNW_IS_P4(*ptr)) {
00200 __uint64_t desc_size = ((rlen * 2) + 7 ) / 8,
00201 byte_no = 0L, shift_no = 0L;
00202
00203 count = 1;
00204 fprintf(fp, "\tP4: 0x%02x (desc_size=%llu)\n",
00205 (unsigned char)*ptr,
00206 (unsigned long long)(count + desc_size));
00207 if (1 + desc_size > size) {
00208 fprintf(fp, "\n\t\tInvalid size for descriptor P4 (spill_mask)\n");
00209 count += desc_size;
00210 } else {
00211 fprintf(fp, "\t\tType spill_mask, imask size in doublebits = %llu\n",
00212 (unsigned long long)rlen);
00213 fprintf(fp, "\t\tDumping imask: ");
00214 for (i = 0; i < (rlen * 2); i += 2) {
00215 byte_no = (i / 8) + 1;
00216 shift_no = i % 8;
00217
00218 loc = (unsigned char)(*(ptr + byte_no));
00219 loc <<= shift_no;
00220 loc >>= 6;
00221 fprintf(fp, "%01x", loc);
00222 }
00223 fprintf(fp, "\n");
00224 count += desc_size;
00225 }
00226 } else if (__UNW_IS_P5(*ptr)) {
00227 __uint32_t frmask = 0;
00228
00229 count = 4;
00230 fprintf(fp, "\tP5: 0x%02x 0x%02x 0x%02x 0x%02x (desc_size=%llu)\n",
00231 (unsigned char)*ptr, (unsigned char)*(ptr+1),
00232 (unsigned char)*(ptr+2), (unsigned char)*(ptr+3),
00233 (unsigned long long)count);
00234 frmask = (__uint32_t)((*(ptr+1) & 0x0f));
00235 frmask <<= 4;
00236 frmask |= *(ptr+2);
00237 frmask <<= 8;
00238 frmask |= *(ptr+3);
00239 fprintf(fp, "\t\tType frgr_mem, grmask 0x%01x, frmask %05x\n",
00240 (unsigned char)((*(ptr+1) & 0xf0) >> 4), frmask);
00241 } else if (__UNW_IS_P6(*ptr)) {
00242 count = 1;
00243 fprintf(fp, "\tP6: 0x%02x (desc_size=%llu)\n",
00244 (unsigned char)*ptr,
00245 (unsigned long long)count);
00246 if (0x00 == (*ptr & 0x10)) {
00247 fprintf(fp, "\tType fr_mem, frmask %01x\n",
00248 (unsigned char)(*ptr & 0x0f));
00249 } else {
00250 fprintf(fp, "\tType gr_mem, grmask %01x\n",
00251 (unsigned char)(*ptr & 0x0f));
00252 }
00253 } else if (__UNW_IS_P7(*ptr)) {
00254 char *type = "unknown";
00255
00256 count = 1;
00257 fprintf(fp, "\tP7: 0x%02x ", (unsigned char)*ptr);
00258 ret = __leb128_decode(ptr+count, size, &val);
00259 count += ret;
00260 fprintf(fp, "t/spoff/pspoff=%llu ",
00261 (unsigned long long)val);
00262 if (0x00 == (*ptr & 0x0f)) {
00263
00264 ret = __leb128_decode(ptr+count, size, &val);
00265 count += ret;
00266 fprintf(fp, "size=%llu*16 (desc_size=%llu)\n",
00267 (unsigned long long)val,
00268 (unsigned long long)count);
00269 } else {
00270 fprintf(fp, "(desc_size=%llu)\n", (unsigned long long)count);
00271 }
00272 switch (*ptr & 0x0f) {
00273 case 0:
00274 type = "mem_stack_f";
00275 break;
00276 case 1:
00277 type = "mem_stack_v";
00278 break;
00279 case 2:
00280 type = "spill_base";
00281 break;
00282 case 3:
00283 type = "psp_sprel";
00284 break;
00285 case 4:
00286 type = "rp_when";
00287 break;
00288 case 5:
00289 type = "rp_psprel";
00290 break;
00291 case 6:
00292 type = "pfs_when";
00293 break;
00294 case 7:
00295 type = "pfs_psprel";
00296 break;
00297 case 8:
00298 type = "preds_when";
00299 break;
00300 case 9:
00301 type = "preds_psprel";
00302 break;
00303 case 10:
00304 type = "lc_when";
00305 break;
00306 case 11:
00307 type = "lc_psprel";
00308 break;
00309 case 12:
00310 type = "unat_when";
00311 break;
00312 case 13:
00313 type = "unat_psprel";
00314 break;
00315 case 14:
00316 type = "fpsr_when";
00317 break;
00318 case 15:
00319 type = "fpsr_psprel";
00320 break;
00321 default:
00322 break;
00323 }
00324 fprintf(fp, "\t\tType %s\n", type);
00325 } else if (__UNW_IS_P8(*ptr)) {
00326 char *type = "unknown";
00327
00328 count = 2;
00329 fprintf(fp, "\tP8: 0x%02x 0x%02x ",
00330 (unsigned char)*ptr, (unsigned char)*(ptr+1));
00331 ret = __leb128_decode(ptr+count, size, &val);
00332 count += ret;
00333 fprintf(fp, "t/spoff/pspoff=%llu (desc_size=%llu)\n",
00334 (unsigned long long)val,
00335 (unsigned long long)count);
00336 switch (*(ptr+1)) {
00337 case 0:
00338 type = "unused";
00339 break;
00340 case 1:
00341 type = "rp_sprel";
00342 break;
00343 case 2:
00344 type = "pfs_sprel";
00345 break;
00346 case 3:
00347 type = "preds_sprel";
00348 break;
00349 case 4:
00350 type = "lc_sprel";
00351 break;
00352 case 5:
00353 type = "unat_sprel";
00354 break;
00355 case 6:
00356 type = "fpsr_sprel";
00357 break;
00358 case 7:
00359 type = "bsp_when";
00360 break;
00361 case 8:
00362 type = "bsp_psprel";
00363 break;
00364 case 9:
00365 type = "bsp_sprel";
00366 break;
00367 case 10:
00368 type = "bspstore_when";
00369 break;
00370 case 11:
00371 type = "bspstore_psprel";
00372 break;
00373 case 12:
00374 type = "bspstore_sprel";
00375 break;
00376 case 13:
00377 type = "rnat_when";
00378 break;
00379 case 14:
00380 type = "rnat_psprel";
00381 break;
00382 case 15:
00383 type = "rnat_sprel";
00384 break;
00385 case 16:
00386 type = "priunat_when";
00387 break;
00388 case 17:
00389 type = "priunat_psprel";
00390 break;
00391 case 18:
00392 type = "priunat_sprel";
00393 break;
00394 default:
00395 break;
00396 }
00397 fprintf(fp, "\t\tType %s\n", type);
00398 } else if (__UNW_IS_P9(*ptr)) {
00399 count = 3;
00400 fprintf(fp, "\tP9: 0x%02x 0x%02x 0x%02x (desc_size=%llu)\n",
00401 (unsigned char)*ptr,
00402 (unsigned char)*(ptr+1),
00403 (unsigned char)*(ptr+2),
00404 (unsigned long long)count);
00405 fprintf(fp, "\t\tType gr_gr, grmask 0x%01x, gr %u\n",
00406 (unsigned char)(*(ptr+1) & 0x0f),
00407 (unsigned char)(*(ptr+2) & 0x7f));
00408 } else if (__UNW_IS_P10(*ptr)) {
00409 count = 3;
00410 fprintf(fp, "\tP10: 0x%02x 0x%02x 0x%02x (desc_size=%llu)\n",
00411 (unsigned char)*ptr,
00412 (unsigned char)*(ptr+1),
00413 (unsigned char)*(ptr+2),
00414 (unsigned long long)count);
00415 fprintf(fp, "\t\tType ABI-specific, abi %u, context 0x%02x\n",
00416 (unsigned char)*(ptr+1),
00417 (unsigned char)*(ptr+2));
00418 } else if (__UNW_IS_X1(*ptr)) {
00419 count = 2;
00420 fprintf(fp, "\tX1: 0x%02x", (unsigned char)*ptr);
00421 ret = __leb128_decode(ptr+count, size, &val);
00422 count += ret;
00423 fprintf(fp, "time=%llu\n", (unsigned long long) val);
00424 fprintf(fp, "\t\treg = 0x%0x, ",
00425 (unsigned char)*(ptr+1));
00426 ret = __leb128_decode(ptr+count, size, &val);
00427 count += ret;
00428 fprintf(fp, "offset = %lld\n", (long long)val);
00429 } else if (__UNW_IS_X2(*ptr)) {
00430 count = 3;
00431 fprintf(fp, "\tX1: 0x%02x", (unsigned char)*ptr);
00432 ret = __leb128_decode(ptr+count, size, &val);
00433 count += ret;
00434 fprintf(fp, "time=%llu\n",
00435 (unsigned long long) val);
00436 fprintf(fp, "\t\treg = 0x%0x, ",
00437 (unsigned char)*(ptr+1));
00438 fprintf(fp, "treg = 0x%0x\n",
00439 (unsigned char)*(ptr+2));
00440 } else {
00441 fprintf(fp, "\tInvalid prologue descriptor\n");
00442 }
00443 return count;
00444 }
00445
00446
00447
00448
00449
00450 static __uint64_t unwind_dump_body_desc(FILE *fp, __uint64_t rlen,
00451 char *ptr, __uint64_t size) {
00452 __uint64_t count = 0L, ret, val, val1, val2;
00453
00454 if (__UNW_IS_B1(*ptr)) {
00455 count = 1;
00456 fprintf(fp, "\tB1: 0x%02x (desc_size=%llu)\n",
00457 (unsigned char)*ptr,
00458 (unsigned long long)count);
00459 if (0x00 == (*ptr & 0x20)) {
00460 fprintf(fp, "\t\tBody label state %u\n",
00461 (unsigned char)(*ptr & 0x1f));
00462 } else {
00463 fprintf(fp, "\t\tBody copy state %u\n",
00464 (unsigned char)(*ptr & 0x1f));
00465 }
00466 } else if (__UNW_IS_B2(*ptr)) {
00467 count = 1;
00468 fprintf(fp, "\tB2: 0x%02x ", (unsigned char)*ptr);
00469 ret = __leb128_decode(ptr+count, size, &val);
00470 count += ret;
00471 fprintf(fp, "t=%llu (desc_size=%llu)\n",
00472 (unsigned long long)val,
00473 (unsigned long long)count);
00474 fprintf(fp, "\t\tEpilogue, %u nested prologues, ",
00475 (unsigned char)(*ptr & 0x1f));
00476 fprintf(fp, "time -%llu (body size %llu)\n",
00477 (unsigned long long)val,
00478 (unsigned long long)rlen);
00479 } else if (__UNW_IS_B3(*ptr)) {
00480 count = 1;
00481 fprintf(fp, "\tB3: 0x%02x ", (unsigned char)*ptr);
00482 ret = __leb128_decode(ptr+count, size, &val);
00483 count += ret;
00484 fprintf(fp, "t=%llu ", (unsigned long long)val);
00485 val1 = val;
00486 ret = __leb128_decode(ptr+count, size, &val);
00487 count += ret;
00488 fprintf(fp, "ecount=%llu ", (unsigned long long)val);
00489 val2 = val;
00490 fprintf(fp, "(desc_size=%llu)\n", (unsigned long long)count);
00491 fprintf(fp, "\t\tEpilogue, %llu nested prologues, ",
00492 (unsigned long long)val2);
00493 fprintf(fp, "time -%llu (body size %llu)\n",
00494 (unsigned long long)val1,
00495 (unsigned long long)rlen);
00496 } else if (__UNW_IS_B4(*ptr)) {
00497 count = 1;
00498 fprintf(fp, "\tB4: 0x%02x ", (unsigned char)*ptr);
00499 ret = __leb128_decode(ptr+count, size, &val);
00500 count += ret;
00501 fprintf(fp, "label=%llu (desc_size=%llu)\n",
00502 (unsigned long long)val,
00503 (unsigned long long)count);
00504 if (0x00 == (*ptr & 0x08)) {
00505 fprintf(fp, "\t\tBody label state %llu\n",
00506 (unsigned long long)val);
00507 } else {
00508 fprintf(fp, "\t\tBody copy state %llu\n",
00509 (unsigned long long)val);
00510 }
00511 } else if (__UNW_IS_X1(*ptr)) {
00512 count = 2;
00513 fprintf(fp, "\tX1: 0x%02x ", (unsigned char)*ptr);
00514 ret = __leb128_decode(ptr+count, size, &val);
00515 count += ret;
00516 fprintf(fp, "time=%llu\n", (unsigned long long) val);
00517 fprintf(fp, "\t\treg = 0x%0x, ",
00518 (unsigned char)*(ptr+1));
00519 ret = __leb128_decode(ptr+count, size, &val);
00520 count += ret;
00521 fprintf(fp, "offset = %lld\n", (long long)val);
00522 } else if (__UNW_IS_X2(*ptr)) {
00523 count = 3;
00524 fprintf(fp, "\tX2: 0x%02x ", (unsigned char)*ptr);
00525 ret = __leb128_decode(ptr+count, size, &val);
00526 count += ret;
00527 fprintf(fp, "time=%llu\n",
00528 (unsigned long long) val);
00529 fprintf(fp, "\t\treg = 0x%0x, ",
00530 (unsigned char)*(ptr+1));
00531 fprintf(fp, "treg = 0x%0x\n",
00532 (unsigned char)*(ptr+2));
00533 } else {
00534 fprintf(fp, "\tInvalid body descriptor\n");
00535 }
00536 return count;
00537 }
00538
00539
00540
00541
00542
00543 __unw_error_t unwind_dump2ascii(char *unwind_table_ptr,
00544 __uint64_t unwind_table_size,
00545 char *unwind_info_ptr,
00546 __uint64_t unwind_info_size,
00547 void *arg) {
00548 FILE *fp = (NULL != arg) ? (FILE *)arg : stdout;
00549 __uint64_t i, size = 0L, count = 0L, retnum = 0L, unwind_info_offset = 0L,
00550 rlen = 0L, unwind_table_size_in_entries =
00551 unwind_table_size / sizeof(__unw_table_entry_t);
00552 __unw_table_entry_t *unwind_table =
00553 (__unw_table_entry_t *)unwind_table_ptr;
00554 __unw_info_t *info = NULL;
00555 char *ptr = NULL;
00556 enum { __UNW_UNDEF, __UNW_PROLOGUE, __UNW_BODY } desc_id = __UNW_UNDEF;
00557 __unw_error_t ret = __UNW_OK;
00558
00559
00560 if (NULL != unwind_table_ptr) {
00561 fprintf(fp, "\n\t\t*** UNWIND TABLE ***\n");
00562 for (i = 0; i < unwind_table_size_in_entries; i++) {
00563 fprintf(fp, "Unwind table entry: %03llu ",
00564 (unsigned long long)i);
00565 fprintf(fp, "Addresses: 0x%08llx - 0x%08llx ",
00566 (unsigned long long)unwind_table[i]._start,
00567 (unsigned long long)unwind_table[i]._end);
00568 fprintf(fp, "Unwind info: 0x%08llx\n",
00569 (unsigned long long)unwind_table[i]._info);
00570 }
00571 fprintf(fp, "\n");
00572 }
00573
00574
00575 if (NULL != unwind_info_ptr) {
00576 fprintf(fp, "\n\t\t*** UNWIND INFO ***\n");
00577 while (unwind_info_offset < unwind_info_size) {
00578 info = (__unw_info_t *)((char *)unwind_info_ptr +
00579 unwind_info_offset);
00580 size = (__uint64_t)(__UNW_LENGTH((info->_header) *
00581 sizeof(__unw_dbl_word_t)));
00582
00583
00584 fprintf(fp, "Unwind info @ %p ", info);
00585 fprintf(fp, "(Offset: 0x%llx)\n",
00586 (unsigned long long)unwind_info_offset);
00587 fprintf(fp, "\tVersion: %llu ",
00588 (unsigned long long)__UNW_VER(info->_header));
00589 fprintf(fp, "Flags EHANDLER/UHANDLER: %llu/%llu ",
00590 (unsigned long long)__UNW_FLAG_EHANDLER(info->_header),
00591 (unsigned long long)__UNW_FLAG_UHANDLER(info->_header));
00592 fprintf(fp, "Size: 1+%llu\n", (unsigned long long)(size /
00593 sizeof(__unw_dbl_word_t)));
00594
00595
00596 if (__UNW_FLAG_EHANDLER(info->_header) ||
00597 __UNW_FLAG_UHANDLER(info->_header)) {
00598 fprintf(fp, "Personality routine: %llx\n",
00599 (unsigned long long)(*(__unw_addr_t *)
00600 ((char *)unwind_info_ptr + unwind_info_offset +
00601 sizeof(__unw_dbl_word_t) + size)));
00602 }
00603
00604
00605 if (unwind_info_offset + sizeof(__unw_dbl_word_t) + size >
00606 unwind_info_size) {
00607 fprintf(fp, "\tInvalid size\n");
00608 ret = __UNW_INV_SIZE_ERROR;
00609 break;
00610 }
00611
00612
00613 if (__UNW_VER(info->_header) != 1) {
00614 fprintf(fp, "\tInvalid version\n");
00615 ret = __UNW_INV_VERSION_ERROR;
00616 break;
00617 }
00618
00619
00620 ptr = (char *)info->_body;
00621 count = 0L;
00622 while (count < size) {
00623 if (__UNW_IS_HEADER(*ptr)) {
00624 if (__UNW_IS_PROLOGUE_HEADER(*ptr)) {
00625 desc_id = __UNW_PROLOGUE;
00626 retnum = unwind_dump_header_desc(fp,
00627 &rlen, ptr, size-count);
00628 } else if (__UNW_IS_BODY_HEADER(*ptr)) {
00629 desc_id = __UNW_BODY;
00630 retnum = unwind_dump_header_desc(fp,
00631 &rlen, ptr, size-count);
00632 } else {
00633 fprintf(fp, "\tInvalid header (0x%x)\n",
00634 (unsigned char)*ptr);
00635 break;
00636 }
00637 } else {
00638 if (__UNW_PROLOGUE == desc_id) {
00639 retnum = unwind_dump_prologue_desc(fp,
00640 rlen, ptr, size-count);
00641 } else if (__UNW_BODY == desc_id) {
00642 retnum = unwind_dump_body_desc(fp,
00643 rlen, ptr, size-count);
00644 } else {
00645 fprintf(fp, "\tInvalid prologue/body\n");
00646 break;
00647 }
00648 }
00649 if (0 == retnum) {
00650 break;
00651 }
00652 count += retnum;
00653 ptr += retnum;
00654 }
00655
00656
00657 unwind_info_offset += (sizeof(__unw_dbl_word_t) + size);
00658 if (__UNW_FLAG_EHANDLER(info->_header) ||
00659 __UNW_FLAG_UHANDLER(info->_header)) {
00660 __uint64_t real_size = (sizeof(__unw_addr_t) +
00661 sizeof(__unw_dbl_word_t) - 1) /
00662 sizeof(__unw_dbl_word_t);
00663 real_size *= sizeof(__unw_dbl_word_t);
00664 unwind_info_offset += real_size;
00665 }
00666 }
00667 fprintf(fp, "\n");
00668 }
00669
00670 return ret;
00671 }