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

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/sgs/elfdump/common/elfdump.c
          +++ new/usr/src/cmd/sgs/elfdump/common/elfdump.c
↓ open down ↓ 543 lines elided ↑ open up ↑
 544  544  #define MSG_UNW_BINSRTABENT     MSG_UNW_BINSRTABENT_32
 545  545  #endif
 546  546  
 547  547          Cache                   *_cache = &cache[shndx];
 548  548          Shdr                    *shdr = _cache->c_shdr;
 549  549          uchar_t                 *data = (uchar_t *)(_cache->c_data->d_buf);
 550  550          size_t                  datasize = _cache->c_data->d_size;
 551  551          Conv_dwarf_ehe_buf_t    dwarf_ehe_buf;
 552  552          uint64_t                ndx, frame_ptr, fde_cnt, tabndx;
 553  553          uint_t                  vers, frame_ptr_enc, fde_cnt_enc, table_enc;
 554      -        uint64_t                initloc, initloc0;
      554 +        uint64_t                initloc, initloc0 = 0;
 555  555          uint64_t                gotaddr = 0;
 556  556          int                     cnt;
 557  557  
 558  558          for (cnt = 1; cnt < shnum; cnt++) {
 559  559                  if (strncmp(cache[cnt].c_name, MSG_ORIG(MSG_ELF_GOT),
 560  560                      MSG_ELF_GOT_SIZE) == 0) {
 561  561                          gotaddr = cache[cnt].c_shdr->sh_addr;
 562  562                          break;
 563  563                  }
 564  564          }
 565  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 +
 566  572          /*
 567  573           * Is this a .eh_frame_hdr?
 568  574           */
 569  575          if ((uphdr && (shdr->sh_addr == uphdr->p_vaddr)) ||
 570  576              (strncmp(_cache->c_name, MSG_ORIG(MSG_SCN_FRMHDR),
 571  577              MSG_SCN_FRMHDR_SIZE) == 0)) {
 572  578                  /*
 573  579                   * There can only be a single .eh_frame_hdr.
 574  580                   * Flag duplicates.
 575  581                   */
↓ open down ↓ 4 lines elided ↑ open up ↑
 580  586                  dbg_print(0, MSG_ORIG(MSG_UNW_FRMHDR));
 581  587                  ndx = 0;
 582  588  
 583  589                  vers = data[ndx++];
 584  590                  frame_ptr_enc = data[ndx++];
 585  591                  fde_cnt_enc = data[ndx++];
 586  592                  table_enc = data[ndx++];
 587  593  
 588  594                  dbg_print(0, MSG_ORIG(MSG_UNW_FRMVERS), vers);
 589  595  
 590      -                frame_ptr = dwarf_ehe_extract(data, &ndx, frame_ptr_enc,
 591      -                    ehdr->e_ident, B_TRUE, shdr->sh_addr, ndx, gotaddr);
      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 +                }
 592  610                  if (eh_state->hdr_cnt == 1) {
 593  611                          eh_state->hdr_ndx = shndx;
 594  612                          eh_state->frame_ptr = frame_ptr;
 595  613                  }
 596  614  
 597  615                  dbg_print(0, MSG_ORIG(MSG_UNW_FRPTRENC),
 598  616                      conv_dwarf_ehe(frame_ptr_enc, &dwarf_ehe_buf),
 599  617                      EC_XWORD(frame_ptr));
 600  618  
 601      -                fde_cnt = dwarf_ehe_extract(data, &ndx, fde_cnt_enc,
 602      -                    ehdr->e_ident, B_TRUE, shdr->sh_addr, ndx, gotaddr);
      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 +                }
 603  633  
 604  634                  dbg_print(0, MSG_ORIG(MSG_UNW_FDCNENC),
 605  635                      conv_dwarf_ehe(fde_cnt_enc, &dwarf_ehe_buf),
 606  636                      EC_XWORD(fde_cnt));
 607  637                  dbg_print(0, MSG_ORIG(MSG_UNW_TABENC),
 608  638                      conv_dwarf_ehe(table_enc, &dwarf_ehe_buf));
 609  639                  dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB1));
 610  640                  dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB2));
 611  641  
 612  642                  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*/
      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 +                        }
 616  661                          if ((tabndx != 0) && (initloc0 > initloc))
 617  662                                  (void) fprintf(stderr,
 618  663                                      MSG_INTL(MSG_ERR_BADSORT), file,
 619  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 +
 620  682                          dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTABENT),
 621  683                              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)));
      684 +                            EC_XWORD(table));
 625  685                          initloc0 = initloc;
 626  686                  }
 627  687          } else {                /* Display the .eh_frame section */
 628  688                  eh_state->frame_cnt++;
 629  689                  if (eh_state->frame_cnt == 1) {
 630  690                          eh_state->frame_ndx = shndx;
 631  691                          eh_state->frame_base = shdr->sh_addr;
 632  692                  } else if ((eh_state->frame_cnt >  1) &&
 633  693                      (ehdr->e_type != ET_REL)) {
 634  694                          Conv_inv_buf_t  inv_buf;
 635  695  
 636  696                          (void) fprintf(stderr, MSG_INTL(MSG_WARN_MULTEHFRM),
 637  697                              file, EC_WORD(shndx), _cache->c_name,
 638  698                              conv_ehdr_type(osabi, ehdr->e_type, 0, &inv_buf));
 639  699                  }
 640      -                dump_eh_frame(data, datasize, shdr->sh_addr,
 641      -                    ehdr->e_machine, ehdr->e_ident, gotaddr);
      700 +                dump_eh_frame(file, _cache->c_name, data, datasize,
      701 +                    shdr->sh_addr, ehdr->e_machine, ehdr->e_ident, gotaddr);
 642  702          }
 643  703  
 644  704          /*
 645  705           * If we've seen the .eh_frame_hdr and the first .eh_frame section,
 646  706           * compare the header frame_ptr to the address of the actual frame
 647  707           * section to ensure the link-editor got this right.  Note, this
 648  708           * diagnostic is only produced when unwind information is explicitly
 649  709           * asked for, as shared objects built with an older ld(1) may reveal
 650  710           * this inconsistency.  Although an inconsistency, it doesn't seem to
 651  711           * have any adverse effect on existing tools.
↓ open down ↓ 77 lines elided ↑ open up ↑
 729  789  #define MSG_EXR_TITLE   MSG_EXR_TITLE_64
 730  790  #define MSG_EXR_ENTRY   MSG_EXR_ENTRY_64
 731  791  #else
 732  792  #define MSG_EXR_TITLE   MSG_EXR_TITLE_32
 733  793  #define MSG_EXR_ENTRY   MSG_EXR_ENTRY_32
 734  794  #endif
 735  795  
 736  796          exception_range_entry   scratch, *ent, *cur_ent = &scratch;
 737  797          char                    index[MAXNDXSIZE];
 738  798          Word                    i, nelts;
 739      -        Addr                    addr, addr0, offset = 0;
      799 +        Addr                    addr, addr0 = 0, offset = 0;
 740  800          Addr                    exc_addr = _cache->c_shdr->sh_addr;
 741  801  
 742  802          dbg_print(0, MSG_INTL(MSG_EXR_TITLE));
 743  803          ent = (exception_range_entry *)(_cache->c_data->d_buf);
 744  804          nelts = _cache->c_data->d_size / sizeof (exception_range_entry);
 745  805  
 746  806          for (i = 0; i < nelts; i++, ent++) {
 747  807                  if (do_swap) {
 748  808                          /*
 749  809                           * Copy byte swapped values into the scratch buffer.
↓ open down ↓ 6 lines elided ↑ open up ↑
 756  816                  } else {
 757  817                          cur_ent = ent;
 758  818                  }
 759  819  
 760  820                  /*
 761  821                   * The table is required to be sorted by the address
 762  822                   * derived from ret_addr, to allow binary searching. Ensure
 763  823                   * that addresses grow monotonically.
 764  824                   */
 765  825                  addr = SRELPTR(ret_addr);
 766      -                /*LINTED:E_VAR_USED_BEFORE_SET*/
 767  826                  if ((i != 0) && (addr0 > addr))
 768  827                          (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSORT),
 769  828                              file, _cache->c_name, EC_WORD(i));
 770  829  
 771  830                  (void) snprintf(index, MAXNDXSIZE, MSG_ORIG(MSG_FMT_INDEX),
 772  831                      EC_XWORD(i));
 773  832                  dbg_print(0, MSG_INTL(MSG_EXR_ENTRY), index, EC_ADDR(offset),
 774  833                      EC_ADDR(addr), EC_ADDR(cur_ent->length),
 775  834                      EC_ADDR(SRELPTR(handler_addr)),
 776  835                      EC_ADDR(SRELPTR(type_block)));
↓ open down ↓ 2897 lines elided ↑ open up ↑
3674 3733                           */
3675 3734                          if (is_corenote) {
3676 3735                                  /* We only issue the bad arch error once */
3677 3736                                  static int      badnote_done = 0;
3678 3737                                  corenote_ret_t  corenote_ret;
3679 3738  
3680 3739                                  corenote_ret = corenote(ehdr->e_machine,
3681 3740                                      do_swap, pnstate.pn_type, pnstate.pn_desc,
3682 3741                                      pnstate.pn_descsz);
3683 3742                                  switch (corenote_ret) {
     3743 +                                case CORENOTE_R_OK_DUMP:
     3744 +                                        hexdump = 1;
     3745 +                                        break;
3684 3746                                  case CORENOTE_R_OK:
3685 3747                                          hexdump = 0;
3686 3748                                          break;
3687 3749                                  case CORENOTE_R_BADDATA:
3688 3750                                          (void) fprintf(stderr,
3689 3751                                              MSG_INTL(MSG_NOTE_BADCOREDATA),
3690 3752                                              file);
3691 3753                                          break;
3692 3754                                  case CORENOTE_R_BADARCH:
3693 3755                                          if (badnote_done)
3694 3756                                                  break;
3695 3757                                          (void) fprintf(stderr,
3696 3758                                              MSG_INTL(MSG_NOTE_BADCOREARCH),
3697 3759                                              file,
3698 3760                                              conv_ehdr_mach(ehdr->e_machine,
3699 3761                                              0, &inv_buf));
3700 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 +
3701 3770                                  }
3702 3771                          }
3703 3772  
3704 3773                          /*
3705 3774                           * The default thing when we don't understand
3706 3775                           * the note data is to display it as hex bytes.
3707 3776                           */
3708 3777                          if (hexdump) {
3709 3778                                  dbg_print(0, MSG_ORIG(MSG_NOTE_DESC));
3710 3779                                  dump_hex_bytes(pnstate.pn_desc,
↓ open down ↓ 1200 lines elided ↑ open up ↑
4911 4980           *
4912 4981           * If we tried above to create the section header cache and failed,
4913 4982           * it is time to exit. Otherwise, create it if needed.
4914 4983           */
4915 4984          switch (cache_state) {
4916 4985          case CACHE_NEEDED:
4917 4986                  if (create_cache(file, fd, elf, ehdr, &cache, shstrndx,
4918 4987                      &shnum, &flags) == 0)
4919 4988                          return (ret);
4920 4989                  break;
     4990 +        case CACHE_OK:
     4991 +                break;
4921 4992          case CACHE_FAIL:
4922 4993                  return (ret);
4923 4994          }
4924 4995          if (shnum <= 1)
4925 4996                  goto done;
4926 4997  
4927 4998          /*
4928 4999           * If -w was specified, find and write out the section(s) data.
4929 5000           */
4930 5001          if (wfd) {
↓ open down ↓ 227 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX