520 hdrdata[hdroff++] = DW_EH_PE_sdata4 | DW_EH_PE_datarel;
521
522 /*
523 * Header Offsets
524 * -----------------------------------
525 * byte version +1
526 * byte eh_frame_ptr_enc +1
527 * byte fde_count_enc +1
528 * byte table_enc +1
529 * 4 bytes eh_frame_ptr +4
530 * 4 bytes fde_count +4
531 */
532 /* LINTED */
533 binarytable = (uint_t *)(hdrdata + 12);
534 first_unwind = 0;
535 fde_count = 0;
536
537 for (APLIST_TRAVERSE(ofl->ofl_unwind, idx, osp)) {
538 uchar_t *data;
539 size_t size;
540 uint64_t off = 0;
541 uint_t cieRflag = 0, ciePflag = 0;
542 Shdr *shdr;
543
544 /*
545 * remember first UNWIND section to
546 * point to in the frame_ptr entry.
547 */
548 if (first_unwind == 0)
549 first_unwind = osp;
550
551 data = osp->os_outdata->d_buf;
552 shdr = osp->os_shdr;
553 size = shdr->sh_size;
554
555 while (off < size) {
556 uint_t length, id;
557 uint64_t ndx = 0;
558
559 /*
560 * Extract length in lsb format. A zero length
584 cieRflag = 0;
585 /*
586 * We need to drill through the CIE
587 * to find the Rflag. It's the Rflag
588 * which describes how the FDE code-pointers
589 * are encoded.
590 */
591
592 cieversion = data[off + ndx];
593 ndx += 1;
594
595 /*
596 * augstr
597 */
598 cieaugstr = (char *)(&data[off + ndx]);
599 ndx += strlen(cieaugstr) + 1;
600
601 /*
602 * calign & dalign
603 */
604 (void) uleb_extract(&data[off], &ndx);
605 (void) sleb_extract(&data[off], &ndx);
606
607 /*
608 * retreg
609 */
610 if (cieversion == 1)
611 ndx++;
612 else
613 (void) uleb_extract(&data[off], &ndx);
614 /*
615 * we walk through the augmentation
616 * section now looking for the Rflag
617 */
618 for (cieaugndx = 0; cieaugstr[cieaugndx];
619 cieaugndx++) {
620 /* BEGIN CSTYLED */
621 switch (cieaugstr[cieaugndx]) {
622 case 'z':
623 /* size */
624 (void) uleb_extract(&data[off],
625 &ndx);
626 break;
627 case 'P':
628 /* personality */
629 ciePflag = data[off + ndx];
630 ndx++;
631 /*
632 * Just need to extract the
633 * value to move on to the next
634 * field.
635 */
636 (void) dwarf_ehe_extract(
637 &data[off],
638 &ndx, ciePflag,
639 ofl->ofl_dehdr->e_ident, B_FALSE,
640 shdr->sh_addr, off + ndx, 0);
641 break;
642 case 'R':
643 /* code encoding */
644 cieRflag = data[off + ndx];
645 ndx++;
646 break;
647 case 'L':
648 /* lsda encoding */
649 ndx++;
650 break;
651 }
652 /* END CSTYLED */
653 }
654 } else {
655 uint_t bintabndx;
656 uint64_t initloc;
657 uint64_t fdeaddr;
658 uint64_t gotaddr = 0;
659
660 if (ofl->ofl_osgot != NULL)
661 gotaddr =
662 ofl->ofl_osgot->os_shdr->sh_addr;
663
664 initloc = dwarf_ehe_extract(&data[off],
665 &ndx, cieRflag, ofl->ofl_dehdr->e_ident,
666 B_FALSE,
667 shdr->sh_addr, off + ndx,
668 gotaddr);
669
670 /*
671 * Ignore FDEs with initloc set to 0.
672 * initloc will not be 0 unless this FDE was
673 * abandoned due to GNU linkonce processing.
674 * The 0 value occurs because we don't resolve
675 * sloppy relocations for unwind header target
676 * sections.
677 */
678 if (initloc != 0) {
679 bintabndx = fde_count * 2;
680 fde_count++;
681
682 /*
683 * FDEaddr is adjusted
684 * to account for the length & id which
685 * have already been consumed.
686 */
687 fdeaddr = shdr->sh_addr + off;
688
|
520 hdrdata[hdroff++] = DW_EH_PE_sdata4 | DW_EH_PE_datarel;
521
522 /*
523 * Header Offsets
524 * -----------------------------------
525 * byte version +1
526 * byte eh_frame_ptr_enc +1
527 * byte fde_count_enc +1
528 * byte table_enc +1
529 * 4 bytes eh_frame_ptr +4
530 * 4 bytes fde_count +4
531 */
532 /* LINTED */
533 binarytable = (uint_t *)(hdrdata + 12);
534 first_unwind = 0;
535 fde_count = 0;
536
537 for (APLIST_TRAVERSE(ofl->ofl_unwind, idx, osp)) {
538 uchar_t *data;
539 size_t size;
540 uint64_t off = 0, ujunk;
541 int64_t sjunk;
542 uint_t cieRflag = 0, ciePflag = 0;
543 Shdr *shdr;
544
545 /*
546 * remember first UNWIND section to
547 * point to in the frame_ptr entry.
548 */
549 if (first_unwind == 0)
550 first_unwind = osp;
551
552 data = osp->os_outdata->d_buf;
553 shdr = osp->os_shdr;
554 size = shdr->sh_size;
555
556 while (off < size) {
557 uint_t length, id;
558 uint64_t ndx = 0;
559
560 /*
561 * Extract length in lsb format. A zero length
585 cieRflag = 0;
586 /*
587 * We need to drill through the CIE
588 * to find the Rflag. It's the Rflag
589 * which describes how the FDE code-pointers
590 * are encoded.
591 */
592
593 cieversion = data[off + ndx];
594 ndx += 1;
595
596 /*
597 * augstr
598 */
599 cieaugstr = (char *)(&data[off + ndx]);
600 ndx += strlen(cieaugstr) + 1;
601
602 /*
603 * calign & dalign
604 */
605 if (uleb_extract(&data[off], &ndx,
606 size - off, &ujunk) == DW_OVERFLOW) {
607 ld_eprintf(ofl, ERR_FATAL,
608 MSG_INTL(MSG_SCN_DWFOVRFLW),
609 ofl->ofl_name,
610 osp->os_name);
611 return (S_ERROR);
612 }
613
614 if (sleb_extract(&data[off], &ndx,
615 size - off, &sjunk) == DW_OVERFLOW) {
616 ld_eprintf(ofl, ERR_FATAL,
617 MSG_INTL(MSG_SCN_DWFOVRFLW),
618 ofl->ofl_name,
619 osp->os_name);
620 return (S_ERROR);
621 }
622
623 /*
624 * retreg
625 */
626 if (cieversion == 1) {
627 ndx++;
628 } else {
629 if (uleb_extract(&data[off], &ndx,
630 size - off, &ujunk) ==
631 DW_OVERFLOW) {
632 ld_eprintf(ofl, ERR_FATAL,
633 MSG_INTL(MSG_SCN_DWFOVRFLW),
634 ofl->ofl_name,
635 osp->os_name);
636 return (S_ERROR);
637 }
638 }
639 /*
640 * we walk through the augmentation
641 * section now looking for the Rflag
642 */
643 for (cieaugndx = 0; cieaugstr[cieaugndx];
644 cieaugndx++) {
645 /* BEGIN CSTYLED */
646 switch (cieaugstr[cieaugndx]) {
647 case 'z':
648 /* size */
649 if (uleb_extract(&data[off],
650 &ndx, size - off, &ujunk) ==
651 DW_OVERFLOW) {
652 ld_eprintf(ofl, ERR_FATAL,
653 MSG_INTL(MSG_SCN_DWFOVRFLW),
654 ofl->ofl_name,
655 osp->os_name);
656 return (S_ERROR);
657 }
658 break;
659 case 'P':
660 /* personality */
661 ciePflag = data[off + ndx];
662 ndx++;
663 /*
664 * Just need to extract the
665 * value to move on to the next
666 * field.
667 */
668 switch (dwarf_ehe_extract(
669 &data[off], size - off,
670 &ndx, &ujunk, ciePflag,
671 ofl->ofl_dehdr->e_ident, B_FALSE,
672 shdr->sh_addr, off + ndx, 0)) {
673 case DW_OVERFLOW:
674 ld_eprintf(ofl, ERR_FATAL,
675 MSG_INTL(MSG_SCN_DWFOVRFLW),
676 ofl->ofl_name,
677 osp->os_name);
678 return (S_ERROR);
679 case DW_BAD_ENCODING:
680 ld_eprintf(ofl, ERR_FATAL,
681 MSG_INTL(MSG_SCN_DWFBADENC),
682 ofl->ofl_name,
683 osp->os_name, ciePflag);
684 return (S_ERROR);
685 case DW_SUCCESS:
686 break;
687 }
688 break;
689 case 'R':
690 /* code encoding */
691 cieRflag = data[off + ndx];
692 ndx++;
693 break;
694 case 'L':
695 /* lsda encoding */
696 ndx++;
697 break;
698 }
699 /* END CSTYLED */
700 }
701 } else {
702 uint_t bintabndx;
703 uint64_t initloc;
704 uint64_t fdeaddr;
705 uint64_t gotaddr = 0;
706
707 if (ofl->ofl_osgot != NULL)
708 gotaddr =
709 ofl->ofl_osgot->os_shdr->sh_addr;
710
711 switch (dwarf_ehe_extract(&data[off],
712 size - off, &ndx, &initloc, cieRflag,
713 ofl->ofl_dehdr->e_ident, B_FALSE,
714 shdr->sh_addr, off + ndx, gotaddr)) {
715 case DW_OVERFLOW:
716 ld_eprintf(ofl, ERR_FATAL,
717 MSG_INTL(MSG_SCN_DWFOVRFLW),
718 ofl->ofl_name,
719 osp->os_name);
720 return (S_ERROR);
721 case DW_BAD_ENCODING:
722 ld_eprintf(ofl, ERR_FATAL,
723 MSG_INTL(MSG_SCN_DWFBADENC),
724 ofl->ofl_name,
725 osp->os_name, cieRflag);
726 return (S_ERROR);
727 case DW_SUCCESS:
728 break;
729 }
730
731 /*
732 * Ignore FDEs with initloc set to 0.
733 * initloc will not be 0 unless this FDE was
734 * abandoned due to GNU linkonce processing.
735 * The 0 value occurs because we don't resolve
736 * sloppy relocations for unwind header target
737 * sections.
738 */
739 if (initloc != 0) {
740 bintabndx = fde_count * 2;
741 fde_count++;
742
743 /*
744 * FDEaddr is adjusted
745 * to account for the length & id which
746 * have already been consumed.
747 */
748 fdeaddr = shdr->sh_addr + off;
749
|