Print this page
3265 link-editor builds bogus .eh_frame_hdr on ia32

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 ↓ 524 lines elided ↑ open up ↑
 525  525   *              the .eh_frame_hdr section.
 526  526   *      ehdr - ELF header for file
 527  527   *      eh_state - Data used across calls to this routine. The
 528  528   *              caller should zero it before the first call, and
 529  529   *              pass it on every call.
 530  530   *      osabi - OSABI to use in displaying information
 531  531   *      file - Name of file
 532  532   *      flags - Command line option flags
 533  533   */
 534  534  static void
 535      -unwind_eh_frame(Cache *cache, Word shndx, Phdr *uphdr, Ehdr *ehdr,
      535 +unwind_eh_frame(Cache *cache, Word shndx, Word shnum, Phdr *uphdr, Ehdr *ehdr,
 536  536      gnu_eh_state_t *eh_state, uchar_t osabi, const char *file, uint_t flags)
 537  537  {
 538  538  #if     defined(_ELF64)
 539  539  #define MSG_UNW_BINSRTAB2       MSG_UNW_BINSRTAB2_64
 540  540  #define MSG_UNW_BINSRTABENT     MSG_UNW_BINSRTABENT_64
 541  541  #else
 542  542  #define MSG_UNW_BINSRTAB2       MSG_UNW_BINSRTAB2_32
 543  543  #define MSG_UNW_BINSRTABENT     MSG_UNW_BINSRTABENT_32
 544  544  #endif
 545  545  
 546  546          Cache                   *_cache = &cache[shndx];
 547  547          Shdr                    *shdr = _cache->c_shdr;
 548  548          uchar_t                 *data = (uchar_t *)(_cache->c_data->d_buf);
 549  549          size_t                  datasize = _cache->c_data->d_size;
 550  550          Conv_dwarf_ehe_buf_t    dwarf_ehe_buf;
 551  551          uint64_t                ndx, frame_ptr, fde_cnt, tabndx;
 552  552          uint_t                  vers, frame_ptr_enc, fde_cnt_enc, table_enc;
 553  553          uint64_t                initloc, initloc0;
      554 +        uint64_t                gotaddr = 0;
      555 +        int                     cnt;
 554  556  
      557 +        for (cnt = 1; cnt < shnum; cnt++) {
      558 +                if (strncmp(cache[cnt].c_name, MSG_ORIG(MSG_ELF_GOT),
      559 +                    MSG_ELF_GOT_SIZE) == 0) {
      560 +                        gotaddr = cache[cnt].c_shdr->sh_addr;
      561 +                        break;
      562 +                }
      563 +        }
 555  564  
 556  565          /*
 557  566           * Is this a .eh_frame_hdr?
 558  567           */
 559  568          if ((uphdr && (shdr->sh_addr == uphdr->p_vaddr)) ||
 560  569              (strncmp(_cache->c_name, MSG_ORIG(MSG_SCN_FRMHDR),
 561  570              MSG_SCN_FRMHDR_SIZE) == 0)) {
 562  571                  /*
 563  572                   * There can only be a single .eh_frame_hdr.
 564  573                   * Flag duplicates.
↓ open down ↓ 6 lines elided ↑ open up ↑
 571  580                  ndx = 0;
 572  581  
 573  582                  vers = data[ndx++];
 574  583                  frame_ptr_enc = data[ndx++];
 575  584                  fde_cnt_enc = data[ndx++];
 576  585                  table_enc = data[ndx++];
 577  586  
 578  587                  dbg_print(0, MSG_ORIG(MSG_UNW_FRMVERS), vers);
 579  588  
 580  589                  frame_ptr = dwarf_ehe_extract(data, &ndx, frame_ptr_enc,
 581      -                    ehdr->e_ident, shdr->sh_addr, ndx);
      590 +                    ehdr->e_ident, B_TRUE, shdr->sh_addr, ndx, gotaddr);
 582  591                  if (eh_state->hdr_cnt == 1) {
 583  592                          eh_state->hdr_ndx = shndx;
 584  593                          eh_state->frame_ptr = frame_ptr;
 585  594                  }
 586  595  
 587  596                  dbg_print(0, MSG_ORIG(MSG_UNW_FRPTRENC),
 588  597                      conv_dwarf_ehe(frame_ptr_enc, &dwarf_ehe_buf),
 589  598                      EC_XWORD(frame_ptr));
 590  599  
 591  600                  fde_cnt = dwarf_ehe_extract(data, &ndx, fde_cnt_enc,
 592      -                    ehdr->e_ident, shdr->sh_addr, ndx);
      601 +                    ehdr->e_ident, B_TRUE, shdr->sh_addr, ndx, gotaddr);
 593  602  
 594  603                  dbg_print(0, MSG_ORIG(MSG_UNW_FDCNENC),
 595  604                      conv_dwarf_ehe(fde_cnt_enc, &dwarf_ehe_buf),
 596  605                      EC_XWORD(fde_cnt));
 597  606                  dbg_print(0, MSG_ORIG(MSG_UNW_TABENC),
 598  607                      conv_dwarf_ehe(table_enc, &dwarf_ehe_buf));
 599  608                  dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB1));
 600  609                  dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB2));
 601  610  
 602  611                  for (tabndx = 0; tabndx < fde_cnt; tabndx++) {
 603  612                          initloc = dwarf_ehe_extract(data, &ndx, table_enc,
 604      -                            ehdr->e_ident, shdr->sh_addr, ndx);
      613 +                            ehdr->e_ident, B_TRUE, shdr->sh_addr, ndx, gotaddr);
 605  614                          /*LINTED:E_VAR_USED_BEFORE_SET*/
 606  615                          if ((tabndx != 0) && (initloc0 > initloc))
 607  616                                  (void) fprintf(stderr,
 608  617                                      MSG_INTL(MSG_ERR_BADSORT), file,
 609  618                                      _cache->c_name, EC_WORD(tabndx));
 610  619                          dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTABENT),
 611  620                              EC_XWORD(initloc),
 612  621                              EC_XWORD(dwarf_ehe_extract(data, &ndx,
 613      -                            table_enc, ehdr->e_ident, shdr->sh_addr,
 614      -                            ndx)));
      622 +                            table_enc, ehdr->e_ident, B_TRUE, shdr->sh_addr,
      623 +                            ndx, gotaddr)));
 615  624                          initloc0 = initloc;
 616  625                  }
 617  626          } else {                /* Display the .eh_frame section */
 618  627                  eh_state->frame_cnt++;
 619  628                  if (eh_state->frame_cnt == 1) {
 620  629                          eh_state->frame_ndx = shndx;
 621  630                          eh_state->frame_base = shdr->sh_addr;
 622  631                  } else if ((eh_state->frame_cnt >  1) &&
 623  632                      (ehdr->e_type != ET_REL)) {
 624  633                          Conv_inv_buf_t  inv_buf;
 625  634  
 626  635                          (void) fprintf(stderr, MSG_INTL(MSG_WARN_MULTEHFRM),
 627  636                              file, EC_WORD(shndx), _cache->c_name,
 628  637                              conv_ehdr_type(osabi, ehdr->e_type, 0, &inv_buf));
 629  638                  }
 630  639                  dump_eh_frame(data, datasize, shdr->sh_addr,
 631      -                    ehdr->e_machine, ehdr->e_ident);
      640 +                    ehdr->e_machine, ehdr->e_ident, gotaddr);
 632  641          }
 633  642  
 634  643          /*
 635  644           * If we've seen the .eh_frame_hdr and the first .eh_frame section,
 636  645           * compare the header frame_ptr to the address of the actual frame
 637  646           * section to ensure the link-editor got this right.  Note, this
 638  647           * diagnostic is only produced when unwind information is explicitly
 639  648           * asked for, as shared objects built with an older ld(1) may reveal
 640  649           * this inconsistency.  Although an inconsistency, it doesn't seem to
 641  650           * have any adverse effect on existing tools.
↓ open down ↓ 226 lines elided ↑ open up ↑
 868  877                  if (_cache->c_data == NULL)
 869  878                          continue;
 870  879  
 871  880                  dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
 872  881                  dbg_print(0, MSG_INTL(MSG_ELF_SCN_UNWIND), _cache->c_name);
 873  882  
 874  883                  if (is_exrange)
 875  884                          unwind_exception_ranges(_cache, file,
 876  885                              _elf_sys_encoding() != ehdr->e_ident[EI_DATA]);
 877  886                  else
 878      -                        unwind_eh_frame(cache, cnt, uphdr, ehdr, &eh_state,
 879      -                            osabi, file, flags);
      887 +                        unwind_eh_frame(cache, cnt, shnum, uphdr, ehdr,
      888 +                            &eh_state, osabi, file, flags);
 880  889          }
 881  890  }
 882  891  
 883  892  /*
 884  893   * Initialize a symbol table state structure
 885  894   *
 886  895   * entry:
 887  896   *      state - State structure to be initialized
 888  897   *      cache - Cache of all section headers
 889  898   *      shnum - # of sections in cache
↓ open down ↓ 4259 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX