1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-06-28 04:11:43 +02:00

dwarf: fix synthetic eh_frame_hdr

Ben Avison (bavison@riscopen.org) has observed that when a synthetic
eh_frame_hdr is generated, there is no space in it for the eh_frame,
so the eh_frame value is written to, and later read from, memory that
is not assigned to this purpose, with unpredictable results.

This change adds a new field to the dwarf_eh_frame_hdr type, to
make room for that value, and adds the (packed) attribute to the
struct defintion to avoid a problem with unused space in the struct.
This commit is contained in:
Doug Moore 2017-07-05 21:56:31 -05:00 committed by Dave Watson
parent ca6b6f3ad9
commit 90d0d15c4e
3 changed files with 10 additions and 10 deletions

View file

@ -106,16 +106,16 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#define DW_EH_VERSION 1 /* The version we're implementing */
struct dwarf_eh_frame_hdr
struct __attribute__((packed)) dwarf_eh_frame_hdr
{
unsigned char version;
unsigned char eh_frame_ptr_enc;
unsigned char fde_count_enc;
unsigned char table_enc;
Elf_W (Addr) eh_frame;
/* The rest of the header is variable-length and consists of the
following members:
encoded_t eh_frame_ptr;
encoded_t fde_count;
struct
{

View file

@ -537,14 +537,14 @@ dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr)
eh_frame = dwarf_find_eh_frame_section (info);
if (eh_frame)
{
unsigned char *p = (unsigned char *) &synth_eh_frame_hdr;
Debug (1, "using synthetic .eh_frame_hdr section for %s\n",
info->dlpi_name);
/* synth_eh_frame_hdr.version */ p[0] = DW_EH_VERSION;
/* synth_eh_frame_hdr.eh_frame_ptr_enc */ p[1] = DW_EH_PE_absptr | ((sizeof(Elf_W (Addr)) == 4) ? DW_EH_PE_udata4 : DW_EH_PE_udata8);
/* synth_eh_frame_hdr.fde_count_enc */ p[2] = DW_EH_PE_omit;
/* synth_eh_frame_hdr.table_enc */ p[3] = DW_EH_PE_omit;
*(Elf_W (Addr) *)(&p[4]) = eh_frame;
synth_eh_frame_hdr.version = DW_EH_VERSION;
synth_eh_frame_hdr.eh_frame_ptr_enc = DW_EH_PE_absptr |
((sizeof(Elf_W (Addr)) == 4) ? DW_EH_PE_udata4 : DW_EH_PE_udata8);
synth_eh_frame_hdr.fde_count_enc = DW_EH_PE_omit;
synth_eh_frame_hdr.table_enc = DW_EH_PE_omit;
synth_eh_frame_hdr.eh_frame = eh_frame;
hdr = &synth_eh_frame_hdr;
}
}
@ -581,7 +581,7 @@ dwarf_callback (struct dl_phdr_info *info, size_t size, void *ptr)
}
a = unw_get_accessors (unw_local_addr_space);
addr = (unw_word_t) (uintptr_t) (hdr + 1);
addr = (unw_word_t) (uintptr_t) (&hdr->eh_frame);
/* (Optionally) read eh_frame_ptr: */
if ((ret = dwarf_read_encoded_pointer (unw_local_addr_space, a,

View file

@ -139,7 +139,7 @@ dwarf_find_unwind_table (struct elf_dyn_info *edi, unw_addr_space_t as,
}
a = unw_get_accessors (unw_local_addr_space);
addr = to_unw_word (hdr + 1);
addr = to_unw_word (&hdr->eh_frame);
/* Fill in a dummy proc_info structure. We just need to fill in
enough to ensure that dwarf_read_encoded_pointer() can do it's