bfd/
* elf-eh-frame.c (_bfd_elf_parse_eh_frame): Handle CIE version 4 provided that it has the expected address size and zero segment length. binutils/ * dwarf.c (struct Frame_Chunk): Add ptr_size and segment_size fields. (display_debug_frames): Handle CIE version 4.
This commit is contained in:
parent
a233b20c0e
commit
604282a731
@ -1,5 +1,9 @@
|
||||
2010-04-05 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* elf-eh-frame.c (_bfd_elf_parse_eh_frame): Handle CIE version 4
|
||||
provided that it has the expected address size and zero segment
|
||||
length.
|
||||
|
||||
* dwarf2.c (struct line_head): Add maximum_ops_per_insn field.
|
||||
(struct line_info): Add op_index field, change end_sequence type to
|
||||
unsigned char.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* .eh_frame section optimization.
|
||||
Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
||||
Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
||||
Free Software Foundation, Inc.
|
||||
Written by Jakub Jelinek <jakub@redhat.com>.
|
||||
|
||||
@ -636,7 +636,9 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
|
||||
REQUIRE (read_byte (&buf, end, &cie->version));
|
||||
|
||||
/* Cannot handle unknown versions. */
|
||||
REQUIRE (cie->version == 1 || cie->version == 3);
|
||||
REQUIRE (cie->version == 1
|
||||
|| cie->version == 3
|
||||
|| cie->version == 4);
|
||||
REQUIRE (strlen ((char *) buf) < sizeof (cie->augmentation));
|
||||
|
||||
strcpy (cie->augmentation, (char *) buf);
|
||||
@ -651,6 +653,13 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
|
||||
REQUIRE (skip_bytes (&buf, end, ptr_size));
|
||||
SKIP_RELOCS (buf);
|
||||
}
|
||||
if (cie->version >= 4)
|
||||
{
|
||||
REQUIRE (buf + 1 < end);
|
||||
REQUIRE (buf[0] == ptr_size);
|
||||
REQUIRE (buf[1] == 0);
|
||||
buf += 2;
|
||||
}
|
||||
REQUIRE (read_uleb128 (&buf, end, &cie->code_align));
|
||||
REQUIRE (read_sleb128 (&buf, end, &cie->data_align));
|
||||
if (cie->version == 1)
|
||||
|
@ -1,5 +1,9 @@
|
||||
2010-04-05 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* dwarf.c (struct Frame_Chunk): Add ptr_size and segment_size
|
||||
fields.
|
||||
(display_debug_frames): Handle CIE version 4.
|
||||
|
||||
* dwarf.c (struct State_Machine_Registers): Add op_index field,
|
||||
change end_sequence type to unsigned char.
|
||||
(reset_state_machine): Clear op_index.
|
||||
|
@ -3906,6 +3906,8 @@ typedef struct Frame_Chunk
|
||||
int ra;
|
||||
unsigned char fde_encoding;
|
||||
unsigned char cfa_exp;
|
||||
unsigned char ptr_size;
|
||||
unsigned char segment_size;
|
||||
}
|
||||
Frame_Chunk;
|
||||
|
||||
@ -4114,6 +4116,7 @@ display_debug_frames (struct dwarf_section *section,
|
||||
unsigned int length_return;
|
||||
int max_regs = 0;
|
||||
const char *bad_reg = _("bad register: ");
|
||||
int saved_eh_addr_size = eh_addr_size;
|
||||
|
||||
printf (_("Contents of the %s section:\n"), section->name);
|
||||
|
||||
@ -4128,7 +4131,7 @@ display_debug_frames (struct dwarf_section *section,
|
||||
int need_col_headers = 1;
|
||||
unsigned char *augmentation_data = NULL;
|
||||
unsigned long augmentation_data_len = 0;
|
||||
int encoded_ptr_size = eh_addr_size;
|
||||
int encoded_ptr_size = saved_eh_addr_size;
|
||||
int offset_size;
|
||||
int initial_length_size;
|
||||
|
||||
@ -4184,48 +4187,36 @@ display_debug_frames (struct dwarf_section *section,
|
||||
fc->augmentation = (char *) start;
|
||||
start = (unsigned char *) strchr ((char *) start, '\0') + 1;
|
||||
|
||||
if (fc->augmentation[0] == 'z')
|
||||
if (strcmp (fc->augmentation, "eh") == 0)
|
||||
start += eh_addr_size;
|
||||
|
||||
if (version >= 4)
|
||||
{
|
||||
fc->code_factor = LEB ();
|
||||
fc->data_factor = SLEB ();
|
||||
if (version == 1)
|
||||
{
|
||||
fc->ra = GET (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
fc->ra = LEB ();
|
||||
}
|
||||
augmentation_data_len = LEB ();
|
||||
augmentation_data = start;
|
||||
start += augmentation_data_len;
|
||||
}
|
||||
else if (strcmp (fc->augmentation, "eh") == 0)
|
||||
{
|
||||
start += eh_addr_size;
|
||||
fc->code_factor = LEB ();
|
||||
fc->data_factor = SLEB ();
|
||||
if (version == 1)
|
||||
{
|
||||
fc->ra = GET (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
fc->ra = LEB ();
|
||||
}
|
||||
fc->ptr_size = GET (1);
|
||||
fc->segment_size = GET (1);
|
||||
eh_addr_size = fc->ptr_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
fc->code_factor = LEB ();
|
||||
fc->data_factor = SLEB ();
|
||||
if (version == 1)
|
||||
{
|
||||
fc->ra = GET (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
fc->ra = LEB ();
|
||||
}
|
||||
fc->ptr_size = eh_addr_size;
|
||||
fc->segment_size = 0;
|
||||
}
|
||||
fc->code_factor = LEB ();
|
||||
fc->data_factor = SLEB ();
|
||||
if (version == 1)
|
||||
{
|
||||
fc->ra = GET (1);
|
||||
}
|
||||
else
|
||||
{
|
||||
fc->ra = LEB ();
|
||||
}
|
||||
|
||||
if (fc->augmentation[0] == 'z')
|
||||
{
|
||||
augmentation_data_len = LEB ();
|
||||
augmentation_data = start;
|
||||
start += augmentation_data_len;
|
||||
}
|
||||
cie = fc;
|
||||
|
||||
@ -4240,6 +4231,11 @@ display_debug_frames (struct dwarf_section *section,
|
||||
(unsigned long)(saved_start - section_start), length, cie_id);
|
||||
printf (" Version: %d\n", version);
|
||||
printf (" Augmentation: \"%s\"\n", fc->augmentation);
|
||||
if (version >= 4)
|
||||
{
|
||||
printf (" Pointer Size: %u\n", fc->ptr_size);
|
||||
printf (" Segment Size: %u\n", fc->segment_size);
|
||||
}
|
||||
printf (" Code alignment factor: %u\n", fc->code_factor);
|
||||
printf (" Data alignment factor: %d\n", fc->data_factor);
|
||||
printf (" Return address column: %d\n", fc->ra);
|
||||
@ -4286,6 +4282,7 @@ display_debug_frames (struct dwarf_section *section,
|
||||
{
|
||||
unsigned char *look_for;
|
||||
static Frame_Chunk fde_fc;
|
||||
unsigned long segment_selector;
|
||||
|
||||
fc = & fde_fc;
|
||||
memset (fc, 0, sizeof (Frame_Chunk));
|
||||
@ -4307,6 +4304,8 @@ display_debug_frames (struct dwarf_section *section,
|
||||
cie = fc;
|
||||
fc->augmentation = "";
|
||||
fc->fde_encoding = 0;
|
||||
fc->ptr_size = eh_addr_size;
|
||||
fc->segment_size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4316,6 +4315,9 @@ display_debug_frames (struct dwarf_section *section,
|
||||
memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
|
||||
memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
|
||||
fc->augmentation = cie->augmentation;
|
||||
fc->ptr_size = cie->ptr_size;
|
||||
eh_addr_size = cie->ptr_size;
|
||||
fc->segment_size = cie->segment_size;
|
||||
fc->code_factor = cie->code_factor;
|
||||
fc->data_factor = cie->data_factor;
|
||||
fc->cfa_reg = cie->cfa_reg;
|
||||
@ -4328,6 +4330,12 @@ display_debug_frames (struct dwarf_section *section,
|
||||
if (fc->fde_encoding)
|
||||
encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
|
||||
|
||||
segment_selector = 0;
|
||||
if (fc->segment_size)
|
||||
{
|
||||
segment_selector = byte_get (start, fc->segment_size);
|
||||
start += fc->segment_size;
|
||||
}
|
||||
fc->pc_begin = get_encoded_value (start, fc->fde_encoding);
|
||||
if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel)
|
||||
fc->pc_begin += section->address + (start - section_start);
|
||||
@ -4342,10 +4350,12 @@ display_debug_frames (struct dwarf_section *section,
|
||||
start += augmentation_data_len;
|
||||
}
|
||||
|
||||
printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n",
|
||||
printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=",
|
||||
(unsigned long)(saved_start - section_start), length, cie_id,
|
||||
(unsigned long)(cie->chunk_start - section_start),
|
||||
fc->pc_begin, fc->pc_begin + fc->pc_range);
|
||||
(unsigned long)(cie->chunk_start - section_start));
|
||||
if (fc->segment_size)
|
||||
printf ("%04lx:", segment_selector);
|
||||
printf ("%08lx..%08lx\n", fc->pc_begin, fc->pc_begin + fc->pc_range);
|
||||
if (! do_debug_frames_interp && augmentation_data_len)
|
||||
{
|
||||
unsigned long i;
|
||||
@ -4893,6 +4903,7 @@ display_debug_frames (struct dwarf_section *section,
|
||||
frame_display_row (fc, &need_col_headers, &max_regs);
|
||||
|
||||
start = block_end;
|
||||
eh_addr_size = saved_eh_addr_size;
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
|
Loading…
x
Reference in New Issue
Block a user