diff --git a/binutils-2.20.51.0.2-dwarf4.patch b/binutils-2.20.51.0.2-dwarf4.patch new file mode 100644 index 0000000..9ab603e --- /dev/null +++ b/binutils-2.20.51.0.2-dwarf4.patch @@ -0,0 +1,1324 @@ +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; diff --git a/binutils.spec b/binutils.spec index a4b47ed..26bb076 100644 --- a/binutils.spec +++ b/binutils.spec @@ -17,7 +17,7 @@ Summary: A GNU collection of binary utilities Name: %{?cross}binutils%{?_with_debug:-debug} Version: 2.20.51.0.2 -Release: 17%{?dist} +Release: 18%{?dist} License: GPLv3+ Group: Development/Tools URL: http://sources.redhat.com/binutils @@ -39,6 +39,8 @@ Patch13: binutils-2.20.51.0.2-ppc-hidden-plt-relocs.patch Patch14: binutils-2.20.51.0.2-x86-hash-table.patch Patch15: binutils-2.20.51.0.2-copy-osabi.patch Patch16: binutils-2.20.51.0.2-do-not-set-ifunc.patch +Patch17: binutils-2.20.51.0.2-do-not-bind-unique-symbols-locally.patch +Patch18: binutils-2.20.51.0.2-dwarf4.patch %define gold_arches %ix86 x86_64 @@ -147,6 +149,8 @@ libelf instead of BFD. %patch14 -p0 -b .hash-table~ %patch15 -p0 -b .copy-osabi~ %patch16 -p0 -b .no-ifunc~ +%patch17 -p0 -b .no-bind-unique~ +%patch18 -p0 -b .dwarf4~ # We cannot run autotools as there is an exact requirement of autoconf-2.59. @@ -449,6 +453,10 @@ exit 0 %endif # %{isnative} %changelog +* Thu Apr 8 2010 Nick Clifton - 2.20.51.0.2-18 +- Do not allow unique symbols to be bound locally. (PR ld/11434) +- Add support for DWARF4 debug information. + * Thu Mar 4 2010 Nick Clifton - 2.20.51.0.2-17 - Do not set ELFOSABI_LINUX on binaries which just link to IFUNC using DSOs. (BZ 568941)