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;
|