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

@@ -47,10 +47,11 @@
                                         /*      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,12 +300,12 @@
                         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);
+                            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,11 +464,11 @@
 #undef LOW_OP
 }
 
 void
 dump_eh_frame(uchar_t *data, size_t datasize, uint64_t sh_addr,
-    Half e_machine, uchar_t *e_ident)
+    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,10 +478,11 @@
 
         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,12 +568,12 @@
                                 case 'P':
                                         ciePflag = data[off + ndx];
                                         ndx += 1;
 
                                         persVal = dwarf_ehe_extract(&data[off],
-                                            &ndx, ciePflag, e_ident,
-                                            sh_addr, off + ndx);
+                                            &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,15 +633,15 @@
                             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);
+                            &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, sh_addr, off + ndx);
+                            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,11 +660,12 @@
                                 if (val && cieLflag_present) {
                                         uint64_t    lsda;
 
                                         lsda = dwarf_ehe_extract(&data[off],
                                             &lndx, cieLflag, e_ident,
-                                            sh_addr, off + lndx);
+                                            B_FALSE, sh_addr, off + lndx,
+                                            gotaddr);
                                         dbg_print(0,
                                             MSG_ORIG(MSG_UNW_FDEAXLSDA),
                                             EC_XWORD(lsda));
                                 }
                         }