diff -rcp ../binutils-2.20.51.0.2.original/bfd/ChangeLog ./bfd/ChangeLog *** ../binutils-2.20.51.0.2.original/bfd/ChangeLog 2010-04-08 12:35:44.000000000 +0100 --- ./bfd/ChangeLog 2010-04-08 12:35:59.000000000 +0100 *************** *** 1,3 **** --- 1,31 ---- + 2010-04-08 Nick Clifton + + Import these patches from the mainline: + + 2010-04-05 Jakub Jelinek + + * 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 + + * 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 Import this patch from the mainline: diff -rcp ../binutils-2.20.51.0.2.original/bfd/dwarf2.c ./bfd/dwarf2.c *** ../binutils-2.20.51.0.2.original/bfd/dwarf2.c 2010-04-08 12:35:44.000000000 +0100 --- ./bfd/dwarf2.c 2010-04-08 12:35:59.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 * *** 753,759 **** 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); --- 754,760 ---- 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 * *** 767,772 **** --- 768,780 ---- 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 * *** 805,810 **** --- 813,819 ---- 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 * *** 831,836 **** --- 840,848 ---- 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 * *** 868,873 **** --- 880,886 ---- (*_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 *** 897,903 **** char *filename; unsigned int line; unsigned int column; ! int end_sequence; /* End of (sequential) code sequence. */ }; struct fileinfo --- 910,917 ---- 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 * *** 963,969 **** { return (new_line->address > line->address || (new_line->address == line->address ! && new_line->end_sequence < line->end_sequence)); } --- 977,985 ---- { 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 * *** 975,980 **** --- 991,997 ---- static void 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 *** 985,990 **** --- 1002,1008 ---- /* 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 *** 1015,1020 **** --- 1033,1039 ---- if (table->last_line && table->last_line->address == address + && table->last_line->op_index == op_index && table->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 *** 1225,1230 **** --- 1244,1256 ---- } 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 *** 1233,1238 **** --- 1259,1278 ---- 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 *** 1320,1325 **** --- 1360,1366 ---- { /* 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 *** 1343,1353 **** { /* 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. */ ! add_line_info (table, address, filename, line, column, 0); if (address < low_pc) low_pc = address; if (address > high_pc) --- 1384,1404 ---- { /* 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. */ ! add_line_info (table, address, op_index, filename, ! line, column, 0); if (address < low_pc) low_pc = address; if (address > high_pc) *************** decode_line_info (struct comp_unit *unit *** 1365,1372 **** { case DW_LNE_end_sequence: end_sequence = 1; ! add_line_info (table, address, filename, line, column, ! end_sequence); if (address < low_pc) low_pc = address; if (address > high_pc) --- 1416,1423 ---- { case DW_LNE_end_sequence: end_sequence = 1; ! add_line_info (table, address, op_index, filename, ! line, column, end_sequence); if (address < low_pc) low_pc = address; if (address > high_pc) *************** decode_line_info (struct comp_unit *unit *** 1375,1380 **** --- 1426,1432 ---- 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 *** 1422,1436 **** } break; case DW_LNS_copy: ! add_line_info (table, address, filename, line, column, 0); if (address < low_pc) low_pc = address; if (address > high_pc) 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: --- 1474,1499 ---- } break; case DW_LNS_copy: ! add_line_info (table, address, op_index, ! filename, line, column, 0); if (address < low_pc) low_pc = address; if (address > high_pc) 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 *** 1460,1470 **** 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: --- 1523,1542 ---- 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 *** 1930,1935 **** --- 2002,2008 ---- 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 *** 2031,2039 **** 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; } --- 2104,2112 ---- 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.2.original/bfd/elf-eh-frame.c ./bfd/elf-eh-frame.c *** ../binutils-2.20.51.0.2.original/bfd/elf-eh-frame.c 2010-04-08 12:35:43.000000000 +0100 --- ./bfd/elf-eh-frame.c 2010-04-08 12:35:59.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.2.original/binutils/ChangeLog ./binutils/ChangeLog *** ../binutils-2.20.51.0.2.original/binutils/ChangeLog 2010-04-08 12:35:39.000000000 +0100 --- ./binutils/ChangeLog 2010-04-08 12:37:44.000000000 +0100 *************** *** 1,3 **** --- 1,31 ---- + 2010-04-08 Nick Clifton + + Import these patches from the mainline: + + 2010-04-05 Jakub Jelinek + + * 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 + + * 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. + 2009-10-01 Alan Modra * addr2line.c (slurp_symtab): Don't use bfd_read_minisymbols. diff -rcp ../binutils-2.20.51.0.2.original/binutils/dwarf.c ./binutils/dwarf.c *** ../binutils-2.20.51.0.2.original/binutils/dwarf.c 2010-04-08 12:35:39.000000000 +0100 --- ./binutils/dwarf.c 2010-04-08 12:35:59.000000000 +0100 *************** typedef struct State_Machine_Registers *** 263,269 **** 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; --- 263,270 ---- 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 *** 275,280 **** --- 276,282 ---- 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 *** 321,326 **** --- 323,329 ---- 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 *** 1153,1166 **** 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; --- 1156,1169 ---- 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 *** 1170,1179 **** --- 1173,1187 ---- 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 *** 1232,1241 **** --- 1240,1251 ---- 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 *** 1271,1276 **** --- 1281,1287 ---- 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 *** 1351,1357 **** 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 max = debug_info_p->max_loc_offsets; --- 1362,1370 ---- 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 max = debug_info_p->max_loc_offsets; *************** read_and_display_attr_value (unsigned lo *** 1380,1386 **** break; case DW_AT_ranges: ! if (form == DW_FORM_data4 || form == DW_FORM_data8) { /* Process range list. */ unsigned int max = debug_info_p->max_range_lists; --- 1393,1401 ---- break; case DW_AT_ranges: ! if (form == DW_FORM_data4 ! || form == DW_FORM_data8 ! || form == DW_FORM_sec_offset) { /* Process range list. */ unsigned int max = debug_info_p->max_range_lists; *************** read_and_display_attr_value (unsigned lo *** 1590,1596 **** 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: --- 1605,1613 ---- 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 *** 2035,2041 **** 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); --- 2052,2060 ---- 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 *** 2266,2274 **** /* Check its version number. */ info.li_version = byte_get (hdrptr, 2); hdrptr += 2; ! if (info.li_version != 2 && info.li_version != 3) { ! warn (_("Only DWARF version 2 and 3 line info is currently supported.\n")); return 0; } --- 2285,2295 ---- /* Check its version number. */ info.li_version = byte_get (hdrptr, 2); hdrptr += 2; ! if (info.li_version != 2 ! && info.li_version != 3 ! && info.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 *** 2276,2281 **** --- 2297,2314 ---- hdrptr += offset_size; info.li_min_insn_length = byte_get (hdrptr, 1); hdrptr++; + if (info.li_version >= 4) + { + info.li_max_ops_per_insn = byte_get (hdrptr, 1); + hdrptr++; + if (info.li_max_ops_per_insn == 0) + { + warn (_("Invalid maximum operations per insn.\n")); + return 0; + } + } + else + info.li_max_ops_per_insn = 1; info.li_default_is_stmt = byte_get (hdrptr, 1); hdrptr++; info.li_line_base = byte_get (hdrptr, 1); *************** display_debug_lines_raw (struct dwarf_se *** 2294,2299 **** --- 2327,2334 ---- printf (_(" DWARF Version: %d\n"), info.li_version); printf (_(" Prologue Length: %d\n"), info.li_prologue_length); printf (_(" Minimum Instruction Length: %d\n"), info.li_min_insn_length); + if (info.li_version >= 4) + printf (_(" Maximum Ops per Instruction: %d\n"), info.li_max_ops_per_insn); printf (_(" Initial value of 'is_stmt': %d\n"), info.li_default_is_stmt); printf (_(" Line Base: %d\n"), info.li_line_base); printf (_(" Line Range: %d\n"), info.li_line_range); *************** display_debug_lines_raw (struct dwarf_se *** 2377,2386 **** if (op_code >= info.li_opcode_base) { op_code -= info.li_opcode_base; ! uladv = (op_code / info.li_line_range) * info.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 % info.li_line_range) + info.li_line_base; state_machine_regs.line += adv; printf (_(" and Line by %d to %d\n"), --- 2412,2438 ---- if (op_code >= info.li_opcode_base) { op_code -= info.li_opcode_base; ! uladv = (op_code / info.li_line_range); ! if (info.li_max_ops_per_insn == 1) ! { ! uladv *= info.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) ! / info.li_max_ops_per_insn) ! * info.li_min_insn_length; ! state_machine_regs.op_index ! = (state_machine_regs.op_index + uladv) ! % info.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 % info.li_line_range) + info.li_line_base; state_machine_regs.line += adv; printf (_(" and Line by %d to %d\n"), *************** display_debug_lines_raw (struct dwarf_se *** 2398,2408 **** case DW_LNS_advance_pc: uladv = read_leb128 (data, & bytes_read, 0); - uladv *= info.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: --- 2450,2476 ---- case DW_LNS_advance_pc: uladv = read_leb128 (data, & bytes_read, 0); data += bytes_read; ! if (info.li_max_ops_per_insn == 1) ! { ! uladv *= info.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) ! / info.li_max_ops_per_insn) ! * info.li_min_insn_length; ! state_machine_regs.op_index ! = (state_machine_regs.op_index + uladv) ! % info.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 *** 2441,2457 **** break; case DW_LNS_const_add_pc: ! uladv = (((255 - info.li_opcode_base) / info.li_line_range) ! * info.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; --- 2509,2542 ---- break; case DW_LNS_const_add_pc: ! uladv = ((255 - info.li_opcode_base) / info.li_line_range); ! if (info.li_max_ops_per_insn) ! { ! uladv *= info.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) ! / info.li_max_ops_per_insn) ! * info.li_min_insn_length; ! state_machine_regs.op_index ! = (state_machine_regs.op_index + uladv) ! % info.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 *** 2554,2562 **** /* Get this CU's Line Number Block version number. */ info.li_version = byte_get (hdrptr, 2); hdrptr += 2; ! if (info.li_version != 2 && info.li_version != 3) { ! warn (_("Only DWARF version 2 and 3 line info is currently " "supported.\n")); return 0; } --- 2639,2649 ---- /* Get this CU's Line Number Block version number. */ info.li_version = byte_get (hdrptr, 2); hdrptr += 2; ! if (info.li_version != 2 ! && info.li_version != 3 ! && info.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 *** 2565,2570 **** --- 2652,2669 ---- hdrptr += offset_size; info.li_min_insn_length = byte_get (hdrptr, 1); hdrptr++; + if (info.li_version >= 4) + { + info.li_max_ops_per_insn = byte_get (hdrptr, 1); + hdrptr++; + if (info.li_max_ops_per_insn == 0) + { + warn (_("Invalid maximum operations per insn.\n")); + return 0; + } + } + else + info.li_max_ops_per_insn = 1; info.li_default_is_stmt = byte_get (hdrptr, 1); hdrptr++; info.li_line_base = byte_get (hdrptr, 1); *************** display_debug_lines_decoded (struct dwar *** 2702,2709 **** if (op_code >= info.li_opcode_base) { op_code -= info.li_opcode_base; ! uladv = (op_code / info.li_line_range) * info.li_min_insn_length; ! state_machine_regs.address += uladv; adv = (op_code % info.li_line_range) + info.li_line_base; state_machine_regs.line += adv; --- 2801,2822 ---- if (op_code >= info.li_opcode_base) { op_code -= info.li_opcode_base; ! uladv = (op_code / info.li_line_range); ! if (info.li_max_ops_per_insn == 1) ! { ! uladv *= info.li_min_insn_length; ! state_machine_regs.address += uladv; ! } ! else ! { ! state_machine_regs.address ! += ((state_machine_regs.op_index + uladv) ! / info.li_max_ops_per_insn) ! * info.li_min_insn_length; ! state_machine_regs.op_index ! = (state_machine_regs.op_index + uladv) ! % info.li_max_ops_per_insn; ! } adv = (op_code % info.li_line_range) + info.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 *= info.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 (info.li_max_ops_per_insn == 1) ! { ! uladv *= info.li_min_insn_length; ! state_machine_regs.address += uladv; ! } ! else ! { ! state_machine_regs.address ! += ((state_machine_regs.op_index + uladv) ! / info.li_max_ops_per_insn) ! * info.li_min_insn_length; ! state_machine_regs.op_index ! = (state_machine_regs.op_index + uladv) ! % info.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 - info.li_opcode_base) / info.li_line_range) ! * info.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 - info.li_opcode_base) / info.li_line_range); ! if (info.li_max_ops_per_insn == 1) ! { ! uladv *= info.li_min_insn_length; ! state_machine_regs.address += uladv; ! } ! else ! { ! state_machine_regs.address ! += ((state_machine_regs.op_index + uladv) ! / info.li_max_ops_per_insn) ! * info.li_min_insn_length; ! state_machine_regs.op_index ! = (state_machine_regs.op_index + uladv) ! % info.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 (info.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 (info.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 *** 4129,4134 **** --- 4280,4286 ---- { 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 *** 4150,4155 **** --- 4302,4309 ---- 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 *** 4159,4164 **** --- 4313,4321 ---- 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 *** 4171,4176 **** --- 4328,4339 ---- 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 *** 4185,4194 **** 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; --- 4348,4359 ---- 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 *** 4736,4741 **** --- 4901,4907 ---- 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.2.original/include/ChangeLog ./include/ChangeLog *** ../binutils-2.20.51.0.2.original/include/ChangeLog 2010-04-08 12:35:39.000000000 +0100 --- ./include/ChangeLog 2010-04-08 12:37:27.000000000 +0100 *************** *** 1,3 **** --- 1,12 ---- + 2010-04-08 Nick Clifton + + Import these patches from the mainline: + + 2010-04-05 Jakub Jelinek + + * dwarf2.h (DWARF2_Internal_LineInfo): Add li_max_ops_per_insn + field. + 2008-10-03 Rafael Espindola * plugin-api.h: New. diff -rcp ../binutils-2.20.51.0.2.original/include/dwarf2.h ./include/dwarf2.h *** ../binutils-2.20.51.0.2.original/include/dwarf2.h 2010-04-08 12:35:38.000000000 +0100 --- ./include/dwarf2.h 2010-04-08 12:35:59.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;