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));
}
}