binutils/binutils-2.20.51.0.7-dwarf4...

1327 lines
42 KiB
Diff

diff -rcp ../binutils-2.20.51.0.7.original/bfd/ChangeLog ./bfd/ChangeLog
*** ../binutils-2.20.51.0.7.original/bfd/ChangeLog 2010-04-08 15:40:38.000000000 +0100
--- ./bfd/ChangeLog 2010-04-08 15:40:46.000000000 +0100
***************
*** 1,3 ****
--- 1,31 ----
+ 2010-04-08 Nick Clifton <nickc@redhat.com>
+
+ Import these patches from the mainline:
+
+ 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.
+ (new_line_sorts_after): For the same address compare op_index.
+ (add_line_info): Add op_index argument, store it into the structure.
+ (decode_line_info): Complain about unknown versions of .debug_line.
+ Initialize maximum_ops_per_insn. Add op_index state register and
+ track it.
+
+ 2010-04-01 Jakub Jelinek <jakub@redhat.com>
+
+ * dwarf2.c (read_attribute_value): Handle CU version 4
+ for DW_FORM_ref_addr, handle DW_FORM_sec_offset, DW_FORM_exprloc
+ and DW_FORM_flag_present. For unknown form value return NULL.
+ (scan_unit_for_symbols): For DW_AT_location handle DW_FORM_exprloc
+ like DW_FORM_block.
+ (parse_comp_unit): Allow CU version 4.
+
+
2010-04-07 Nick Clifton <nickc@redhat.com>
Import this patch from the mainline:
diff -rcp ../binutils-2.20.51.0.7.original/bfd/dwarf2.c ./bfd/dwarf2.c
*** ../binutils-2.20.51.0.7.original/bfd/dwarf2.c 2010-04-08 15:40:38.000000000 +0100
--- ./bfd/dwarf2.c 2010-04-08 15:47:06.000000000 +0100
*************** struct line_head
*** 45,50 ****
--- 45,51 ----
unsigned short version;
bfd_vma prologue_length;
unsigned char minimum_instruction_length;
+ unsigned char maximum_ops_per_insn;
unsigned char default_is_stmt;
int line_base;
unsigned char line_range;
*************** read_attribute_value (struct attribute *
*** 760,766 ****
case DW_FORM_ref_addr:
/* DW_FORM_ref_addr is an address in DWARF2, and an offset in
DWARF3. */
! if (unit->version == 3)
{
if (unit->offset_size == 4)
attr->u.val = read_4_bytes (unit->abfd, info_ptr);
--- 761,767 ----
case DW_FORM_ref_addr:
/* DW_FORM_ref_addr is an address in DWARF2, and an offset in
DWARF3. */
! if (unit->version == 3 || unit->version == 4)
{
if (unit->offset_size == 4)
attr->u.val = read_4_bytes (unit->abfd, info_ptr);
*************** read_attribute_value (struct attribute *
*** 774,779 ****
--- 775,787 ----
attr->u.val = read_address (unit, info_ptr);
info_ptr += unit->addr_size;
break;
+ case DW_FORM_sec_offset:
+ if (unit->offset_size == 4)
+ attr->u.val = read_4_bytes (unit->abfd, info_ptr);
+ else
+ attr->u.val = read_8_bytes (unit->abfd, info_ptr);
+ info_ptr += unit->offset_size;
+ break;
case DW_FORM_block2:
amt = sizeof (struct dwarf_block);
blk = (struct dwarf_block *) bfd_alloc (abfd, amt);
*************** read_attribute_value (struct attribute *
*** 816,821 ****
--- 824,830 ----
attr->u.str = read_indirect_string (unit, info_ptr, &bytes_read);
info_ptr += bytes_read;
break;
+ case DW_FORM_exprloc:
case DW_FORM_block:
amt = sizeof (struct dwarf_block);
blk = (struct dwarf_block *) bfd_alloc (abfd, amt);
*************** read_attribute_value (struct attribute *
*** 846,851 ****
--- 855,863 ----
attr->u.val = read_1_byte (abfd, info_ptr);
info_ptr += 1;
break;
+ case DW_FORM_flag_present:
+ attr->u.val = 1;
+ break;
case DW_FORM_sdata:
attr->u.sval = read_signed_leb128 (abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
*************** read_attribute_value (struct attribute *
*** 887,892 ****
--- 899,905 ----
(*_bfd_error_handler) (_("Dwarf Error: Invalid or unhandled FORM value: %u."),
form);
bfd_set_error (bfd_error_bad_value);
+ return NULL;
}
return info_ptr;
}
*************** struct line_info
*** 916,922 ****
char *filename;
unsigned int line;
unsigned int column;
! int end_sequence; /* End of (sequential) code sequence. */
};
struct fileinfo
--- 929,936 ----
char *filename;
unsigned int line;
unsigned int column;
! unsigned char op_index;
! unsigned char end_sequence; /* End of (sequential) code sequence. */
};
struct fileinfo
*************** new_line_sorts_after (struct line_info *
*** 990,996 ****
{
return (new_line->address > line->address
|| (new_line->address == line->address
! && new_line->end_sequence < line->end_sequence));
}
--- 1004,1012 ----
{
return (new_line->address > line->address
|| (new_line->address == line->address
! && (new_line->op_index > line->op_index
! || (new_line->op_index == line->op_index
! && new_line->end_sequence < line->end_sequence))));
}
*************** new_line_sorts_after (struct line_info *
*** 1002,1007 ****
--- 1018,1024 ----
static bfd_boolean
add_line_info (struct line_info_table *table,
bfd_vma address,
+ unsigned char op_index,
char *filename,
unsigned int line,
unsigned int column,
*************** add_line_info (struct line_info_table *t
*** 1016,1021 ****
--- 1033,1039 ----
/* Set member data of 'info'. */
info->address = address;
+ info->op_index = op_index;
info->line = line;
info->column = column;
info->end_sequence = end_sequence;
*************** add_line_info (struct line_info_table *t
*** 1047,1052 ****
--- 1065,1071 ----
if (seq
&& seq->last_line->address == address
+ && seq->last_line->op_index == op_index
&& seq->last_line->end_sequence == end_sequence)
{
/* We only keep the last entry with the same address and end
*************** decode_line_info (struct comp_unit *unit
*** 1372,1377 ****
--- 1391,1403 ----
}
line_end = line_ptr + lh.total_length;
lh.version = read_2_bytes (abfd, line_ptr);
+ if (lh.version < 2 || lh.version > 4)
+ {
+ (*_bfd_error_handler)
+ (_("Dwarf Error: Unhandled .debug_line version %d."), lh.version);
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ }
line_ptr += 2;
if (offset_size == 4)
lh.prologue_length = read_4_bytes (abfd, line_ptr);
*************** decode_line_info (struct comp_unit *unit
*** 1380,1385 ****
--- 1406,1425 ----
line_ptr += offset_size;
lh.minimum_instruction_length = read_1_byte (abfd, line_ptr);
line_ptr += 1;
+ if (lh.version >= 4)
+ {
+ lh.maximum_ops_per_insn = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ }
+ else
+ lh.maximum_ops_per_insn = 1;
+ if (lh.maximum_ops_per_insn == 0)
+ {
+ (*_bfd_error_handler)
+ (_("Dwarf Error: Invalid maximum operations per instruction."));
+ bfd_set_error (bfd_error_bad_value);
+ return NULL;
+ }
lh.default_is_stmt = read_1_byte (abfd, line_ptr);
line_ptr += 1;
lh.line_base = read_1_signed_byte (abfd, line_ptr);
*************** decode_line_info (struct comp_unit *unit
*** 1460,1465 ****
--- 1500,1506 ----
{
/* State machine registers. */
bfd_vma address = 0;
+ unsigned char op_index = 0;
char * filename = table->num_files ? concat_filename (table, 1) : NULL;
unsigned int line = 1;
unsigned int column = 0;
*************** decode_line_info (struct comp_unit *unit
*** 1483,1493 ****
{
/* Special operand. */
adj_opcode = op_code - lh.opcode_base;
! address += (adj_opcode / lh.line_range)
! * lh.minimum_instruction_length;
line += lh.line_base + (adj_opcode % lh.line_range);
/* Append row to matrix using current values. */
! if (!add_line_info (table, address, filename, line, column, 0))
goto line_fail;
if (address < low_pc)
low_pc = address;
--- 1524,1544 ----
{
/* Special operand. */
adj_opcode = op_code - lh.opcode_base;
! if (lh.maximum_ops_per_insn == 1)
! address += (adj_opcode / lh.line_range)
! * lh.minimum_instruction_length;
! else
! {
! address += ((op_index + (adj_opcode / lh.line_range))
! / lh.maximum_ops_per_insn)
! * lh.minimum_instruction_length;
! op_index = (op_index + (adj_opcode / lh.line_range))
! % lh.maximum_ops_per_insn;
! }
line += lh.line_base + (adj_opcode % lh.line_range);
/* Append row to matrix using current values. */
! if (! add_line_info (table, address, op_index, filename,
! line, column, 0))
goto line_fail;
if (address < low_pc)
low_pc = address;
*************** decode_line_info (struct comp_unit *unit
*** 1506,1513 ****
{
case DW_LNE_end_sequence:
end_sequence = 1;
! if (!add_line_info (table, address, filename, line, column,
! end_sequence))
goto line_fail;
if (address < low_pc)
low_pc = address;
--- 1557,1564 ----
{
case DW_LNE_end_sequence:
end_sequence = 1;
! if (!add_line_info (table, address, op_index, filename,
! line, column, end_sequence))
goto line_fail;
if (address < low_pc)
low_pc = address;
*************** decode_line_info (struct comp_unit *unit
*** 1518,1523 ****
--- 1569,1575 ----
break;
case DW_LNE_set_address:
address = read_address (unit, line_ptr);
+ op_index = 0;
line_ptr += unit->addr_size;
break;
case DW_LNE_define_file:
*************** decode_line_info (struct comp_unit *unit
*** 1560,1566 ****
}
break;
case DW_LNS_copy:
! if (!add_line_info (table, address, filename, line, column, 0))
goto line_fail;
if (address < low_pc)
low_pc = address;
--- 1612,1618 ----
}
break;
case DW_LNS_copy:
! if (!add_line_info (table, address, op_index, filename, line, column, 0))
goto line_fail;
if (address < low_pc)
low_pc = address;
*************** decode_line_info (struct comp_unit *unit
*** 1568,1575 ****
high_pc = address;
break;
case DW_LNS_advance_pc:
! address += lh.minimum_instruction_length
! * read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
line_ptr += bytes_read;
break;
case DW_LNS_advance_line:
--- 1620,1637 ----
high_pc = address;
break;
case DW_LNS_advance_pc:
! if (lh.maximum_ops_per_insn == 1)
! address += lh.minimum_instruction_length
! * read_unsigned_leb128 (abfd, line_ptr,
! &bytes_read);
! else
! {
! bfd_vma adjust = read_unsigned_leb128 (abfd, line_ptr,
! &bytes_read);
! address = ((op_index + adjust) / lh.maximum_ops_per_insn)
! * lh.minimum_instruction_length;
! op_index = (op_index + adjust) % lh.maximum_ops_per_insn;
! }
line_ptr += bytes_read;
break;
case DW_LNS_advance_line:
*************** decode_line_info (struct comp_unit *unit
*** 1599,1609 ****
case DW_LNS_set_basic_block:
break;
case DW_LNS_const_add_pc:
! address += lh.minimum_instruction_length
! * ((255 - lh.opcode_base) / lh.line_range);
break;
case DW_LNS_fixed_advance_pc:
address += read_2_bytes (abfd, line_ptr);
line_ptr += 2;
break;
default:
--- 1661,1680 ----
case DW_LNS_set_basic_block:
break;
case DW_LNS_const_add_pc:
! if (lh.maximum_ops_per_insn == 1)
! address += lh.minimum_instruction_length
! * ((255 - lh.opcode_base) / lh.line_range);
! else
! {
! bfd_vma adjust = ((255 - lh.opcode_base) / lh.line_range);
! address += lh.minimum_instruction_length
! * ((op_index + adjust) / lh.maximum_ops_per_insn);
! op_index = (op_index + adjust) % lh.maximum_ops_per_insn;
! }
break;
case DW_LNS_fixed_advance_pc:
address += read_2_bytes (abfd, line_ptr);
+ op_index = 0;
line_ptr += 2;
break;
default:
*************** scan_unit_for_symbols (struct comp_unit
*** 2113,2118 ****
--- 2184,2190 ----
case DW_FORM_block1:
case DW_FORM_block2:
case DW_FORM_block4:
+ case DW_FORM_exprloc:
if (*attr.u.blk->data == DW_OP_addr)
{
var->stack = 0;
*************** parse_comp_unit (struct dwarf2_debug *st
*** 2216,2224 ****
addr_size = read_1_byte (abfd, info_ptr);
info_ptr += 1;
! if (version != 2 && version != 3)
{
! (*_bfd_error_handler) (_("Dwarf Error: found dwarf version '%u', this reader only handles version 2 and 3 information."), version);
bfd_set_error (bfd_error_bad_value);
return 0;
}
--- 2288,2296 ----
addr_size = read_1_byte (abfd, info_ptr);
info_ptr += 1;
! if (version != 2 && version != 3 && version != 4)
{
! (*_bfd_error_handler) (_("Dwarf Error: found dwarf version '%u', this reader only handles version 2, 3 and 4 information."), version);
bfd_set_error (bfd_error_bad_value);
return 0;
}
diff -rcp ../binutils-2.20.51.0.7.original/bfd/elf-eh-frame.c ./bfd/elf-eh-frame.c
*** ../binutils-2.20.51.0.7.original/bfd/elf-eh-frame.c 2010-04-08 15:40:38.000000000 +0100
--- ./bfd/elf-eh-frame.c 2010-04-08 15:40:46.000000000 +0100
*************** _bfd_elf_parse_eh_frame (bfd *abfd, stru
*** 636,642 ****
REQUIRE (read_byte (&buf, end, &cie->version));
/* Cannot handle unknown versions. */
! REQUIRE (cie->version == 1 || cie->version == 3);
REQUIRE (strlen ((char *) buf) < sizeof (cie->augmentation));
strcpy (cie->augmentation, (char *) buf);
--- 636,644 ----
REQUIRE (read_byte (&buf, end, &cie->version));
/* Cannot handle unknown versions. */
! REQUIRE (cie->version == 1
! || cie->version == 3
! || cie->version == 4);
REQUIRE (strlen ((char *) buf) < sizeof (cie->augmentation));
strcpy (cie->augmentation, (char *) buf);
*************** _bfd_elf_parse_eh_frame (bfd *abfd, stru
*** 651,656 ****
--- 653,665 ----
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)
diff -rcp ../binutils-2.20.51.0.7.original/binutils/ChangeLog ./binutils/ChangeLog
*** ../binutils-2.20.51.0.7.original/binutils/ChangeLog 2010-04-08 15:40:38.000000000 +0100
--- ./binutils/ChangeLog 2010-04-08 15:47:41.000000000 +0100
***************
*** 1,3 ****
--- 1,31 ----
+ 2010-04-08 Nick Clifton <nickc@redhat.com>
+
+ Import these patches from the mainline:
+
+ 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.
+ (process_extended_line_op): For DW_LNE_set_address clear op_index.
+ (display_debug_lines_raw): Initialize li_max_ops_per_insn.
+ Track op_index state machine register and print it if
+ li_max_ops_per_insn is != 1.
+ (display_debug_lines_decoded): Likewise.
+
+ 2010-04-01 Jakub Jelinek <jakub@redhat.com>
+
+ * dwarf.c (read_and_display_attr_value): Don't reject
+ dwarf_version == 4. Handle DW_FORM_sec_offset, DW_FORM_flag_present
+ and DW_FORM_exprloc.
+ (process_debug_info): Handle cu_version == 4.
+ (display_debug_lines_raw, display_debug_lines_decoded): Handle
+ li_version == 4.
+
2010-03-17 Alan Modra <amodra@gmail.com>
* readelf.c (dump_arm_unwind): Warning fix.
diff -rcp ../binutils-2.20.51.0.7.original/binutils/dwarf.c ./binutils/dwarf.c
*** ../binutils-2.20.51.0.7.original/binutils/dwarf.c 2010-04-08 15:40:38.000000000 +0100
--- ./binutils/dwarf.c 2010-04-08 15:56:46.000000000 +0100
*************** typedef struct State_Machine_Registers
*** 264,270 ****
unsigned int column;
int is_stmt;
int basic_block;
! int end_sequence;
/* This variable hold the number of the last entry seen
in the File Table. */
unsigned int last_file_entry;
--- 264,271 ----
unsigned int column;
int is_stmt;
int basic_block;
! unsigned char op_index;
! unsigned char end_sequence;
/* This variable hold the number of the last entry seen
in the File Table. */
unsigned int last_file_entry;
*************** static void
*** 276,281 ****
--- 277,283 ----
reset_state_machine (int is_stmt)
{
state_machine_regs.address = 0;
+ state_machine_regs.op_index = 0;
state_machine_regs.file = 1;
state_machine_regs.line = 1;
state_machine_regs.column = 0;
*************** process_extended_line_op (unsigned char
*** 322,327 ****
--- 324,330 ----
adr = byte_get (data, len - bytes_read - 1);
printf (_("set Address to 0x%lx\n"), adr);
state_machine_regs.address = adr;
+ state_machine_regs.op_index = 0;
break;
case DW_LNE_define_file:
*************** read_and_display_attr_value (unsigned lo
*** 1154,1167 ****
uvalue = byte_get (data, pointer_size);
data += pointer_size;
}
! else if (dwarf_version == 3)
{
uvalue = byte_get (data, offset_size);
data += offset_size;
}
else
{
! error (_("Internal error: DWARF version is not 2 or 3.\n"));
}
break;
--- 1157,1170 ----
uvalue = byte_get (data, pointer_size);
data += pointer_size;
}
! else if (dwarf_version == 3 || dwarf_version == 4)
{
uvalue = byte_get (data, offset_size);
data += offset_size;
}
else
{
! error (_("Internal error: DWARF version is not 2, 3 or 4.\n"));
}
break;
*************** read_and_display_attr_value (unsigned lo
*** 1171,1180 ****
--- 1174,1188 ----
break;
case DW_FORM_strp:
+ case DW_FORM_sec_offset:
uvalue = byte_get (data, offset_size);
data += offset_size;
break;
+ case DW_FORM_flag_present:
+ uvalue = 1;
+ break;
+
case DW_FORM_ref1:
case DW_FORM_flag:
case DW_FORM_data1:
*************** read_and_display_attr_value (unsigned lo
*** 1233,1242 ****
--- 1241,1252 ----
case DW_FORM_data4:
case DW_FORM_addr:
+ case DW_FORM_sec_offset:
if (!do_loc)
printf (" 0x%lx", uvalue);
break;
+ case DW_FORM_flag_present:
case DW_FORM_flag:
case DW_FORM_data1:
case DW_FORM_data2:
*************** read_and_display_attr_value (unsigned lo
*** 1272,1277 ****
--- 1282,1288 ----
break;
case DW_FORM_block:
+ case DW_FORM_exprloc:
uvalue = read_leb128 (data, & bytes_read, 0);
block_start = data + bytes_read;
if (do_loc)
*************** read_and_display_attr_value (unsigned lo
*** 1352,1358 ****
case DW_AT_segment:
case DW_AT_static_link:
case DW_AT_use_location:
! if (form == DW_FORM_data4 || form == DW_FORM_data8)
{
/* Process location list. */
unsigned int lmax = debug_info_p->max_loc_offsets;
--- 1363,1371 ----
case DW_AT_segment:
case DW_AT_static_link:
case DW_AT_use_location:
! if (form == DW_FORM_data4
! || form == DW_FORM_data8
! || form == DW_FORM_sec_offset)
{
/* Process location list. */
unsigned int lmax = debug_info_p->max_loc_offsets;
*************** read_and_display_attr_value (unsigned lo
*** 1381,1387 ****
break;
case DW_AT_ranges:
! if (form == DW_FORM_data4 || form == DW_FORM_data8)
{
/* Process range list. */
unsigned int lmax = debug_info_p->max_range_lists;
--- 1394,1402 ----
break;
case DW_AT_ranges:
! if (form == DW_FORM_data4
! || form == DW_FORM_data8
! || form == DW_FORM_sec_offset)
{
/* Process range list. */
unsigned int lmax = debug_info_p->max_range_lists;
*************** read_and_display_attr_value (unsigned lo
*** 1591,1597 ****
case DW_AT_segment:
case DW_AT_static_link:
case DW_AT_use_location:
! if (form == DW_FORM_data4 || form == DW_FORM_data8)
printf (_("(location list)"));
/* Fall through. */
case DW_AT_allocated:
--- 1606,1614 ----
case DW_AT_segment:
case DW_AT_static_link:
case DW_AT_use_location:
! if (form == DW_FORM_data4
! || form == DW_FORM_data8
! || form == DW_FORM_sec_offset)
printf (_("(location list)"));
/* Fall through. */
case DW_AT_allocated:
*************** process_debug_info (struct dwarf_section
*** 2038,2044 ****
tags = hdrptr;
start += compunit.cu_length + initial_length_size;
! if (compunit.cu_version != 2 && compunit.cu_version != 3)
{
warn (_("CU at offset %lx contains corrupt or unsupported version number: %d.\n"),
cu_offset, compunit.cu_version);
--- 2055,2063 ----
tags = hdrptr;
start += compunit.cu_length + initial_length_size;
! if (compunit.cu_version != 2
! && compunit.cu_version != 3
! && compunit.cu_version != 4)
{
warn (_("CU at offset %lx contains corrupt or unsupported version number: %d.\n"),
cu_offset, compunit.cu_version);
*************** display_debug_lines_raw (struct dwarf_se
*** 2269,2277 ****
/* Check its version number. */
linfo.li_version = byte_get (hdrptr, 2);
hdrptr += 2;
! if (linfo.li_version != 2 && linfo.li_version != 3)
{
! warn (_("Only DWARF version 2 and 3 line info is currently supported.\n"));
return 0;
}
--- 2288,2298 ----
/* Check its version number. */
linfo.li_version = byte_get (hdrptr, 2);
hdrptr += 2;
! if (linfo.li_version != 2
! && linfo.li_version != 3
! && linfo.li_version != 4)
{
! warn (_("Only DWARF version 2, 3 and 4 line info is currently supported.\n"));
return 0;
}
*************** display_debug_lines_raw (struct dwarf_se
*** 2279,2284 ****
--- 2300,2317 ----
hdrptr += offset_size;
linfo.li_min_insn_length = byte_get (hdrptr, 1);
hdrptr++;
+ if (linfo.li_version >= 4)
+ {
+ linfo.li_max_ops_per_insn = byte_get (hdrptr, 1);
+ hdrptr++;
+ if (linfo.li_max_ops_per_insn == 0)
+ {
+ warn (_("Invalid maximum operations per insn.\n"));
+ return 0;
+ }
+ }
+ else
+ linfo.li_max_ops_per_insn = 1;
linfo.li_default_is_stmt = byte_get (hdrptr, 1);
hdrptr++;
linfo.li_line_base = byte_get (hdrptr, 1);
*************** display_debug_lines_raw (struct dwarf_se
*** 2297,2302 ****
--- 2330,2337 ----
printf (_(" DWARF Version: %d\n"), linfo.li_version);
printf (_(" Prologue Length: %d\n"), linfo.li_prologue_length);
printf (_(" Minimum Instruction Length: %d\n"), linfo.li_min_insn_length);
+ if (linfo.li_version >= 4)
+ printf (_(" Maximum Ops per Instruction: %d\n"), linfo.li_max_ops_per_insn);
printf (_(" Initial value of 'is_stmt': %d\n"), linfo.li_default_is_stmt);
printf (_(" Line Base: %d\n"), linfo.li_line_base);
printf (_(" Line Range: %d\n"), linfo.li_line_range);
*************** display_debug_lines_raw (struct dwarf_se
*** 2380,2389 ****
if (op_code >= linfo.li_opcode_base)
{
op_code -= linfo.li_opcode_base;
! uladv = (op_code / linfo.li_line_range) * linfo.li_min_insn_length;
! state_machine_regs.address += uladv;
! printf (_(" Special opcode %d: advance Address by %lu to 0x%lx"),
! op_code, uladv, state_machine_regs.address);
adv = (op_code % linfo.li_line_range) + linfo.li_line_base;
state_machine_regs.line += adv;
printf (_(" and Line by %d to %d\n"),
--- 2415,2441 ----
if (op_code >= linfo.li_opcode_base)
{
op_code -= linfo.li_opcode_base;
! uladv = (op_code / linfo.li_line_range);
! if (linfo.li_max_ops_per_insn == 1)
! {
! uladv *= linfo.li_min_insn_length;
! state_machine_regs.address += uladv;
! printf (_(" Special opcode %d: advance Address by %lu to 0x%lx"),
! op_code, uladv, state_machine_regs.address);
! }
! else
! {
! state_machine_regs.address
! += ((state_machine_regs.op_index + uladv)
! / linfo.li_max_ops_per_insn)
! * linfo.li_min_insn_length;
! state_machine_regs.op_index
! = (state_machine_regs.op_index + uladv)
! % linfo.li_max_ops_per_insn;
! printf (_(" Special opcode %d: advance Address by %lu to 0x%lx[%d]"),
! op_code, uladv, state_machine_regs.address,
! state_machine_regs.op_index);
! }
adv = (op_code % linfo.li_line_range) + linfo.li_line_base;
state_machine_regs.line += adv;
printf (_(" and Line by %d to %d\n"),
*************** display_debug_lines_raw (struct dwarf_se
*** 2401,2411 ****
case DW_LNS_advance_pc:
uladv = read_leb128 (data, & bytes_read, 0);
- uladv *= linfo.li_min_insn_length;
data += bytes_read;
! state_machine_regs.address += uladv;
! printf (_(" Advance PC by %lu to 0x%lx\n"), uladv,
! state_machine_regs.address);
break;
case DW_LNS_advance_line:
--- 2453,2479 ----
case DW_LNS_advance_pc:
uladv = read_leb128 (data, & bytes_read, 0);
data += bytes_read;
! if (linfo.li_max_ops_per_insn == 1)
! {
! uladv *= linfo.li_min_insn_length;
! state_machine_regs.address += uladv;
! printf (_(" Advance PC by %lu to 0x%lx\n"), uladv,
! state_machine_regs.address);
! }
! else
! {
! state_machine_regs.address
! += ((state_machine_regs.op_index + uladv)
! / linfo.li_max_ops_per_insn)
! * linfo.li_min_insn_length;
! state_machine_regs.op_index
! = (state_machine_regs.op_index + uladv)
! % linfo.li_max_ops_per_insn;
! printf (_(" Advance PC by %lu to 0x%lx[%d]\n"), uladv,
! state_machine_regs.address,
! state_machine_regs.op_index);
! }
break;
case DW_LNS_advance_line:
*************** display_debug_lines_raw (struct dwarf_se
*** 2444,2460 ****
break;
case DW_LNS_const_add_pc:
! uladv = (((255 - linfo.li_opcode_base) / linfo.li_line_range)
! * linfo.li_min_insn_length);
! state_machine_regs.address += uladv;
! printf (_(" Advance PC by constant %lu to 0x%lx\n"), uladv,
! state_machine_regs.address);
break;
case DW_LNS_fixed_advance_pc:
uladv = byte_get (data, 2);
data += 2;
state_machine_regs.address += uladv;
printf (_(" Advance PC by fixed size amount %lu to 0x%lx\n"),
uladv, state_machine_regs.address);
break;
--- 2512,2545 ----
break;
case DW_LNS_const_add_pc:
! uladv = ((255 - linfo.li_opcode_base) / linfo.li_line_range);
! if (linfo.li_max_ops_per_insn)
! {
! uladv *= linfo.li_min_insn_length;
! state_machine_regs.address += uladv;
! printf (_(" Advance PC by constant %lu to 0x%lx\n"), uladv,
! state_machine_regs.address);
! }
! else
! {
! state_machine_regs.address
! += ((state_machine_regs.op_index + uladv)
! / linfo.li_max_ops_per_insn)
! * linfo.li_min_insn_length;
! state_machine_regs.op_index
! = (state_machine_regs.op_index + uladv)
! % linfo.li_max_ops_per_insn;
! printf (_(" Advance PC by constant %lu to 0x%lx[%d]\n"),
! uladv, state_machine_regs.address,
! state_machine_regs.op_index);
! }
break;
case DW_LNS_fixed_advance_pc:
uladv = byte_get (data, 2);
data += 2;
state_machine_regs.address += uladv;
+ state_machine_regs.op_index = 0;
printf (_(" Advance PC by fixed size amount %lu to 0x%lx\n"),
uladv, state_machine_regs.address);
break;
*************** display_debug_lines_decoded (struct dwar
*** 2557,2565 ****
/* Get this CU's Line Number Block version number. */
linfo.li_version = byte_get (hdrptr, 2);
hdrptr += 2;
! if (linfo.li_version != 2 && linfo.li_version != 3)
{
! warn (_("Only DWARF version 2 and 3 line info is currently "
"supported.\n"));
return 0;
}
--- 2642,2652 ----
/* Get this CU's Line Number Block version number. */
linfo.li_version = byte_get (hdrptr, 2);
hdrptr += 2;
! if (linfo.li_version != 2
! && linfo.li_version != 3
! && linfo.li_version != 4)
{
! warn (_("Only DWARF version 2, 3 and 4 line info is currently "
"supported.\n"));
return 0;
}
*************** display_debug_lines_decoded (struct dwar
*** 2568,2573 ****
--- 2655,2672 ----
hdrptr += offset_size;
linfo.li_min_insn_length = byte_get (hdrptr, 1);
hdrptr++;
+ if (linfo.li_version >= 4)
+ {
+ linfo.li_max_ops_per_insn = byte_get (hdrptr, 1);
+ hdrptr++;
+ if (linfo.li_max_ops_per_insn == 0)
+ {
+ warn (_("Invalid maximum operations per insn.\n"));
+ return 0;
+ }
+ }
+ else
+ linfo.li_max_ops_per_insn = 1;
linfo.li_default_is_stmt = byte_get (hdrptr, 1);
hdrptr++;
linfo.li_line_base = byte_get (hdrptr, 1);
*************** display_debug_lines_decoded (struct dwar
*** 2703,2710 ****
if (op_code >= linfo.li_opcode_base)
{
op_code -= linfo.li_opcode_base;
! uladv = (op_code / linfo.li_line_range) * linfo.li_min_insn_length;
! state_machine_regs.address += uladv;
adv = (op_code % linfo.li_line_range) + linfo.li_line_base;
state_machine_regs.line += adv;
--- 2802,2823 ----
if (op_code >= linfo.li_opcode_base)
{
op_code -= linfo.li_opcode_base;
! uladv = (op_code / linfo.li_line_range);
! if (linfo.li_max_ops_per_insn == 1)
! {
! uladv *= linfo.li_min_insn_length;
! state_machine_regs.address += uladv;
! }
! else
! {
! state_machine_regs.address
! += ((state_machine_regs.op_index + uladv)
! / linfo.li_max_ops_per_insn)
! * linfo.li_min_insn_length;
! state_machine_regs.op_index
! = (state_machine_regs.op_index + uladv)
! % linfo.li_max_ops_per_insn;
! }
adv = (op_code % linfo.li_line_range) + linfo.li_line_base;
state_machine_regs.line += adv;
*************** display_debug_lines_decoded (struct dwar
*** 2737,2742 ****
--- 2850,2856 ----
case DW_LNE_set_address:
state_machine_regs.address =
byte_get (op_code_data, ext_op_code_len - bytes_read - 1);
+ state_machine_regs.op_index = 0;
break;
case DW_LNE_define_file:
{
*************** display_debug_lines_decoded (struct dwar
*** 2765,2773 ****
case DW_LNS_advance_pc:
uladv = read_leb128 (data, & bytes_read, 0);
- uladv *= linfo.li_min_insn_length;
data += bytes_read;
! state_machine_regs.address += uladv;
break;
case DW_LNS_advance_line:
--- 2879,2900 ----
case DW_LNS_advance_pc:
uladv = read_leb128 (data, & bytes_read, 0);
data += bytes_read;
! if (linfo.li_max_ops_per_insn == 1)
! {
! uladv *= linfo.li_min_insn_length;
! state_machine_regs.address += uladv;
! }
! else
! {
! state_machine_regs.address
! += ((state_machine_regs.op_index + uladv)
! / linfo.li_max_ops_per_insn)
! * linfo.li_min_insn_length;
! state_machine_regs.op_index
! = (state_machine_regs.op_index + uladv)
! % linfo.li_max_ops_per_insn;
! }
break;
case DW_LNS_advance_line:
*************** display_debug_lines_decoded (struct dwar
*** 2812,2826 ****
break;
case DW_LNS_const_add_pc:
! uladv = (((255 - linfo.li_opcode_base) / linfo.li_line_range)
! * linfo.li_min_insn_length);
! state_machine_regs.address += uladv;
break;
case DW_LNS_fixed_advance_pc:
uladv = byte_get (data, 2);
data += 2;
state_machine_regs.address += uladv;
break;
case DW_LNS_set_prologue_end:
--- 2939,2967 ----
break;
case DW_LNS_const_add_pc:
! uladv = ((255 - linfo.li_opcode_base) / linfo.li_line_range);
! if (linfo.li_max_ops_per_insn == 1)
! {
! uladv *= linfo.li_min_insn_length;
! state_machine_regs.address += uladv;
! }
! else
! {
! state_machine_regs.address
! += ((state_machine_regs.op_index + uladv)
! / linfo.li_max_ops_per_insn)
! * linfo.li_min_insn_length;
! state_machine_regs.op_index
! = (state_machine_regs.op_index + uladv)
! % linfo.li_max_ops_per_insn;
! }
break;
case DW_LNS_fixed_advance_pc:
uladv = byte_get (data, 2);
data += 2;
state_machine_regs.address += uladv;
+ state_machine_regs.op_index = 0;
break;
case DW_LNS_set_prologue_end:
*************** display_debug_lines_decoded (struct dwar
*** 2874,2886 ****
if (!do_wide || (fileNameLength <= MAX_FILENAME_LENGTH))
{
! printf (_("%-35s %11d %#18lx\n"), newFileName,
! state_machine_regs.line, state_machine_regs.address);
}
else
{
! printf (_("%s %11d %#18lx\n"), newFileName,
! state_machine_regs.line, state_machine_regs.address);
}
if (op_code == DW_LNE_end_sequence)
--- 3015,3041 ----
if (!do_wide || (fileNameLength <= MAX_FILENAME_LENGTH))
{
! if (linfo.li_max_ops_per_insn == 1)
! printf (_("%-35s %11d %#18lx\n"), newFileName,
! state_machine_regs.line,
! state_machine_regs.address);
! else
! printf (_("%-35s %11d %#18lx[%d]\n"), newFileName,
! state_machine_regs.line,
! state_machine_regs.address,
! state_machine_regs.op_index);
}
else
{
! if (linfo.li_max_ops_per_insn == 1)
! printf (_("%s %11d %#18lx\n"), newFileName,
! state_machine_regs.line,
! state_machine_regs.address);
! else
! printf (_("%s %11d %#18lx[%d]\n"), newFileName,
! state_machine_regs.line,
! state_machine_regs.address,
! state_machine_regs.op_index);
}
if (op_code == DW_LNE_end_sequence)
*************** typedef struct Frame_Chunk
*** 3751,3756 ****
--- 3906,3913 ----
int ra;
unsigned char fde_encoding;
unsigned char cfa_exp;
+ unsigned char ptr_size;
+ unsigned char segment_size;
}
Frame_Chunk;
*************** display_debug_frames (struct dwarf_secti
*** 3959,3964 ****
--- 4116,4122 ----
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);
*************** display_debug_frames (struct dwarf_secti
*** 3973,3979 ****
int need_col_headers = 1;
unsigned char *augmentation_data = NULL;
unsigned long augmentation_data_len = 0;
! int encoded_ptr_size = eh_addr_size;
int offset_size;
int initial_length_size;
--- 4131,4137 ----
int need_col_headers = 1;
unsigned char *augmentation_data = NULL;
unsigned long augmentation_data_len = 0;
! int encoded_ptr_size = saved_eh_addr_size;
int offset_size;
int initial_length_size;
*************** display_debug_frames (struct dwarf_secti
*** 4029,4076 ****
fc->augmentation = (char *) start;
start = (unsigned char *) strchr ((char *) start, '\0') + 1;
! if (fc->augmentation[0] == 'z')
{
! 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 ();
! }
}
else
{
! fc->code_factor = LEB ();
! fc->data_factor = SLEB ();
! if (version == 1)
! {
! fc->ra = GET (1);
! }
! else
! {
! fc->ra = LEB ();
! }
}
cie = fc;
--- 4187,4222 ----
fc->augmentation = (char *) start;
start = (unsigned char *) strchr ((char *) start, '\0') + 1;
! if (strcmp (fc->augmentation, "eh") == 0)
! start += eh_addr_size;
!
! if (version >= 4)
{
! fc->ptr_size = GET (1);
! fc->segment_size = GET (1);
! eh_addr_size = fc->ptr_size;
}
! else
{
! 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;
*************** display_debug_frames (struct dwarf_secti
*** 4085,4090 ****
--- 4231,4241 ----
(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);
*************** display_debug_frames (struct dwarf_secti
*** 4131,4136 ****
--- 4282,4288 ----
{
unsigned char *look_for;
static Frame_Chunk fde_fc;
+ unsigned long segment_selector;
fc = & fde_fc;
memset (fc, 0, sizeof (Frame_Chunk));
*************** display_debug_frames (struct dwarf_secti
*** 4152,4157 ****
--- 4304,4311 ----
cie = fc;
fc->augmentation = "";
fc->fde_encoding = 0;
+ fc->ptr_size = eh_addr_size;
+ fc->segment_size = 0;
}
else
{
*************** display_debug_frames (struct dwarf_secti
*** 4161,4166 ****
--- 4315,4323 ----
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;
*************** display_debug_frames (struct dwarf_secti
*** 4173,4178 ****
--- 4330,4341 ----
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);
*************** display_debug_frames (struct dwarf_secti
*** 4187,4196 ****
start += augmentation_data_len;
}
! printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n",
(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);
if (! do_debug_frames_interp && augmentation_data_len)
{
unsigned long i;
--- 4350,4361 ----
start += augmentation_data_len;
}
! 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));
! 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;
*************** display_debug_frames (struct dwarf_secti
*** 4738,4743 ****
--- 4903,4909 ----
frame_display_row (fc, &need_col_headers, &max_regs);
start = block_end;
+ eh_addr_size = saved_eh_addr_size;
}
printf ("\n");
diff -rcp ../binutils-2.20.51.0.7.original/include/ChangeLog ./include/ChangeLog
*** ../binutils-2.20.51.0.7.original/include/ChangeLog 2010-04-08 15:40:37.000000000 +0100
--- ./include/ChangeLog 2010-04-08 15:57:22.000000000 +0100
***************
*** 1,3 ****
--- 1,12 ----
+ 2010-04-08 Nick Clifton <nickc@redhat.com>
+
+ Import these patches from the mainline:
+
+ 2010-04-05 Jakub Jelinek <jakub@redhat.com>
+
+ * dwarf2.h (DWARF2_Internal_LineInfo): Add li_max_ops_per_insn
+ field.
+
2010-03-05 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* elf/common.h (VER_FLG_*): Document.
diff -rcp ../binutils-2.20.51.0.7.original/include/dwarf2.h ./include/dwarf2.h
*** ../binutils-2.20.51.0.7.original/include/dwarf2.h 2010-04-08 15:40:37.000000000 +0100
--- ./include/dwarf2.h 2010-04-08 15:40:46.000000000 +0100
*************** typedef struct
*** 66,71 ****
--- 66,72 ----
unsigned short li_version;
unsigned int li_prologue_length;
unsigned char li_min_insn_length;
+ unsigned char li_max_ops_per_insn;
unsigned char li_default_is_stmt;
int li_line_base;
unsigned char li_line_range;