From 9b8d1a36034b5bdf665b952f581d96a987faecdf Mon Sep 17 00:00:00 2001 From: Cary Coutant Date: Tue, 24 Jul 2012 21:06:58 +0000 Subject: [PATCH] 2012-07-24 Teresa Johnson bfd/ * bfd.c (bfd_find_nearest_line_discriminator): New macro. * coff-rs6000.c: Init _bfd_find_nearest_line_discriminator. * coff64-rs6000.c: Likewise. * dwarf2.c (struct line_info): Add discriminator field. (add_line_info): Fill in new discriminator field. (decode_line_info): Record discriminator information instead of ignoring it. (lookup_address_in_line_info_table): Return discriminator field if requested. (comp_unit_find_nearest_line): Add discriminator argument. (find_line): Likewise. (_bfd_dwarf2_find_nearest_line): Likewise. (_bfd_dwarf2_find_line): Likewise. * elf-bfd.h (_bfd_elf_find_nearest_line_discriminator): New. (_bfd_elf_find_line_discriminator): Likewise. (_bfd_generic_find_nearest_line_discriminator): Likewise. Defined. * elf.c (_bfd_elf_find_nearest_line): Change to a wrapper that invokes _bfd_elf_find_nearest_line_discriminator with correct arguments. (_bfd_elf_find_nearest_line_discriminator): New. (_bfd_elf_find_line): Change to a wrapper that invokes _bfd_elf_find_line_discriminator with correct arguments. (_bfd_elf_find_line_discriminator): New. * coffgen.c (coff_find_nearest_line_with_names): Handle new discriminator argument. * elf32-arm.c (elf32_arm_find_nearest_line): Likewise. * elf64-alpha.c (elf64_alpha_find_nearest_line): Likewise. * elfxx-mips.c (_bfd_mips_elf_find_nearest_line): Likewise. * mach-o.c (bfd_mach_o_find_nearest_line): Likewise. * libbfd-in.h (_bfd_dwarf2_find_nearest_line): Add discriminator argument. (_bfd_dwarf2_find_line): Likewise. (_bfd_generic_find_nearest_line_discriminator): New. * libbfd.c (_bfd_generic_find_nearest_line_discriminator): New. * bfd-in2.h: Regenerated. * libbfd.h: Likewise. * targets.c (BFD_JUMP_TABLE_SYMBOLS): Initialize _bfd_find_nearest_line_discriminator with _bfd_generic_find_nearest_line_discriminator. (bfd_target): Add _bfd_find_nearest_line_discriminator. binutils/ * addr2line.c (find_address_in_section): Invoke bfd_find_nearest_line_discriminator to get the discriminator. (find_offset_in_section): Likewise. (translate_addresses): Print discriminator if it is non-zero. * objdump.c (show_line): Invoke bfd_find_nearest_line_discriminator to get the discriminator, and keep track of prev_discriminator. Print discriminator if it is non-zero. (disassemble_data): Initialize prev_discriminator. (dump_reloc_set): Invoke bfd_find_nearest_line_discriminator to get the discriminator, and keep track of last_discriminator. Print discriminator if it is non-zero. --- bfd/ChangeLog | 44 ++++++++++++++++++++++++++++++++++++++++++++ bfd/bfd-in2.h | 9 +++++++++ bfd/bfd.c | 5 +++++ bfd/coff-rs6000.c | 2 ++ bfd/coff64-rs6000.c | 2 ++ bfd/coffgen.c | 2 +- bfd/dwarf2.c | 39 +++++++++++++++++++++++++++++---------- bfd/elf-bfd.h | 7 +++++++ bfd/elf.c | 32 ++++++++++++++++++++++++++++++-- bfd/elf32-arm.c | 2 +- bfd/elf64-alpha.c | 2 +- bfd/elfxx-mips.c | 2 +- bfd/libbfd-in.h | 9 +++++++-- bfd/libbfd.c | 13 +++++++++++++ bfd/libbfd.h | 9 +++++++-- bfd/mach-o.c | 2 +- bfd/targets.c | 4 ++++ binutils/ChangeLog | 15 +++++++++++++++ binutils/addr2line.c | 18 +++++++++++++----- binutils/objdump.c | 40 ++++++++++++++++++++++++++++++++-------- 20 files changed, 224 insertions(+), 34 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 76665c3cb7..b958889421 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,47 @@ +2012-07-24 Teresa Johnson + + * bfd.c (bfd_find_nearest_line_discriminator): New macro. + * coff-rs6000.c: Init _bfd_find_nearest_line_discriminator. + * coff64-rs6000.c: Likewise. + * dwarf2.c (struct line_info): Add discriminator field. + (add_line_info): Fill in new discriminator field. + (decode_line_info): Record discriminator information instead + of ignoring it. + (lookup_address_in_line_info_table): Return discriminator field if + requested. + (comp_unit_find_nearest_line): Add discriminator argument. + (find_line): Likewise. + (_bfd_dwarf2_find_nearest_line): Likewise. + (_bfd_dwarf2_find_line): Likewise. + * elf-bfd.h (_bfd_elf_find_nearest_line_discriminator): New. + (_bfd_elf_find_line_discriminator): Likewise. + (_bfd_generic_find_nearest_line_discriminator): Likewise. Defined. + * elf.c (_bfd_elf_find_nearest_line): Change to a wrapper + that invokes _bfd_elf_find_nearest_line_discriminator with correct + arguments. + (_bfd_elf_find_nearest_line_discriminator): New. + (_bfd_elf_find_line): Change to a wrapper + that invokes _bfd_elf_find_line_discriminator with correct + arguments. + (_bfd_elf_find_line_discriminator): New. + * coffgen.c (coff_find_nearest_line_with_names): Handle + new discriminator argument. + * elf32-arm.c (elf32_arm_find_nearest_line): Likewise. + * elf64-alpha.c (elf64_alpha_find_nearest_line): Likewise. + * elfxx-mips.c (_bfd_mips_elf_find_nearest_line): Likewise. + * mach-o.c (bfd_mach_o_find_nearest_line): Likewise. + * libbfd-in.h (_bfd_dwarf2_find_nearest_line): Add discriminator + argument. + (_bfd_dwarf2_find_line): Likewise. + (_bfd_generic_find_nearest_line_discriminator): New. + * libbfd.c (_bfd_generic_find_nearest_line_discriminator): New. + * bfd-in2.h: Regenerated. + * libbfd.h: Likewise. + * targets.c (BFD_JUMP_TABLE_SYMBOLS): Initialize + _bfd_find_nearest_line_discriminator with + _bfd_generic_find_nearest_line_discriminator. + (bfd_target): Add _bfd_find_nearest_line_discriminator. + 2012-07-24 Sean Keys * elf32-m68hc1x.c (elf32_m68hc11_relocate_section): Added code diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 7a90a44390..c7ce4cc67a 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -5810,6 +5810,11 @@ bfd_boolean bfd_set_private_flags (bfd *abfd, flagword flags); BFD_SEND (abfd, _bfd_find_nearest_line, \ (abfd, sec, syms, off, file, func, line)) +#define bfd_find_nearest_line_discriminator(abfd, sec, syms, off, file, func, \ + line, disc) \ + BFD_SEND (abfd, _bfd_find_nearest_line_discriminator, \ + (abfd, sec, syms, off, file, func, line, disc)) + #define bfd_find_line(abfd, syms, sym, file, line) \ BFD_SEND (abfd, _bfd_find_line, \ (abfd, syms, sym, file, line)) @@ -6191,6 +6196,7 @@ typedef struct bfd_target NAME##_bfd_is_target_special_symbol, \ NAME##_get_lineno, \ NAME##_find_nearest_line, \ + _bfd_generic_find_nearest_line_discriminator, \ _bfd_generic_find_line, \ NAME##_find_inliner_info, \ NAME##_bfd_make_debug_symbol, \ @@ -6214,6 +6220,9 @@ typedef struct bfd_target bfd_boolean (*_bfd_find_nearest_line) (bfd *, struct bfd_section *, struct bfd_symbol **, bfd_vma, const char **, const char **, unsigned int *); + bfd_boolean (*_bfd_find_nearest_line_discriminator) + (bfd *, struct bfd_section *, struct bfd_symbol **, bfd_vma, + const char **, const char **, unsigned int *, unsigned int *); bfd_boolean (*_bfd_find_line) (bfd *, struct bfd_symbol **, struct bfd_symbol *, const char **, unsigned int *); diff --git a/bfd/bfd.c b/bfd/bfd.c index 640b4205d1..eed1896085 100644 --- a/bfd/bfd.c +++ b/bfd/bfd.c @@ -1424,6 +1424,11 @@ DESCRIPTION . BFD_SEND (abfd, _bfd_find_nearest_line, \ . (abfd, sec, syms, off, file, func, line)) . +.#define bfd_find_nearest_line_discriminator(abfd, sec, syms, off, file, func, \ +. line, disc) \ +. BFD_SEND (abfd, _bfd_find_nearest_line_discriminator, \ +. (abfd, sec, syms, off, file, func, line, disc)) +. .#define bfd_find_line(abfd, syms, sym, file, line) \ . BFD_SEND (abfd, _bfd_find_line, \ . (abfd, syms, sym, file, line)) diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c index 2a968bfc03..9326b32bd1 100644 --- a/bfd/coff-rs6000.c +++ b/bfd/coff-rs6000.c @@ -4118,6 +4118,7 @@ const bfd_target rs6000coff_vec = coff_bfd_is_target_special_symbol, coff_get_lineno, xcoff_find_nearest_line, + _bfd_generic_find_nearest_line_discriminator, _bfd_generic_find_line, coff_find_inliner_info, coff_bfd_make_debug_symbol, @@ -4373,6 +4374,7 @@ const bfd_target pmac_xcoff_vec = coff_bfd_is_target_special_symbol, coff_get_lineno, xcoff_find_nearest_line, + _bfd_generic_find_nearest_line_discriminator, _bfd_generic_find_line, coff_find_inliner_info, coff_bfd_make_debug_symbol, diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c index 031385deee..0821b6ff17 100644 --- a/bfd/coff64-rs6000.c +++ b/bfd/coff64-rs6000.c @@ -2710,6 +2710,7 @@ const bfd_target rs6000coff64_vec = coff_bfd_is_target_special_symbol, coff_get_lineno, coff_find_nearest_line, + _bfd_generic_find_nearest_line_discriminator, _bfd_generic_find_line, coff_find_inliner_info, coff_bfd_make_debug_symbol, @@ -2967,6 +2968,7 @@ const bfd_target aix5coff64_vec = coff_bfd_is_target_special_symbol, coff_get_lineno, coff_find_nearest_line, + _bfd_generic_find_nearest_line_discriminator, _bfd_generic_find_line, coff_find_inliner_info, coff_bfd_make_debug_symbol, diff --git a/bfd/coffgen.c b/bfd/coffgen.c index c0505c6c02..509119b075 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -2153,7 +2153,7 @@ coff_find_nearest_line_with_names (bfd *abfd, if (_bfd_dwarf2_find_nearest_line (abfd, debug_sections, section, symbols, offset, filename_ptr, functionname_ptr, - line_ptr, 0, + line_ptr, NULL, 0, &coff_data(abfd)->dwarf2_find_line_info)) return TRUE; diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c index d31b84939a..069d6141a7 100644 --- a/bfd/dwarf2.c +++ b/bfd/dwarf2.c @@ -980,6 +980,7 @@ struct line_info char *filename; unsigned int line; unsigned int column; + unsigned int discriminator; unsigned char op_index; unsigned char end_sequence; /* End of (sequential) code sequence. */ }; @@ -1080,6 +1081,7 @@ add_line_info (struct line_info_table *table, char *filename, unsigned int line, unsigned int column, + unsigned int discriminator, int end_sequence) { bfd_size_type amt = sizeof (struct line_info); @@ -1095,6 +1097,7 @@ add_line_info (struct line_info_table *table, info->op_index = op_index; info->line = line; info->column = column; + info->discriminator = discriminator; info->end_sequence = end_sequence; if (filename && filename[0]) @@ -1573,6 +1576,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash) char * filename = table->num_files ? concat_filename (table, 1) : NULL; unsigned int line = 1; unsigned int column = 0; + unsigned int discriminator = 0; int is_stmt = lh.default_is_stmt; int end_sequence = 0; /* eraxxon@alumni.rice.edu: Against the DWARF2 specs, some @@ -1607,8 +1611,9 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash) 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)) + line, column, discriminator, 0)) goto line_fail; + discriminator = 0; if (address < low_pc) low_pc = address; if (address > high_pc) @@ -1626,9 +1631,10 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash) { case DW_LNE_end_sequence: end_sequence = 1; - if (!add_line_info (table, address, op_index, filename, - line, column, end_sequence)) + if (!add_line_info (table, address, op_index, filename, line, + column, discriminator, end_sequence)) goto line_fail; + discriminator = 0; if (address < low_pc) low_pc = address; if (address > high_pc) @@ -1668,7 +1674,8 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash) table->num_files++; break; case DW_LNE_set_discriminator: - (void) read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + discriminator = + read_unsigned_leb128 (abfd, line_ptr, &bytes_read); line_ptr += bytes_read; break; case DW_LNE_HP_source_file_correlation: @@ -1686,8 +1693,9 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash) break; case DW_LNS_copy: if (!add_line_info (table, address, op_index, - filename, line, column, 0)) + filename, line, column, discriminator, 0)) goto line_fail; + discriminator = 0; if (address < low_pc) low_pc = address; if (address > high_pc) @@ -1788,7 +1796,8 @@ static bfd_boolean lookup_address_in_line_info_table (struct line_info_table *table, bfd_vma addr, const char **filename_ptr, - unsigned int *linenumber_ptr) + unsigned int *linenumber_ptr, + unsigned int *discriminator_ptr) { struct line_sequence *seq = NULL; struct line_info *each_line; @@ -1823,6 +1832,8 @@ lookup_address_in_line_info_table (struct line_info_table *table, { *filename_ptr = each_line->filename; *linenumber_ptr = each_line->line; + if (discriminator_ptr) + *discriminator_ptr = each_line->discriminator; return TRUE; } } @@ -2552,6 +2563,7 @@ comp_unit_find_nearest_line (struct comp_unit *unit, const char **filename_ptr, const char **functionname_ptr, unsigned int *linenumber_ptr, + unsigned int *discriminator_ptr, struct dwarf2_debug *stash) { bfd_boolean line_p; @@ -2592,7 +2604,8 @@ comp_unit_find_nearest_line (struct comp_unit *unit, stash->inliner_chain = function; line_p = lookup_address_in_line_info_table (unit->line_table, addr, filename_ptr, - linenumber_ptr); + linenumber_ptr, + discriminator_ptr); return line_p || func_p; } @@ -3308,6 +3321,7 @@ find_line (bfd *abfd, const char **filename_ptr, const char **functionname_ptr, unsigned int *linenumber_ptr, + unsigned int *discriminator_ptr, unsigned int addr_size, void **pinfo) { @@ -3419,6 +3433,7 @@ find_line (bfd *abfd, filename_ptr, functionname_ptr, linenumber_ptr, + discriminator_ptr, stash)); if (found) goto done; @@ -3512,6 +3527,7 @@ find_line (bfd *abfd, filename_ptr, functionname_ptr, linenumber_ptr, + discriminator_ptr, stash)); if ((bfd_vma) (stash->info_ptr - stash->sec_info_ptr) @@ -3546,12 +3562,13 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd, const char **filename_ptr, const char **functionname_ptr, unsigned int *linenumber_ptr, + unsigned int *discriminator_ptr, unsigned int addr_size, void **pinfo) { return find_line (abfd, debug_sections, section, offset, NULL, symbols, - filename_ptr, functionname_ptr, linenumber_ptr, addr_size, - pinfo); + filename_ptr, functionname_ptr, linenumber_ptr, + discriminator_ptr, addr_size, pinfo); } /* The DWARF2 version of find_line. @@ -3563,11 +3580,13 @@ _bfd_dwarf2_find_line (bfd *abfd, asymbol *symbol, const char **filename_ptr, unsigned int *linenumber_ptr, + unsigned int *discriminator_ptr, unsigned int addr_size, void **pinfo) { return find_line (abfd, dwarf_debug_sections, NULL, 0, symbol, symbols, - filename_ptr, NULL, linenumber_ptr, addr_size, pinfo); + filename_ptr, NULL, linenumber_ptr, discriminator_ptr, + addr_size, pinfo); } bfd_boolean diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 889ce128b4..ff0e615cfd 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1876,9 +1876,16 @@ extern bfd_boolean _bfd_elf_set_arch_mach extern bfd_boolean _bfd_elf_find_nearest_line (bfd *, asection *, asymbol **, bfd_vma, const char **, const char **, unsigned int *); +extern bfd_boolean _bfd_elf_find_nearest_line_discriminator + (bfd *, asection *, asymbol **, bfd_vma, const char **, const char **, + unsigned int *, unsigned int *); extern bfd_boolean _bfd_elf_find_line (bfd *, asymbol **, asymbol *, const char **, unsigned int *); +extern bfd_boolean _bfd_elf_find_line_discriminator + (bfd *, asymbol **, asymbol *, const char **, unsigned int *, unsigned int *); #define _bfd_generic_find_line _bfd_elf_find_line +#define _bfd_generic_find_nearest_line_discriminator \ + _bfd_elf_find_nearest_line_discriminator extern bfd_boolean _bfd_elf_find_inliner_info (bfd *, const char **, const char **, unsigned int *); #define _bfd_elf_read_minisymbols _bfd_generic_read_minisymbols diff --git a/bfd/elf.c b/bfd/elf.c index 48e5d68341..0ac4032b69 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -7566,6 +7566,23 @@ _bfd_elf_find_nearest_line (bfd *abfd, const char **filename_ptr, const char **functionname_ptr, unsigned int *line_ptr) +{ + return _bfd_elf_find_nearest_line_discriminator (abfd, section, symbols, + offset, filename_ptr, + functionname_ptr, + line_ptr, + NULL); +} + +bfd_boolean +_bfd_elf_find_nearest_line_discriminator (bfd *abfd, + asection *section, + asymbol **symbols, + bfd_vma offset, + const char **filename_ptr, + const char **functionname_ptr, + unsigned int *line_ptr, + unsigned int *discriminator_ptr) { bfd_boolean found; @@ -7584,7 +7601,7 @@ _bfd_elf_find_nearest_line (bfd *abfd, if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections, section, symbols, offset, filename_ptr, functionname_ptr, - line_ptr, 0, + line_ptr, discriminator_ptr, 0, &elf_tdata (abfd)->dwarf2_find_line_info)) { if (!*functionname_ptr) @@ -7619,9 +7636,20 @@ _bfd_elf_find_nearest_line (bfd *abfd, bfd_boolean _bfd_elf_find_line (bfd *abfd, asymbol **symbols, asymbol *symbol, const char **filename_ptr, unsigned int *line_ptr) +{ + return _bfd_elf_find_line_discriminator (abfd, symbols, symbol, + filename_ptr, line_ptr, + NULL); +} + +bfd_boolean +_bfd_elf_find_line_discriminator (bfd *abfd, asymbol **symbols, asymbol *symbol, + const char **filename_ptr, + unsigned int *line_ptr, + unsigned int *discriminator_ptr) { return _bfd_dwarf2_find_line (abfd, symbols, symbol, - filename_ptr, line_ptr, 0, + filename_ptr, line_ptr, discriminator_ptr, 0, &elf_tdata (abfd)->dwarf2_find_line_info); } diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index bc1f19532c..1bbd96ce9e 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -12886,7 +12886,7 @@ elf32_arm_find_nearest_line (bfd * abfd, if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections, section, symbols, offset, filename_ptr, functionname_ptr, - line_ptr, 0, + line_ptr, NULL, 0, & elf_tdata (abfd)->dwarf2_find_line_info)) { if (!*functionname_ptr) diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c index 40e4bfb318..deb03c183c 100644 --- a/bfd/elf64-alpha.c +++ b/bfd/elf64-alpha.c @@ -1452,7 +1452,7 @@ elf64_alpha_find_nearest_line (bfd *abfd, asection *section, asymbol **symbols, if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections, section, symbols, offset, filename_ptr, functionname_ptr, - line_ptr, 0, + line_ptr, NULL, 0, &elf_tdata (abfd)->dwarf2_find_line_info)) return TRUE; diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 9478f16380..9fef8efe46 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -11709,7 +11709,7 @@ _bfd_mips_elf_find_nearest_line (bfd *abfd, asection *section, if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections, section, symbols, offset, filename_ptr, functionname_ptr, - line_ptr, ABI_64_P (abfd) ? 8 : 0, + line_ptr, NULL, ABI_64_P (abfd) ? 8 : 0, &elf_tdata (abfd)->dwarf2_find_line_info)) return TRUE; diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h index baffaea1ba..c424fe2510 100644 --- a/bfd/libbfd-in.h +++ b/bfd/libbfd-in.h @@ -540,16 +540,21 @@ extern const struct dwarf_debug_section dwarf_debug_sections[]; /* Find the nearest line using DWARF 2 debugging information. */ extern bfd_boolean _bfd_dwarf2_find_nearest_line (bfd *, const struct dwarf_debug_section *, asection *, asymbol **, bfd_vma, - const char **, const char **, unsigned int *, unsigned int, void **); + const char **, const char **, unsigned int *, unsigned int *, unsigned int, + void **); /* Find the line using DWARF 2 debugging information. */ extern bfd_boolean _bfd_dwarf2_find_line (bfd *, asymbol **, asymbol *, const char **, - unsigned int *, unsigned int, void **); + unsigned int *, unsigned int *, unsigned int, void **); bfd_boolean _bfd_generic_find_line (bfd *, asymbol **, asymbol *, const char **, unsigned int *); +bfd_boolean _bfd_generic_find_nearest_line_discriminator + (bfd *, asection *, asymbol **, bfd_vma, const char **, const char **, + unsigned int *, unsigned int *); + /* Find inliner info after calling bfd_find_nearest_line. */ extern bfd_boolean _bfd_dwarf2_find_inliner_info (bfd *, const char **, const char **, unsigned int *, void **); diff --git a/bfd/libbfd.c b/bfd/libbfd.c index 44651cf9c3..553c729562 100644 --- a/bfd/libbfd.c +++ b/bfd/libbfd.c @@ -1117,6 +1117,19 @@ _bfd_generic_find_line (bfd *abfd ATTRIBUTE_UNUSED, return FALSE; } +bfd_boolean +_bfd_generic_find_nearest_line_discriminator (bfd *abfd ATTRIBUTE_UNUSED, + asection *section ATTRIBUTE_UNUSED, + asymbol **symbols ATTRIBUTE_UNUSED, + bfd_vma offset ATTRIBUTE_UNUSED, + const char **filename_ptr ATTRIBUTE_UNUSED, + const char **functionname_ptr ATTRIBUTE_UNUSED, + unsigned int *line_ptr ATTRIBUTE_UNUSED, + unsigned int *discriminator_ptr ATTRIBUTE_UNUSED) +{ + return FALSE; +} + bfd_boolean _bfd_generic_init_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED, asection *isec ATTRIBUTE_UNUSED, diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 1d95fd8352..e74ce34ad4 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -545,16 +545,21 @@ extern const struct dwarf_debug_section dwarf_debug_sections[]; /* Find the nearest line using DWARF 2 debugging information. */ extern bfd_boolean _bfd_dwarf2_find_nearest_line (bfd *, const struct dwarf_debug_section *, asection *, asymbol **, bfd_vma, - const char **, const char **, unsigned int *, unsigned int, void **); + const char **, const char **, unsigned int *, unsigned int *, unsigned int, + void **); /* Find the line using DWARF 2 debugging information. */ extern bfd_boolean _bfd_dwarf2_find_line (bfd *, asymbol **, asymbol *, const char **, - unsigned int *, unsigned int, void **); + unsigned int *, unsigned int *, unsigned int, void **); bfd_boolean _bfd_generic_find_line (bfd *, asymbol **, asymbol *, const char **, unsigned int *); +bfd_boolean _bfd_generic_find_nearest_line_discriminator + (bfd *, asection *, asymbol **, bfd_vma, const char **, const char **, + unsigned int *, unsigned int *); + /* Find inliner info after calling bfd_find_nearest_line. */ extern bfd_boolean _bfd_dwarf2_find_inliner_info (bfd *, const char **, const char **, unsigned int *, void **); diff --git a/bfd/mach-o.c b/bfd/mach-o.c index 1f9fc17608..84d5a72960 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -4836,7 +4836,7 @@ bfd_mach_o_find_nearest_line (bfd *abfd, if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections, section, symbols, offset, filename_ptr, functionname_ptr, - line_ptr, 0, + line_ptr, NULL, 0, &mdata->dwarf2_find_line_info)) return TRUE; return FALSE; diff --git a/bfd/targets.c b/bfd/targets.c index cfa91a8fb8..ce1cf350f4 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -369,6 +369,7 @@ BFD_JUMP_TABLE macros. . NAME##_bfd_is_target_special_symbol, \ . NAME##_get_lineno, \ . NAME##_find_nearest_line, \ +. _bfd_generic_find_nearest_line_discriminator, \ . _bfd_generic_find_line, \ . NAME##_find_inliner_info, \ . NAME##_bfd_make_debug_symbol, \ @@ -392,6 +393,9 @@ BFD_JUMP_TABLE macros. . bfd_boolean (*_bfd_find_nearest_line) . (bfd *, struct bfd_section *, struct bfd_symbol **, bfd_vma, . const char **, const char **, unsigned int *); +. bfd_boolean (*_bfd_find_nearest_line_discriminator) +. (bfd *, struct bfd_section *, struct bfd_symbol **, bfd_vma, +. const char **, const char **, unsigned int *, unsigned int *); . bfd_boolean (*_bfd_find_line) . (bfd *, struct bfd_symbol **, struct bfd_symbol *, . const char **, unsigned int *); diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 3068937616..0edd5197c0 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,18 @@ +2012-07-24 Teresa Johnson + + * addr2line.c (find_address_in_section): Invoke + bfd_find_nearest_line_discriminator to get the discriminator. + (find_offset_in_section): Likewise. + (translate_addresses): Print discriminator if it is non-zero. + * objdump.c (show_line): Invoke + bfd_find_nearest_line_discriminator to get the discriminator, + and keep track of prev_discriminator. Print discriminator + if it is non-zero. + (disassemble_data): Initialize prev_discriminator. + (dump_reloc_set): Invoke bfd_find_nearest_line_discriminator + to get the discriminator, and keep track of last_discriminator. + Print discriminator if it is non-zero. + 2012-07-17 Nick Clifton * elfcomm.c (setup_archive): Extract index table and symbol table diff --git a/binutils/addr2line.c b/binutils/addr2line.c index 663da4570e..5febaeae62 100644 --- a/binutils/addr2line.c +++ b/binutils/addr2line.c @@ -139,6 +139,7 @@ static bfd_vma pc; static const char *filename; static const char *functionname; static unsigned int line; +static unsigned int discriminator; static bfd_boolean found; /* Look for an address in a section. This is called via @@ -165,8 +166,9 @@ find_address_in_section (bfd *abfd, asection *section, if (pc >= vma + size) return; - found = bfd_find_nearest_line (abfd, section, syms, pc - vma, - &filename, &functionname, &line); + found = bfd_find_nearest_line_discriminator (abfd, section, syms, pc - vma, + &filename, &functionname, + &line, &discriminator); } /* Look for an offset in a section. This is directly called. */ @@ -186,8 +188,9 @@ find_offset_in_section (bfd *abfd, asection *section) if (pc >= size) return; - found = bfd_find_nearest_line (abfd, section, syms, pc, - &filename, &functionname, &line); + found = bfd_find_nearest_line_discriminator (abfd, section, syms, pc, + &filename, &functionname, + &line, &discriminator); } /* Read hexadecimal addresses from stdin, translate into @@ -294,7 +297,12 @@ translate_addresses (bfd *abfd, asection *section) printf ("%s:", filename ? filename : "??"); if (line != 0) - printf ("%u\n", line); + { + if (discriminator != 0) + printf ("%u (discriminator %u)\n", line, discriminator); + else + printf ("%u\n", line); + } else printf ("?\n"); if (!unwind_inlines) diff --git a/binutils/objdump.c b/binutils/objdump.c index b22bf8bde6..49a2457be7 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -1086,6 +1086,7 @@ objdump_symbol_at_address (bfd_vma vma, struct disassemble_info * inf) static char *prev_functionname; static unsigned int prev_line; +static unsigned int prev_discriminator; /* We keep a list of all files that we have seen when doing a disassembly with source, so that we know how much of the file to @@ -1312,13 +1313,15 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset) const char *filename; const char *functionname; unsigned int linenumber; + unsigned int discriminator; bfd_boolean reloc; if (! with_line_numbers && ! with_source_code) return; - if (! bfd_find_nearest_line (abfd, section, syms, addr_offset, &filename, - &functionname, &linenumber)) + if (! bfd_find_nearest_line_discriminator (abfd, section, syms, addr_offset, + &filename, &functionname, + &linenumber, &discriminator)) return; if (filename != NULL && *filename == '\0') @@ -1370,8 +1373,15 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset) && (prev_functionname == NULL || strcmp (functionname, prev_functionname) != 0)) printf ("%s():\n", functionname); - if (linenumber > 0 && linenumber != prev_line) - printf ("%s:%u\n", filename == NULL ? "???" : filename, linenumber); + if (linenumber > 0 && (linenumber != prev_line || + (discriminator != prev_discriminator))) + { + if (discriminator > 0) + printf ("%s:%u (discriminator %u)\n", filename == NULL ? "???" : filename, + linenumber, discriminator); + else + printf ("%s:%u\n", filename == NULL ? "???" : filename, linenumber); + } } if (with_source_code @@ -1423,6 +1433,9 @@ show_line (bfd *abfd, asection *section, bfd_vma addr_offset) if (linenumber > 0 && linenumber != prev_line) prev_line = linenumber; + + if (discriminator != prev_discriminator) + prev_discriminator = discriminator; } /* Pseudo FILE object for strings. */ @@ -2115,6 +2128,7 @@ disassemble_data (bfd *abfd) print_files = NULL; prev_functionname = NULL; prev_line = -1; + prev_discriminator = 0; /* We make a copy of syms to sort. We don't want to sort syms because that will screw up the relocs. */ @@ -2895,6 +2909,7 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount) arelent **p; char *last_filename, *last_functionname; unsigned int last_line; + unsigned int last_discriminator; /* Get column headers lined up reasonably. */ { @@ -2913,12 +2928,14 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount) last_filename = NULL; last_functionname = NULL; last_line = 0; + last_discriminator = 0; for (p = relpp; relcount && *p != NULL; p++, relcount--) { arelent *q = *p; const char *filename, *functionname; unsigned int linenumber; + unsigned int discriminator; const char *sym_name; const char *section_name; bfd_vma addend2 = 0; @@ -2932,8 +2949,9 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount) if (with_line_numbers && sec != NULL - && bfd_find_nearest_line (abfd, sec, syms, q->address, - &filename, &functionname, &linenumber)) + && bfd_find_nearest_line_discriminator (abfd, sec, syms, q->address, + &filename, &functionname, + &linenumber, &discriminator)) { if (functionname != NULL && (last_functionname == NULL @@ -2949,10 +2967,16 @@ dump_reloc_set (bfd *abfd, asection *sec, arelent **relpp, long relcount) && (linenumber != last_line || (filename != NULL && last_filename != NULL - && filename_cmp (filename, last_filename) != 0))) + && filename_cmp (filename, last_filename) != 0) + || (discriminator != last_discriminator))) { - printf ("%s:%u\n", filename == NULL ? "???" : filename, linenumber); + if (discriminator > 0) + printf ("%s:%u\n", filename == NULL ? "???" : filename, linenumber); + else + printf ("%s:%u (discriminator %u)\n", filename == NULL ? "???" : filename, + linenumber, discriminator); last_line = linenumber; + last_discriminator = discriminator; if (last_filename != NULL) free (last_filename); if (filename == NULL) -- 2.34.1