Print this page
5688 ELF tools need to be more careful with dwarf data


 534  */
 535 static void
 536 unwind_eh_frame(Cache *cache, Word shndx, Word shnum, Phdr *uphdr, Ehdr *ehdr,
 537     gnu_eh_state_t *eh_state, uchar_t osabi, const char *file, uint_t flags)
 538 {
 539 #if     defined(_ELF64)
 540 #define MSG_UNW_BINSRTAB2       MSG_UNW_BINSRTAB2_64
 541 #define MSG_UNW_BINSRTABENT     MSG_UNW_BINSRTABENT_64
 542 #else
 543 #define MSG_UNW_BINSRTAB2       MSG_UNW_BINSRTAB2_32
 544 #define MSG_UNW_BINSRTABENT     MSG_UNW_BINSRTABENT_32
 545 #endif
 546 
 547         Cache                   *_cache = &cache[shndx];
 548         Shdr                    *shdr = _cache->c_shdr;
 549         uchar_t                 *data = (uchar_t *)(_cache->c_data->d_buf);
 550         size_t                  datasize = _cache->c_data->d_size;
 551         Conv_dwarf_ehe_buf_t    dwarf_ehe_buf;
 552         uint64_t                ndx, frame_ptr, fde_cnt, tabndx;
 553         uint_t                  vers, frame_ptr_enc, fde_cnt_enc, table_enc;
 554         uint64_t                initloc, initloc0;
 555         uint64_t                gotaddr = 0;
 556         int                     cnt;
 557 
 558         for (cnt = 1; cnt < shnum; cnt++) {
 559                 if (strncmp(cache[cnt].c_name, MSG_ORIG(MSG_ELF_GOT),
 560                     MSG_ELF_GOT_SIZE) == 0) {
 561                         gotaddr = cache[cnt].c_shdr->sh_addr;
 562                         break;
 563                 }
 564         }
 565 






 566         /*
 567          * Is this a .eh_frame_hdr?
 568          */
 569         if ((uphdr && (shdr->sh_addr == uphdr->p_vaddr)) ||
 570             (strncmp(_cache->c_name, MSG_ORIG(MSG_SCN_FRMHDR),
 571             MSG_SCN_FRMHDR_SIZE) == 0)) {
 572                 /*
 573                  * There can only be a single .eh_frame_hdr.
 574                  * Flag duplicates.
 575                  */
 576                 if (++eh_state->hdr_cnt > 1)
 577                         (void) fprintf(stderr, MSG_INTL(MSG_ERR_MULTEHFRMHDR),
 578                             file, EC_WORD(shndx), _cache->c_name);
 579 
 580                 dbg_print(0, MSG_ORIG(MSG_UNW_FRMHDR));
 581                 ndx = 0;
 582 
 583                 vers = data[ndx++];
 584                 frame_ptr_enc = data[ndx++];
 585                 fde_cnt_enc = data[ndx++];
 586                 table_enc = data[ndx++];
 587 
 588                 dbg_print(0, MSG_ORIG(MSG_UNW_FRMVERS), vers);
 589 
 590                 frame_ptr = dwarf_ehe_extract(data, &ndx, frame_ptr_enc,
 591                     ehdr->e_ident, B_TRUE, shdr->sh_addr, ndx, gotaddr);












 592                 if (eh_state->hdr_cnt == 1) {
 593                         eh_state->hdr_ndx = shndx;
 594                         eh_state->frame_ptr = frame_ptr;
 595                 }
 596 
 597                 dbg_print(0, MSG_ORIG(MSG_UNW_FRPTRENC),
 598                     conv_dwarf_ehe(frame_ptr_enc, &dwarf_ehe_buf),
 599                     EC_XWORD(frame_ptr));
 600 
 601                 fde_cnt = dwarf_ehe_extract(data, &ndx, fde_cnt_enc,
 602                     ehdr->e_ident, B_TRUE, shdr->sh_addr, ndx, gotaddr);












 603 
 604                 dbg_print(0, MSG_ORIG(MSG_UNW_FDCNENC),
 605                     conv_dwarf_ehe(fde_cnt_enc, &dwarf_ehe_buf),
 606                     EC_XWORD(fde_cnt));
 607                 dbg_print(0, MSG_ORIG(MSG_UNW_TABENC),
 608                     conv_dwarf_ehe(table_enc, &dwarf_ehe_buf));
 609                 dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB1));
 610                 dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB2));
 611 
 612                 for (tabndx = 0; tabndx < fde_cnt; tabndx++) {
 613                         initloc = dwarf_ehe_extract(data, &ndx, table_enc,
 614                             ehdr->e_ident, B_TRUE, shdr->sh_addr, ndx, gotaddr);
 615                         /*LINTED:E_VAR_USED_BEFORE_SET*/















 616                         if ((tabndx != 0) && (initloc0 > initloc))
 617                                 (void) fprintf(stderr,
 618                                     MSG_INTL(MSG_ERR_BADSORT), file,
 619                                     _cache->c_name, EC_WORD(tabndx));

















 620                         dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTABENT),
 621                             EC_XWORD(initloc),
 622                             EC_XWORD(dwarf_ehe_extract(data, &ndx,
 623                             table_enc, ehdr->e_ident, B_TRUE, shdr->sh_addr,
 624                             ndx, gotaddr)));
 625                         initloc0 = initloc;
 626                 }
 627         } else {                /* Display the .eh_frame section */
 628                 eh_state->frame_cnt++;
 629                 if (eh_state->frame_cnt == 1) {
 630                         eh_state->frame_ndx = shndx;
 631                         eh_state->frame_base = shdr->sh_addr;
 632                 } else if ((eh_state->frame_cnt >  1) &&
 633                     (ehdr->e_type != ET_REL)) {
 634                         Conv_inv_buf_t  inv_buf;
 635 
 636                         (void) fprintf(stderr, MSG_INTL(MSG_WARN_MULTEHFRM),
 637                             file, EC_WORD(shndx), _cache->c_name,
 638                             conv_ehdr_type(osabi, ehdr->e_type, 0, &inv_buf));
 639                 }
 640                 dump_eh_frame(data, datasize, shdr->sh_addr,
 641                     ehdr->e_machine, ehdr->e_ident, gotaddr);
 642         }
 643 
 644         /*
 645          * If we've seen the .eh_frame_hdr and the first .eh_frame section,
 646          * compare the header frame_ptr to the address of the actual frame
 647          * section to ensure the link-editor got this right.  Note, this
 648          * diagnostic is only produced when unwind information is explicitly
 649          * asked for, as shared objects built with an older ld(1) may reveal
 650          * this inconsistency.  Although an inconsistency, it doesn't seem to
 651          * have any adverse effect on existing tools.
 652          */
 653         if (((flags & FLG_MASK_SHOW) != FLG_MASK_SHOW) &&
 654             (eh_state->hdr_cnt > 0) && (eh_state->frame_cnt > 0) &&
 655             (eh_state->frame_ptr != eh_state->frame_base))
 656                 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADEHFRMPTR),
 657                     file, EC_WORD(eh_state->hdr_ndx),
 658                     cache[eh_state->hdr_ndx].c_name,
 659                     EC_XWORD(eh_state->frame_ptr),
 660                     EC_WORD(eh_state->frame_ndx),
 661                     cache[eh_state->frame_ndx].c_name,


 719          * entry:
 720          *      exc_addr - Address of base of exception_range_entry struct
 721          *      cur_ent - Pointer to data in the struct to be translated
 722          *
 723          *      _f - Field of struct to be translated
 724          */
 725 #define SRELPTR(_f) \
 726         srelptr(exc_addr + offsetof(exception_range_entry, _f), cur_ent->_f)
 727 
 728 #if     defined(_ELF64)
 729 #define MSG_EXR_TITLE   MSG_EXR_TITLE_64
 730 #define MSG_EXR_ENTRY   MSG_EXR_ENTRY_64
 731 #else
 732 #define MSG_EXR_TITLE   MSG_EXR_TITLE_32
 733 #define MSG_EXR_ENTRY   MSG_EXR_ENTRY_32
 734 #endif
 735 
 736         exception_range_entry   scratch, *ent, *cur_ent = &scratch;
 737         char                    index[MAXNDXSIZE];
 738         Word                    i, nelts;
 739         Addr                    addr, addr0, offset = 0;
 740         Addr                    exc_addr = _cache->c_shdr->sh_addr;
 741 
 742         dbg_print(0, MSG_INTL(MSG_EXR_TITLE));
 743         ent = (exception_range_entry *)(_cache->c_data->d_buf);
 744         nelts = _cache->c_data->d_size / sizeof (exception_range_entry);
 745 
 746         for (i = 0; i < nelts; i++, ent++) {
 747                 if (do_swap) {
 748                         /*
 749                          * Copy byte swapped values into the scratch buffer.
 750                          * The reserved field is not used, so we skip it.
 751                          */
 752                         scratch.ret_addr = swap_ptrdiff(ent->ret_addr);
 753                         scratch.length = BSWAP_XWORD(ent->length);
 754                         scratch.handler_addr = swap_ptrdiff(ent->handler_addr);
 755                         scratch.type_block = swap_ptrdiff(ent->type_block);
 756                 } else {
 757                         cur_ent = ent;
 758                 }
 759 
 760                 /*
 761                  * The table is required to be sorted by the address
 762                  * derived from ret_addr, to allow binary searching. Ensure
 763                  * that addresses grow monotonically.
 764                  */
 765                 addr = SRELPTR(ret_addr);
 766                 /*LINTED:E_VAR_USED_BEFORE_SET*/
 767                 if ((i != 0) && (addr0 > addr))
 768                         (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSORT),
 769                             file, _cache->c_name, EC_WORD(i));
 770 
 771                 (void) snprintf(index, MAXNDXSIZE, MSG_ORIG(MSG_FMT_INDEX),
 772                     EC_XWORD(i));
 773                 dbg_print(0, MSG_INTL(MSG_EXR_ENTRY), index, EC_ADDR(offset),
 774                     EC_ADDR(addr), EC_ADDR(cur_ent->length),
 775                     EC_ADDR(SRELPTR(handler_addr)),
 776                     EC_ADDR(SRELPTR(type_block)));
 777 
 778                 addr0 = addr;
 779                 exc_addr += sizeof (exception_range_entry);
 780                 offset += sizeof (exception_range_entry);
 781         }
 782 
 783 #undef SRELPTR
 784 #undef MSG_EXR_TITLE
 785 #undef MSG_EXR_ENTRY
 786 }


3664                             pnstate.pn_namesz, c_literal_cb, NULL);
3665                         dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
3666                 }
3667 
3668                 if (pnstate.pn_descsz) {
3669                         int             hexdump = 1;
3670 
3671                         /*
3672                          * If this is a core note, let the corenote()
3673                          * function handle it.
3674                          */
3675                         if (is_corenote) {
3676                                 /* We only issue the bad arch error once */
3677                                 static int      badnote_done = 0;
3678                                 corenote_ret_t  corenote_ret;
3679 
3680                                 corenote_ret = corenote(ehdr->e_machine,
3681                                     do_swap, pnstate.pn_type, pnstate.pn_desc,
3682                                     pnstate.pn_descsz);
3683                                 switch (corenote_ret) {



3684                                 case CORENOTE_R_OK:
3685                                         hexdump = 0;
3686                                         break;
3687                                 case CORENOTE_R_BADDATA:
3688                                         (void) fprintf(stderr,
3689                                             MSG_INTL(MSG_NOTE_BADCOREDATA),
3690                                             file);
3691                                         break;
3692                                 case CORENOTE_R_BADARCH:
3693                                         if (badnote_done)
3694                                                 break;
3695                                         (void) fprintf(stderr,
3696                                             MSG_INTL(MSG_NOTE_BADCOREARCH),
3697                                             file,
3698                                             conv_ehdr_mach(ehdr->e_machine,
3699                                             0, &inv_buf));
3700                                         break;







3701                                 }
3702                         }
3703 
3704                         /*
3705                          * The default thing when we don't understand
3706                          * the note data is to display it as hex bytes.
3707                          */
3708                         if (hexdump) {
3709                                 dbg_print(0, MSG_ORIG(MSG_NOTE_DESC));
3710                                 dump_hex_bytes(pnstate.pn_desc,
3711                                     pnstate.pn_descsz, 8, 4, 4);
3712                         }
3713                 }
3714         }
3715 }
3716 
3717 /*
3718  * Search for and process .note sections.
3719  *
3720  * Returns the number of note sections seen.


4901          * operation, but none of them require the section headers, then
4902          * we are done and can return now.
4903          */
4904         if (((flags & (FLG_MASK_SHOW | FLG_MASK_CALC)) != 0) &&
4905             ((flags & (FLG_MASK_SHOW_SHDR | FLG_MASK_CALC_SHDR)) == 0))
4906                 return (ret);
4907 
4908         /*
4909          * Everything from this point on requires section headers.
4910          * If we have no section headers, there is no reason to continue.
4911          *
4912          * If we tried above to create the section header cache and failed,
4913          * it is time to exit. Otherwise, create it if needed.
4914          */
4915         switch (cache_state) {
4916         case CACHE_NEEDED:
4917                 if (create_cache(file, fd, elf, ehdr, &cache, shstrndx,
4918                     &shnum, &flags) == 0)
4919                         return (ret);
4920                 break;


4921         case CACHE_FAIL:
4922                 return (ret);
4923         }
4924         if (shnum <= 1)
4925                 goto done;
4926 
4927         /*
4928          * If -w was specified, find and write out the section(s) data.
4929          */
4930         if (wfd) {
4931                 for (ndx = 1; ndx < shnum; ndx++) {
4932                         Cache   *_cache = &cache[ndx];
4933 
4934                         if (match(MATCH_F_STRICT | MATCH_F_ALL, _cache->c_name,
4935                             ndx, _cache->c_shdr->sh_type) &&
4936                             _cache->c_data && _cache->c_data->d_buf) {
4937                                 if (write(wfd, _cache->c_data->d_buf,
4938                                     _cache->c_data->d_size) !=
4939                                     _cache->c_data->d_size) {
4940                                         int err = errno;




 534  */
 535 static void
 536 unwind_eh_frame(Cache *cache, Word shndx, Word shnum, Phdr *uphdr, Ehdr *ehdr,
 537     gnu_eh_state_t *eh_state, uchar_t osabi, const char *file, uint_t flags)
 538 {
 539 #if     defined(_ELF64)
 540 #define MSG_UNW_BINSRTAB2       MSG_UNW_BINSRTAB2_64
 541 #define MSG_UNW_BINSRTABENT     MSG_UNW_BINSRTABENT_64
 542 #else
 543 #define MSG_UNW_BINSRTAB2       MSG_UNW_BINSRTAB2_32
 544 #define MSG_UNW_BINSRTABENT     MSG_UNW_BINSRTABENT_32
 545 #endif
 546 
 547         Cache                   *_cache = &cache[shndx];
 548         Shdr                    *shdr = _cache->c_shdr;
 549         uchar_t                 *data = (uchar_t *)(_cache->c_data->d_buf);
 550         size_t                  datasize = _cache->c_data->d_size;
 551         Conv_dwarf_ehe_buf_t    dwarf_ehe_buf;
 552         uint64_t                ndx, frame_ptr, fde_cnt, tabndx;
 553         uint_t                  vers, frame_ptr_enc, fde_cnt_enc, table_enc;
 554         uint64_t                initloc, initloc0 = 0;
 555         uint64_t                gotaddr = 0;
 556         int                     cnt;
 557 
 558         for (cnt = 1; cnt < shnum; cnt++) {
 559                 if (strncmp(cache[cnt].c_name, MSG_ORIG(MSG_ELF_GOT),
 560                     MSG_ELF_GOT_SIZE) == 0) {
 561                         gotaddr = cache[cnt].c_shdr->sh_addr;
 562                         break;
 563                 }
 564         }
 565 
 566         if ((data == NULL) || (datasize == 0)) {
 567                 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
 568                     file, _cache ->c_name);
 569                 return;
 570         }
 571 
 572         /*
 573          * Is this a .eh_frame_hdr?
 574          */
 575         if ((uphdr && (shdr->sh_addr == uphdr->p_vaddr)) ||
 576             (strncmp(_cache->c_name, MSG_ORIG(MSG_SCN_FRMHDR),
 577             MSG_SCN_FRMHDR_SIZE) == 0)) {
 578                 /*
 579                  * There can only be a single .eh_frame_hdr.
 580                  * Flag duplicates.
 581                  */
 582                 if (++eh_state->hdr_cnt > 1)
 583                         (void) fprintf(stderr, MSG_INTL(MSG_ERR_MULTEHFRMHDR),
 584                             file, EC_WORD(shndx), _cache->c_name);
 585 
 586                 dbg_print(0, MSG_ORIG(MSG_UNW_FRMHDR));
 587                 ndx = 0;
 588 
 589                 vers = data[ndx++];
 590                 frame_ptr_enc = data[ndx++];
 591                 fde_cnt_enc = data[ndx++];
 592                 table_enc = data[ndx++];
 593 
 594                 dbg_print(0, MSG_ORIG(MSG_UNW_FRMVERS), vers);
 595 
 596                 switch (dwarf_ehe_extract(data, datasize, &ndx,
 597                     &frame_ptr, frame_ptr_enc, ehdr->e_ident, B_TRUE,
 598                     shdr->sh_addr, ndx, gotaddr)) {
 599                 case DW_OVERFLOW:
 600                         (void) fprintf(stderr, MSG_INTL(MSG_ERR_DWOVRFLW),
 601                             file, _cache->c_name);
 602                         return;
 603                 case DW_BAD_ENCODING:
 604                         (void) fprintf(stderr, MSG_INTL(MSG_ERR_DWBADENC),
 605                             file, _cache->c_name, frame_ptr_enc);
 606                         return;
 607                 case DW_SUCCESS:
 608                         break;
 609                 }
 610                 if (eh_state->hdr_cnt == 1) {
 611                         eh_state->hdr_ndx = shndx;
 612                         eh_state->frame_ptr = frame_ptr;
 613                 }
 614 
 615                 dbg_print(0, MSG_ORIG(MSG_UNW_FRPTRENC),
 616                     conv_dwarf_ehe(frame_ptr_enc, &dwarf_ehe_buf),
 617                     EC_XWORD(frame_ptr));
 618 
 619                 switch (dwarf_ehe_extract(data, datasize, &ndx, &fde_cnt,
 620                     fde_cnt_enc, ehdr->e_ident, B_TRUE, shdr->sh_addr, ndx,
 621                     gotaddr)) {
 622                 case DW_OVERFLOW:
 623                         (void) fprintf(stderr, MSG_INTL(MSG_ERR_DWOVRFLW),
 624                             file, _cache->c_name);
 625                         return;
 626                 case DW_BAD_ENCODING:
 627                         (void) fprintf(stderr, MSG_INTL(MSG_ERR_DWBADENC),
 628                             file, _cache->c_name, fde_cnt_enc);
 629                         return;
 630                 case DW_SUCCESS:
 631                         break;
 632                 }
 633 
 634                 dbg_print(0, MSG_ORIG(MSG_UNW_FDCNENC),
 635                     conv_dwarf_ehe(fde_cnt_enc, &dwarf_ehe_buf),
 636                     EC_XWORD(fde_cnt));
 637                 dbg_print(0, MSG_ORIG(MSG_UNW_TABENC),
 638                     conv_dwarf_ehe(table_enc, &dwarf_ehe_buf));
 639                 dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB1));
 640                 dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB2));
 641 
 642                 for (tabndx = 0; tabndx < fde_cnt; tabndx++) {
 643                         uint64_t table;
 644 
 645                         switch (dwarf_ehe_extract(data, datasize, &ndx,
 646                             &initloc, table_enc, ehdr->e_ident, B_TRUE,
 647                             shdr->sh_addr, ndx, gotaddr)) {
 648                         case DW_OVERFLOW:
 649                                 (void) fprintf(stderr,
 650                                     MSG_INTL(MSG_ERR_DWOVRFLW), file,
 651                                     _cache->c_name);
 652                                 return;
 653                         case DW_BAD_ENCODING:
 654                                 (void) fprintf(stderr,
 655                                     MSG_INTL(MSG_ERR_DWBADENC), file,
 656                                     _cache->c_name, table_enc);
 657                                 return;
 658                         case DW_SUCCESS:
 659                                 break;
 660                         }
 661                         if ((tabndx != 0) && (initloc0 > initloc))
 662                                 (void) fprintf(stderr,
 663                                     MSG_INTL(MSG_ERR_BADSORT), file,
 664                                     _cache->c_name, EC_WORD(tabndx));
 665                         switch (dwarf_ehe_extract(data, datasize, &ndx, &table,
 666                             table_enc, ehdr->e_ident, B_TRUE, shdr->sh_addr,
 667                             ndx, gotaddr)) {
 668                         case DW_OVERFLOW:
 669                                 (void) fprintf(stderr,
 670                                     MSG_INTL(MSG_ERR_DWOVRFLW), file,
 671                                     _cache->c_name);
 672                                 return;
 673                         case DW_BAD_ENCODING:
 674                                 (void) fprintf(stderr,
 675                                     MSG_INTL(MSG_ERR_DWBADENC), file,
 676                                     _cache->c_name, table_enc);
 677                                 return;
 678                         case DW_SUCCESS:
 679                                 break;
 680                         }
 681 
 682                         dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTABENT),
 683                             EC_XWORD(initloc),
 684                             EC_XWORD(table));


 685                         initloc0 = initloc;
 686                 }
 687         } else {                /* Display the .eh_frame section */
 688                 eh_state->frame_cnt++;
 689                 if (eh_state->frame_cnt == 1) {
 690                         eh_state->frame_ndx = shndx;
 691                         eh_state->frame_base = shdr->sh_addr;
 692                 } else if ((eh_state->frame_cnt >  1) &&
 693                     (ehdr->e_type != ET_REL)) {
 694                         Conv_inv_buf_t  inv_buf;
 695 
 696                         (void) fprintf(stderr, MSG_INTL(MSG_WARN_MULTEHFRM),
 697                             file, EC_WORD(shndx), _cache->c_name,
 698                             conv_ehdr_type(osabi, ehdr->e_type, 0, &inv_buf));
 699                 }
 700                 dump_eh_frame(file, _cache->c_name, data, datasize,
 701                     shdr->sh_addr, ehdr->e_machine, ehdr->e_ident, gotaddr);
 702         }
 703 
 704         /*
 705          * If we've seen the .eh_frame_hdr and the first .eh_frame section,
 706          * compare the header frame_ptr to the address of the actual frame
 707          * section to ensure the link-editor got this right.  Note, this
 708          * diagnostic is only produced when unwind information is explicitly
 709          * asked for, as shared objects built with an older ld(1) may reveal
 710          * this inconsistency.  Although an inconsistency, it doesn't seem to
 711          * have any adverse effect on existing tools.
 712          */
 713         if (((flags & FLG_MASK_SHOW) != FLG_MASK_SHOW) &&
 714             (eh_state->hdr_cnt > 0) && (eh_state->frame_cnt > 0) &&
 715             (eh_state->frame_ptr != eh_state->frame_base))
 716                 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADEHFRMPTR),
 717                     file, EC_WORD(eh_state->hdr_ndx),
 718                     cache[eh_state->hdr_ndx].c_name,
 719                     EC_XWORD(eh_state->frame_ptr),
 720                     EC_WORD(eh_state->frame_ndx),
 721                     cache[eh_state->frame_ndx].c_name,


 779          * entry:
 780          *      exc_addr - Address of base of exception_range_entry struct
 781          *      cur_ent - Pointer to data in the struct to be translated
 782          *
 783          *      _f - Field of struct to be translated
 784          */
 785 #define SRELPTR(_f) \
 786         srelptr(exc_addr + offsetof(exception_range_entry, _f), cur_ent->_f)
 787 
 788 #if     defined(_ELF64)
 789 #define MSG_EXR_TITLE   MSG_EXR_TITLE_64
 790 #define MSG_EXR_ENTRY   MSG_EXR_ENTRY_64
 791 #else
 792 #define MSG_EXR_TITLE   MSG_EXR_TITLE_32
 793 #define MSG_EXR_ENTRY   MSG_EXR_ENTRY_32
 794 #endif
 795 
 796         exception_range_entry   scratch, *ent, *cur_ent = &scratch;
 797         char                    index[MAXNDXSIZE];
 798         Word                    i, nelts;
 799         Addr                    addr, addr0 = 0, offset = 0;
 800         Addr                    exc_addr = _cache->c_shdr->sh_addr;
 801 
 802         dbg_print(0, MSG_INTL(MSG_EXR_TITLE));
 803         ent = (exception_range_entry *)(_cache->c_data->d_buf);
 804         nelts = _cache->c_data->d_size / sizeof (exception_range_entry);
 805 
 806         for (i = 0; i < nelts; i++, ent++) {
 807                 if (do_swap) {
 808                         /*
 809                          * Copy byte swapped values into the scratch buffer.
 810                          * The reserved field is not used, so we skip it.
 811                          */
 812                         scratch.ret_addr = swap_ptrdiff(ent->ret_addr);
 813                         scratch.length = BSWAP_XWORD(ent->length);
 814                         scratch.handler_addr = swap_ptrdiff(ent->handler_addr);
 815                         scratch.type_block = swap_ptrdiff(ent->type_block);
 816                 } else {
 817                         cur_ent = ent;
 818                 }
 819 
 820                 /*
 821                  * The table is required to be sorted by the address
 822                  * derived from ret_addr, to allow binary searching. Ensure
 823                  * that addresses grow monotonically.
 824                  */
 825                 addr = SRELPTR(ret_addr);

 826                 if ((i != 0) && (addr0 > addr))
 827                         (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSORT),
 828                             file, _cache->c_name, EC_WORD(i));
 829 
 830                 (void) snprintf(index, MAXNDXSIZE, MSG_ORIG(MSG_FMT_INDEX),
 831                     EC_XWORD(i));
 832                 dbg_print(0, MSG_INTL(MSG_EXR_ENTRY), index, EC_ADDR(offset),
 833                     EC_ADDR(addr), EC_ADDR(cur_ent->length),
 834                     EC_ADDR(SRELPTR(handler_addr)),
 835                     EC_ADDR(SRELPTR(type_block)));
 836 
 837                 addr0 = addr;
 838                 exc_addr += sizeof (exception_range_entry);
 839                 offset += sizeof (exception_range_entry);
 840         }
 841 
 842 #undef SRELPTR
 843 #undef MSG_EXR_TITLE
 844 #undef MSG_EXR_ENTRY
 845 }


3723                             pnstate.pn_namesz, c_literal_cb, NULL);
3724                         dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
3725                 }
3726 
3727                 if (pnstate.pn_descsz) {
3728                         int             hexdump = 1;
3729 
3730                         /*
3731                          * If this is a core note, let the corenote()
3732                          * function handle it.
3733                          */
3734                         if (is_corenote) {
3735                                 /* We only issue the bad arch error once */
3736                                 static int      badnote_done = 0;
3737                                 corenote_ret_t  corenote_ret;
3738 
3739                                 corenote_ret = corenote(ehdr->e_machine,
3740                                     do_swap, pnstate.pn_type, pnstate.pn_desc,
3741                                     pnstate.pn_descsz);
3742                                 switch (corenote_ret) {
3743                                 case CORENOTE_R_OK_DUMP:
3744                                         hexdump = 1;
3745                                         break;
3746                                 case CORENOTE_R_OK:
3747                                         hexdump = 0;
3748                                         break;
3749                                 case CORENOTE_R_BADDATA:
3750                                         (void) fprintf(stderr,
3751                                             MSG_INTL(MSG_NOTE_BADCOREDATA),
3752                                             file);
3753                                         break;
3754                                 case CORENOTE_R_BADARCH:
3755                                         if (badnote_done)
3756                                                 break;
3757                                         (void) fprintf(stderr,
3758                                             MSG_INTL(MSG_NOTE_BADCOREARCH),
3759                                             file,
3760                                             conv_ehdr_mach(ehdr->e_machine,
3761                                             0, &inv_buf));
3762                                         break;
3763                                 case CORENOTE_R_BADTYPE:
3764                                         (void) fprintf(stderr,
3765                                             MSG_INTL(MSG_NOTE_BADCORETYPE),
3766                                             file,
3767                                             EC_WORD(pnstate.pn_type));
3768                                         break;
3769 
3770                                 }
3771                         }
3772 
3773                         /*
3774                          * The default thing when we don't understand
3775                          * the note data is to display it as hex bytes.
3776                          */
3777                         if (hexdump) {
3778                                 dbg_print(0, MSG_ORIG(MSG_NOTE_DESC));
3779                                 dump_hex_bytes(pnstate.pn_desc,
3780                                     pnstate.pn_descsz, 8, 4, 4);
3781                         }
3782                 }
3783         }
3784 }
3785 
3786 /*
3787  * Search for and process .note sections.
3788  *
3789  * Returns the number of note sections seen.


4970          * operation, but none of them require the section headers, then
4971          * we are done and can return now.
4972          */
4973         if (((flags & (FLG_MASK_SHOW | FLG_MASK_CALC)) != 0) &&
4974             ((flags & (FLG_MASK_SHOW_SHDR | FLG_MASK_CALC_SHDR)) == 0))
4975                 return (ret);
4976 
4977         /*
4978          * Everything from this point on requires section headers.
4979          * If we have no section headers, there is no reason to continue.
4980          *
4981          * If we tried above to create the section header cache and failed,
4982          * it is time to exit. Otherwise, create it if needed.
4983          */
4984         switch (cache_state) {
4985         case CACHE_NEEDED:
4986                 if (create_cache(file, fd, elf, ehdr, &cache, shstrndx,
4987                     &shnum, &flags) == 0)
4988                         return (ret);
4989                 break;
4990         case CACHE_OK:
4991                 break;
4992         case CACHE_FAIL:
4993                 return (ret);
4994         }
4995         if (shnum <= 1)
4996                 goto done;
4997 
4998         /*
4999          * If -w was specified, find and write out the section(s) data.
5000          */
5001         if (wfd) {
5002                 for (ndx = 1; ndx < shnum; ndx++) {
5003                         Cache   *_cache = &cache[ndx];
5004 
5005                         if (match(MATCH_F_STRICT | MATCH_F_ALL, _cache->c_name,
5006                             ndx, _cache->c_shdr->sh_type) &&
5007                             _cache->c_data && _cache->c_data->d_buf) {
5008                                 if (write(wfd, _cache->c_data->d_buf,
5009                                     _cache->c_data->d_size) !=
5010                                     _cache->c_data->d_size) {
5011                                         int err = errno;