mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2025-04-01 20:02:17 +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:
parent
ca6b6f3ad9
commit
90d0d15c4e
3 changed files with 10 additions and 10 deletions
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue