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


 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