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/dwarf.c
          +++ new/usr/src/cmd/sgs/elfdump/common/dwarf.c
↓ open down ↓ 41 lines elided ↑ open up ↑
  42   42  typedef struct {
  43   43          Half            e_machine;      /* ehdr->e_machine */
  44   44          uchar_t         *e_ident;       /* ehdr->e_ident */
  45   45          uint64_t        sh_addr;        /* Address of eh_frame section */
  46   46          int             do_swap;        /* True if object and system byte */
  47   47                                          /*      order differs */
  48   48          int             cieRflag;       /* R flag from current CIE */
  49   49          uint64_t        ciecalign;      /* CIE code align factor */
  50   50          int64_t         ciedalign;      /* CIE data align factor */
  51   51          uint64_t        fdeinitloc;     /* FDE initial location */
       52 +        uint64_t        gotaddr;        /* Address of the GOT */
  52   53  } dump_cfi_state_t;
  53   54  
  54   55  
  55   56  /*
  56   57   * Extract an unsigned integer value from an .eh_frame section, converting it
  57   58   * from its native byte order to that of the running machine if necessary.
  58   59   *
  59   60   * entry:
  60   61   *      data - Base address from which to extract datum
  61   62   *      ndx - Address of variable giving index to start byte in data.
↓ open down ↓ 232 lines elided ↑ open up ↑
 294  295                          break;
 295  296  
 296  297                  case 0x0a:              /* v2: DW_CFA_remember_state */
 297  298                  case 0x0b:              /* v2: DW_CFA_restore_state */
 298  299                  case 0x2d:              /* GNU: DW_CFA_GNU_window_save */
 299  300                          dbg_print(0, MSG_ORIG(MSG_CFA_SIMPLE), PREFIX);
 300  301                          break;
 301  302  
 302  303                  case 0x01:              /* v2: DW_CFA_set_loc, address */
 303  304                          cur_pc = dwarf_ehe_extract(&data[off], ndx,
 304      -                            state->cieRflag, state->e_ident,
 305      -                            state->sh_addr, off + *ndx);
      305 +                            state->cieRflag, state->e_ident, B_FALSE,
      306 +                            state->sh_addr, off + *ndx, state->gotaddr);
 306  307                          dbg_print(0, MSG_ORIG(MSG_CFA_CFASET), PREFIX,
 307  308                              EC_XWORD(cur_pc));
 308  309                          break;
 309  310  
 310  311                  case 0x02:      /* v2: DW_CFA_advance_loc_1, 1-byte delta */
 311  312                  case 0x03:      /* v2: DW_CFA_advance_loc_2, 2-byte delta */
 312  313                  case 0x04:      /* v2: DW_CFA_advance_loc_4, 4-byte delta */
 313  314                          /*
 314  315                           * Since the codes are contiguous, and the sizes are
 315  316                           * powers of 2, we can compute the word width from
↓ open down ↓ 142 lines elided ↑ open up ↑
 458  459                  }
 459  460          }
 460  461  
 461  462  #undef PREFIX
 462  463  #undef REGNAME
 463  464  #undef LOW_OP
 464  465  }
 465  466  
 466  467  void
 467  468  dump_eh_frame(uchar_t *data, size_t datasize, uint64_t sh_addr,
 468      -    Half e_machine, uchar_t *e_ident)
      469 +    Half e_machine, uchar_t *e_ident, uint64_t gotaddr)
 469  470  {
 470  471          Conv_dwarf_ehe_buf_t    dwarf_ehe_buf;
 471  472          dump_cfi_state_t        cfi_state;
 472  473          uint64_t        off, ndx;
 473  474          uint_t          cieid, cielength, cieversion, cieretaddr;
 474  475          int             ciePflag, cieZflag, cieLflag, cieLflag_present;
 475  476          uint_t          cieaugndx, length, id;
 476  477          char            *cieaugstr;
 477  478  
 478  479          cfi_state.e_machine = e_machine;
 479  480          cfi_state.e_ident = e_ident;
 480  481          cfi_state.sh_addr = sh_addr;
 481  482          cfi_state.do_swap = _elf_sys_encoding() != e_ident[EI_DATA];
      483 +        cfi_state.gotaddr = gotaddr;
 482  484  
 483  485          off = 0;
 484  486          while (off < datasize) {
 485  487                  ndx = 0;
 486  488  
 487  489                  /*
 488  490                   * Extract length in native format.  A zero length indicates
 489  491                   * that this CIE is a terminator and that processing for this
 490  492                   * unwind information should end. However, skip this entry and
 491  493                   * keep processing, just in case there is any other information
↓ open down ↓ 69 lines elided ↑ open up ↑
 561  563                                           * the proper continuation index after
 562  564                                           * the aux data has been processed.
 563  565                                           */
 564  566                                          ndx_save = ndx;
 565  567                                          break;
 566  568                                  case 'P':
 567  569                                          ciePflag = data[off + ndx];
 568  570                                          ndx += 1;
 569  571  
 570  572                                          persVal = dwarf_ehe_extract(&data[off],
 571      -                                            &ndx, ciePflag, e_ident,
 572      -                                            sh_addr, off + ndx);
      573 +                                            &ndx, ciePflag, e_ident, B_FALSE,
      574 +                                            sh_addr, off + ndx, gotaddr);
 573  575                                          dbg_print(0,
 574  576                                              MSG_ORIG(MSG_UNW_CIEAXPERS));
 575  577                                          dbg_print(0,
 576  578                                              MSG_ORIG(MSG_UNW_CIEAXPERSENC),
 577  579                                              ciePflag, conv_dwarf_ehe(ciePflag,
 578  580                                              &dwarf_ehe_buf));
 579  581                                          dbg_print(0,
 580  582                                              MSG_ORIG(MSG_UNW_CIEAXPERSRTN),
 581  583                                              EC_XWORD(persVal));
 582  584                                          break;
↓ open down ↓ 43 lines elided ↑ open up ↑
 626  628                          uint_t      fdelength = length;
 627  629                          int         fdecieptr = id;
 628  630                          uint64_t    fdeaddrrange;
 629  631  
 630  632                          dbg_print(0, MSG_ORIG(MSG_UNW_FDE),
 631  633                              EC_XWORD(sh_addr + off));
 632  634                          dbg_print(0, MSG_ORIG(MSG_UNW_FDELNGTH),
 633  635                              fdelength, fdecieptr);
 634  636  
 635  637                          cfi_state.fdeinitloc = dwarf_ehe_extract(&data[off],
 636      -                            &ndx, cfi_state.cieRflag, e_ident,
 637      -                            sh_addr, off + ndx);
      638 +                            &ndx, cfi_state.cieRflag, e_ident, B_FALSE,
      639 +                            sh_addr, off + ndx, gotaddr);
 638  640                          fdeaddrrange = dwarf_ehe_extract(&data[off], &ndx,
 639  641                              (cfi_state.cieRflag & ~DW_EH_PE_pcrel),
 640      -                            e_ident, sh_addr, off + ndx);
      642 +                            e_ident, B_FALSE, sh_addr, off + ndx, gotaddr);
 641  643  
 642  644                          dbg_print(0, MSG_ORIG(MSG_UNW_FDEINITLOC),
 643  645                              EC_XWORD(cfi_state.fdeinitloc),
 644  646                              EC_XWORD(fdeaddrrange),
 645  647                              EC_XWORD(cfi_state.fdeinitloc + fdeaddrrange - 1));
 646  648  
 647  649                          if (cieaugstr[0])
 648  650                                  dbg_print(0, MSG_ORIG(MSG_UNW_FDEAXVAL));
 649  651                          if (cieZflag) {
 650  652                                  uint64_t    val;
↓ open down ↓ 2 lines elided ↑ open up ↑
 653  655                                  val = uleb_extract(&data[off], &ndx);
 654  656                                  lndx = ndx;
 655  657                                  ndx += val;
 656  658                                  dbg_print(0, MSG_ORIG(MSG_UNW_FDEAXSIZE),
 657  659                                      EC_XWORD(val));
 658  660                                  if (val && cieLflag_present) {
 659  661                                          uint64_t    lsda;
 660  662  
 661  663                                          lsda = dwarf_ehe_extract(&data[off],
 662  664                                              &lndx, cieLflag, e_ident,
 663      -                                            sh_addr, off + lndx);
      665 +                                            B_FALSE, sh_addr, off + lndx,
      666 +                                            gotaddr);
 664  667                                          dbg_print(0,
 665  668                                              MSG_ORIG(MSG_UNW_FDEAXLSDA),
 666  669                                              EC_XWORD(lsda));
 667  670                                  }
 668  671                          }
 669  672                          if ((fdelength + 4) > ndx)
 670  673                                  dump_cfi(data, off, &ndx, fdelength, &cfi_state,
 671  674                                      MSG_ORIG(MSG_UNW_FDECFI), 6);
 672  675                          off += fdelength + 4;
 673  676                  }
 674  677          }
 675  678  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX