Print this page
3265 link-editor builds bogus .eh_frame_hdr on ia32
@@ -530,11 +530,11 @@
* osabi - OSABI to use in displaying information
* file - Name of file
* flags - Command line option flags
*/
static void
-unwind_eh_frame(Cache *cache, Word shndx, Phdr *uphdr, Ehdr *ehdr,
+unwind_eh_frame(Cache *cache, Word shndx, Word shnum, Phdr *uphdr, Ehdr *ehdr,
gnu_eh_state_t *eh_state, uchar_t osabi, const char *file, uint_t flags)
{
#if defined(_ELF64)
#define MSG_UNW_BINSRTAB2 MSG_UNW_BINSRTAB2_64
#define MSG_UNW_BINSRTABENT MSG_UNW_BINSRTABENT_64
@@ -549,11 +549,20 @@
size_t datasize = _cache->c_data->d_size;
Conv_dwarf_ehe_buf_t dwarf_ehe_buf;
uint64_t ndx, frame_ptr, fde_cnt, tabndx;
uint_t vers, frame_ptr_enc, fde_cnt_enc, table_enc;
uint64_t initloc, initloc0;
+ uint64_t gotaddr = 0;
+ int cnt;
+ for (cnt = 1; cnt < shnum; cnt++) {
+ if (strncmp(cache[cnt].c_name, MSG_ORIG(MSG_ELF_GOT),
+ MSG_ELF_GOT_SIZE) == 0) {
+ gotaddr = cache[cnt].c_shdr->sh_addr;
+ break;
+ }
+ }
/*
* Is this a .eh_frame_hdr?
*/
if ((uphdr && (shdr->sh_addr == uphdr->p_vaddr)) ||
@@ -576,22 +585,22 @@
table_enc = data[ndx++];
dbg_print(0, MSG_ORIG(MSG_UNW_FRMVERS), vers);
frame_ptr = dwarf_ehe_extract(data, &ndx, frame_ptr_enc,
- ehdr->e_ident, shdr->sh_addr, ndx);
+ ehdr->e_ident, B_TRUE, shdr->sh_addr, ndx, gotaddr);
if (eh_state->hdr_cnt == 1) {
eh_state->hdr_ndx = shndx;
eh_state->frame_ptr = frame_ptr;
}
dbg_print(0, MSG_ORIG(MSG_UNW_FRPTRENC),
conv_dwarf_ehe(frame_ptr_enc, &dwarf_ehe_buf),
EC_XWORD(frame_ptr));
fde_cnt = dwarf_ehe_extract(data, &ndx, fde_cnt_enc,
- ehdr->e_ident, shdr->sh_addr, ndx);
+ ehdr->e_ident, B_TRUE, shdr->sh_addr, ndx, gotaddr);
dbg_print(0, MSG_ORIG(MSG_UNW_FDCNENC),
conv_dwarf_ehe(fde_cnt_enc, &dwarf_ehe_buf),
EC_XWORD(fde_cnt));
dbg_print(0, MSG_ORIG(MSG_UNW_TABENC),
@@ -599,21 +608,21 @@
dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB1));
dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB2));
for (tabndx = 0; tabndx < fde_cnt; tabndx++) {
initloc = dwarf_ehe_extract(data, &ndx, table_enc,
- ehdr->e_ident, shdr->sh_addr, ndx);
+ ehdr->e_ident, B_TRUE, shdr->sh_addr, ndx, gotaddr);
/*LINTED:E_VAR_USED_BEFORE_SET*/
if ((tabndx != 0) && (initloc0 > initloc))
(void) fprintf(stderr,
MSG_INTL(MSG_ERR_BADSORT), file,
_cache->c_name, EC_WORD(tabndx));
dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTABENT),
EC_XWORD(initloc),
EC_XWORD(dwarf_ehe_extract(data, &ndx,
- table_enc, ehdr->e_ident, shdr->sh_addr,
- ndx)));
+ table_enc, ehdr->e_ident, B_TRUE, shdr->sh_addr,
+ ndx, gotaddr)));
initloc0 = initloc;
}
} else { /* Display the .eh_frame section */
eh_state->frame_cnt++;
if (eh_state->frame_cnt == 1) {
@@ -626,11 +635,11 @@
(void) fprintf(stderr, MSG_INTL(MSG_WARN_MULTEHFRM),
file, EC_WORD(shndx), _cache->c_name,
conv_ehdr_type(osabi, ehdr->e_type, 0, &inv_buf));
}
dump_eh_frame(data, datasize, shdr->sh_addr,
- ehdr->e_machine, ehdr->e_ident);
+ ehdr->e_machine, ehdr->e_ident, gotaddr);
}
/*
* If we've seen the .eh_frame_hdr and the first .eh_frame section,
* compare the header frame_ptr to the address of the actual frame
@@ -873,12 +882,12 @@
if (is_exrange)
unwind_exception_ranges(_cache, file,
_elf_sys_encoding() != ehdr->e_ident[EI_DATA]);
else
- unwind_eh_frame(cache, cnt, uphdr, ehdr, &eh_state,
- osabi, file, flags);
+ unwind_eh_frame(cache, cnt, shnum, uphdr, ehdr,
+ &eh_state, osabi, file, flags);
}
}
/*
* Initialize a symbol table state structure