Print this page
3265 link-editor builds bogus .eh_frame_hdr on ia32
        
*** 47,56 ****
--- 47,57 ----
                                          /*      order differs */
          int             cieRflag;       /* R flag from current CIE */
          uint64_t        ciecalign;      /* CIE code align factor */
          int64_t         ciedalign;      /* CIE data align factor */
          uint64_t        fdeinitloc;     /* FDE initial location */
+         uint64_t        gotaddr;        /* Address of the GOT */
  } dump_cfi_state_t;
  
  
  /*
   * Extract an unsigned integer value from an .eh_frame section, converting it
*** 299,310 ****
                          dbg_print(0, MSG_ORIG(MSG_CFA_SIMPLE), PREFIX);
                          break;
  
                  case 0x01:              /* v2: DW_CFA_set_loc, address */
                          cur_pc = dwarf_ehe_extract(&data[off], ndx,
!                             state->cieRflag, state->e_ident,
!                             state->sh_addr, off + *ndx);
                          dbg_print(0, MSG_ORIG(MSG_CFA_CFASET), PREFIX,
                              EC_XWORD(cur_pc));
                          break;
  
                  case 0x02:      /* v2: DW_CFA_advance_loc_1, 1-byte delta */
--- 300,311 ----
                          dbg_print(0, MSG_ORIG(MSG_CFA_SIMPLE), PREFIX);
                          break;
  
                  case 0x01:              /* v2: DW_CFA_set_loc, address */
                          cur_pc = dwarf_ehe_extract(&data[off], ndx,
!                             state->cieRflag, state->e_ident, B_FALSE,
!                             state->sh_addr, off + *ndx, state->gotaddr);
                          dbg_print(0, MSG_ORIG(MSG_CFA_CFASET), PREFIX,
                              EC_XWORD(cur_pc));
                          break;
  
                  case 0x02:      /* v2: DW_CFA_advance_loc_1, 1-byte delta */
*** 463,473 ****
  #undef LOW_OP
  }
  
  void
  dump_eh_frame(uchar_t *data, size_t datasize, uint64_t sh_addr,
!     Half e_machine, uchar_t *e_ident)
  {
          Conv_dwarf_ehe_buf_t    dwarf_ehe_buf;
          dump_cfi_state_t        cfi_state;
          uint64_t        off, ndx;
          uint_t          cieid, cielength, cieversion, cieretaddr;
--- 464,474 ----
  #undef LOW_OP
  }
  
  void
  dump_eh_frame(uchar_t *data, size_t datasize, uint64_t sh_addr,
!     Half e_machine, uchar_t *e_ident, uint64_t gotaddr)
  {
          Conv_dwarf_ehe_buf_t    dwarf_ehe_buf;
          dump_cfi_state_t        cfi_state;
          uint64_t        off, ndx;
          uint_t          cieid, cielength, cieversion, cieretaddr;
*** 477,486 ****
--- 478,488 ----
  
          cfi_state.e_machine = e_machine;
          cfi_state.e_ident = e_ident;
          cfi_state.sh_addr = sh_addr;
          cfi_state.do_swap = _elf_sys_encoding() != e_ident[EI_DATA];
+         cfi_state.gotaddr = gotaddr;
  
          off = 0;
          while (off < datasize) {
                  ndx = 0;
  
*** 566,577 ****
                                  case 'P':
                                          ciePflag = data[off + ndx];
                                          ndx += 1;
  
                                          persVal = dwarf_ehe_extract(&data[off],
!                                             &ndx, ciePflag, e_ident,
!                                             sh_addr, off + ndx);
                                          dbg_print(0,
                                              MSG_ORIG(MSG_UNW_CIEAXPERS));
                                          dbg_print(0,
                                              MSG_ORIG(MSG_UNW_CIEAXPERSENC),
                                              ciePflag, conv_dwarf_ehe(ciePflag,
--- 568,579 ----
                                  case 'P':
                                          ciePflag = data[off + ndx];
                                          ndx += 1;
  
                                          persVal = dwarf_ehe_extract(&data[off],
!                                             &ndx, ciePflag, e_ident, B_FALSE,
!                                             sh_addr, off + ndx, gotaddr);
                                          dbg_print(0,
                                              MSG_ORIG(MSG_UNW_CIEAXPERS));
                                          dbg_print(0,
                                              MSG_ORIG(MSG_UNW_CIEAXPERSENC),
                                              ciePflag, conv_dwarf_ehe(ciePflag,
*** 631,645 ****
                              EC_XWORD(sh_addr + off));
                          dbg_print(0, MSG_ORIG(MSG_UNW_FDELNGTH),
                              fdelength, fdecieptr);
  
                          cfi_state.fdeinitloc = dwarf_ehe_extract(&data[off],
!                             &ndx, cfi_state.cieRflag, e_ident,
!                             sh_addr, off + ndx);
                          fdeaddrrange = dwarf_ehe_extract(&data[off], &ndx,
                              (cfi_state.cieRflag & ~DW_EH_PE_pcrel),
!                             e_ident, sh_addr, off + ndx);
  
                          dbg_print(0, MSG_ORIG(MSG_UNW_FDEINITLOC),
                              EC_XWORD(cfi_state.fdeinitloc),
                              EC_XWORD(fdeaddrrange),
                              EC_XWORD(cfi_state.fdeinitloc + fdeaddrrange - 1));
--- 633,647 ----
                              EC_XWORD(sh_addr + off));
                          dbg_print(0, MSG_ORIG(MSG_UNW_FDELNGTH),
                              fdelength, fdecieptr);
  
                          cfi_state.fdeinitloc = dwarf_ehe_extract(&data[off],
!                             &ndx, cfi_state.cieRflag, e_ident, B_FALSE,
!                             sh_addr, off + ndx, gotaddr);
                          fdeaddrrange = dwarf_ehe_extract(&data[off], &ndx,
                              (cfi_state.cieRflag & ~DW_EH_PE_pcrel),
!                             e_ident, B_FALSE, sh_addr, off + ndx, gotaddr);
  
                          dbg_print(0, MSG_ORIG(MSG_UNW_FDEINITLOC),
                              EC_XWORD(cfi_state.fdeinitloc),
                              EC_XWORD(fdeaddrrange),
                              EC_XWORD(cfi_state.fdeinitloc + fdeaddrrange - 1));
*** 658,668 ****
                                  if (val && cieLflag_present) {
                                          uint64_t    lsda;
  
                                          lsda = dwarf_ehe_extract(&data[off],
                                              &lndx, cieLflag, e_ident,
!                                             sh_addr, off + lndx);
                                          dbg_print(0,
                                              MSG_ORIG(MSG_UNW_FDEAXLSDA),
                                              EC_XWORD(lsda));
                                  }
                          }
--- 660,671 ----
                                  if (val && cieLflag_present) {
                                          uint64_t    lsda;
  
                                          lsda = dwarf_ehe_extract(&data[off],
                                              &lndx, cieLflag, e_ident,
!                                             B_FALSE, sh_addr, off + lndx,
!                                             gotaddr);
                                          dbg_print(0,
                                              MSG_ORIG(MSG_UNW_FDEAXLSDA),
                                              EC_XWORD(lsda));
                                  }
                          }