From b877ba7c27b63cd1fdc6d1b2e0ba7c9060ff1a92 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Jan 09 2017 14:13:52 +0000 Subject: Another speed up for objdump when displaying source code alognside disassembly. Relates: #1397113 --- diff --git a/binutils-2.27-objdump-improvements.2.patch b/binutils-2.27-objdump-improvements.2.patch new file mode 100644 index 0000000..7d56c18 --- /dev/null +++ b/binutils-2.27-objdump-improvements.2.patch @@ -0,0 +1,694 @@ +diff -rup binutils.orig/bfd/dwarf2.c binutils-2.27/bfd/dwarf2.c +--- binutils.orig/bfd/dwarf2.c 2017-01-09 10:55:15.558436986 +0000 ++++ binutils-2.27/bfd/dwarf2.c 2017-01-09 13:40:38.642944116 +0000 +@@ -1,5 +1,5 @@ + /* DWARF 2 support. +- Copyright (C) 1994-2016 Free Software Foundation, Inc. ++ Copyright (C) 1994-2017 Free Software Foundation, Inc. + + Adapted from gdb/dwarf2read.c by Gavin Koch of Cygnus Solutions + (gavin@cygnus.com). +@@ -144,16 +144,16 @@ struct dwarf2_debug + /* Length of the loaded .debug_str section. */ + bfd_size_type dwarf_str_size; + +- /* Pointer to the .debug_ranges section loaded into memory. */ ++ /* Pointer to the .debug_ranges section loaded into memory. */ + bfd_byte *dwarf_ranges_buffer; + +- /* Length of the loaded .debug_ranges section. */ ++ /* Length of the loaded .debug_ranges section. */ + bfd_size_type dwarf_ranges_size; + + /* If the most recent call to bfd_find_nearest_line was given an + address in an inlined function, preserve a pointer into the + calling chain for subsequent calls to bfd_find_inliner_info to +- use. */ ++ use. */ + struct funcinfo *inliner_chain; + + /* Section VMAs at the time the stash was built. */ +@@ -212,9 +212,12 @@ struct comp_unit + /* Keep the bfd convenient (for memory allocation). */ + bfd *abfd; + +- /* The lowest and highest addresses contained in this compilation +- unit as specified in the compilation unit header. */ ++ /* Linked list of the low and high address ranges contained in this ++ compilation unit as specified in the compilation unit header. */ + struct arange arange; ++ /* A single arange containing the lowest and highest ++ addresses covered by the compilation unit. */ ++ struct arange minmax; + + /* The DW_AT_name attribute (for error messages). */ + char *name; +@@ -396,7 +399,7 @@ struct info_hash_table + struct bfd_hash_table base; + }; + +-/* Function to create a new entry in info hash table. */ ++/* Function to create a new entry in info hash table. */ + + static struct bfd_hash_entry * + info_hash_table_newfunc (struct bfd_hash_entry *entry, +@@ -482,7 +485,7 @@ insert_info_hash_table (struct info_hash + } + + /* Look up an info entry list from an info hash table. Return NULL +- if there is none. */ ++ if there is none. */ + + static struct info_list_node * + lookup_info_hash_table (struct info_hash_table *hash_table, const char *key) +@@ -523,8 +526,8 @@ read_section (bfd * abfd, + } + if (! msec) + { +- (*_bfd_error_handler) (_("Dwarf Error: Can't find %s section."), +- sec->uncompressed_name); ++ _bfd_error_handler (_("Dwarf Error: Can't find %s section."), ++ sec->uncompressed_name); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } +@@ -552,9 +555,10 @@ read_section (bfd * abfd, + that the client wants. Validate it here to avoid trouble later. */ + if (offset != 0 && offset >= *section_size) + { +- (*_bfd_error_handler) (_("Dwarf Error: Offset (%lu)" +- " greater than or equal to %s size (%lu)."), +- (long) offset, section_name, *section_size); ++ /* xgettext: c-format */ ++ _bfd_error_handler (_("Dwarf Error: Offset (%lu)" ++ " greater than or equal to %s size (%lu)."), ++ (long) offset, section_name, *section_size); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } +@@ -1011,7 +1015,7 @@ read_attribute_value (struct attribute * + + if (info_ptr >= info_ptr_end && form != DW_FORM_flag_present) + { +- (*_bfd_error_handler) (_("Dwarf Error: Info pointer extends beyond end of attributes")); ++ _bfd_error_handler (_("Dwarf Error: Info pointer extends beyond end of attributes")); + bfd_set_error (bfd_error_bad_value); + return info_ptr; + } +@@ -1163,8 +1167,8 @@ read_attribute_value (struct attribute * + info_ptr = read_attribute_value (attr, form, unit, info_ptr, info_ptr_end); + break; + default: +- (*_bfd_error_handler) (_("Dwarf Error: Invalid or unhandled FORM value: %#x."), +- form); ++ _bfd_error_handler (_("Dwarf Error: Invalid or unhandled FORM value: %#x."), ++ form); + bfd_set_error (bfd_error_bad_value); + return NULL; + } +@@ -1219,22 +1223,22 @@ non_mangled (int lang) + + struct line_info + { +- struct line_info* prev_line; +- bfd_vma address; +- char *filename; +- unsigned int line; +- unsigned int column; +- unsigned int discriminator; +- unsigned char op_index; +- unsigned char end_sequence; /* End of (sequential) code sequence. */ ++ struct line_info * prev_line; ++ bfd_vma address; ++ char * filename; ++ unsigned int line; ++ unsigned int column; ++ unsigned int discriminator; ++ unsigned char op_index; ++ unsigned char end_sequence; /* End of (sequential) code sequence. */ + }; + + struct fileinfo + { +- char *name; +- unsigned int dir; +- unsigned int time; +- unsigned int size; ++ char * name; ++ unsigned int dir; ++ unsigned int time; ++ unsigned int size; + }; + + struct line_sequence +@@ -1248,7 +1252,7 @@ struct line_sequence + + struct line_info_table + { +- bfd* abfd; ++ bfd * abfd; + unsigned int num_files; + unsigned int num_dirs; + unsigned int num_sequences; +@@ -1267,37 +1271,37 @@ struct line_info_table + struct funcinfo + { + /* Pointer to previous function in list of all functions. */ +- struct funcinfo *prev_func; ++ struct funcinfo * prev_func; + /* Pointer to function one scope higher. */ +- struct funcinfo *caller_func; ++ struct funcinfo * caller_func; + /* Source location file name where caller_func inlines this func. */ +- char *caller_file; ++ char * caller_file; + /* Source location file name. */ +- char *file; ++ char * file; + /* Source location line number where caller_func inlines this func. */ +- int caller_line; ++ int caller_line; + /* Source location line number. */ +- int line; +- int tag; +- bfd_boolean is_linkage; +- const char *name; +- struct arange arange; ++ int line; ++ int tag; ++ bfd_boolean is_linkage; ++ const char * name; ++ struct arange arange; + /* Where the symbol is defined. */ +- asection *sec; ++ asection * sec; + }; + + struct lookup_funcinfo + { + /* Function information corresponding to this lookup table entry. */ +- struct funcinfo *funcinfo; ++ struct funcinfo * funcinfo; + + /* The lowest address for this specific function. */ +- bfd_vma low_addr; ++ bfd_vma low_addr; + + /* The highest address of this function before the lookup table is sorted. +- The highest address of all prior functions after the lookup table is sorted, +- which is used for binary search. */ +- bfd_vma high_addr; ++ The highest address of all prior functions after the lookup table is ++ sorted, which is used for binary search. */ ++ bfd_vma high_addr; + }; + + struct varinfo +@@ -1468,7 +1472,7 @@ concat_filename (struct line_info_table + { + /* FILE == 0 means unknown. */ + if (file) +- (*_bfd_error_handler) ++ _bfd_error_handler + (_("Dwarf Error: mangled line number section (bad file number).")); + return strdup (""); + } +@@ -1524,7 +1528,7 @@ concat_filename (struct line_info_table + } + + static bfd_boolean +-arange_add (const struct comp_unit *unit, struct arange *first_arange, ++arange_add (struct comp_unit *unit, struct arange *first_arange, + bfd_vma low_pc, bfd_vma high_pc) + { + struct arange *arange; +@@ -1536,11 +1540,16 @@ arange_add (const struct comp_unit *unit + /* If the first arange is empty, use it. */ + if (first_arange->high == 0) + { +- first_arange->low = low_pc; +- first_arange->high = high_pc; ++ unit->minmax.low = first_arange->low = low_pc; ++ unit->minmax.high = first_arange->high = high_pc; + return TRUE; + } + ++ if (unit->minmax.low > low_pc) ++ unit->minmax.low = low_pc; ++ if (unit->minmax.high < high_pc) ++ unit->minmax.high = high_pc; ++ + /* Next see if we can cheaply extend an existing range. */ + arange = first_arange; + do +@@ -1560,7 +1569,7 @@ arange_add (const struct comp_unit *unit + while (arange); + + /* Need to allocate a new arange and insert it into the arange list. +- Order isn't significant, so just insert after the first arange. */ ++ Order isn't significant, so just insert after the first arange. */ + arange = (struct arange *) bfd_alloc (unit->abfd, sizeof (*arange)); + if (arange == NULL) + return FALSE; +@@ -1603,20 +1612,22 @@ compare_sequences (const void* a, const + /* Construct the line information table for quick lookup. */ + + static bfd_boolean +-build_line_info_table (struct line_info_table* table, struct line_sequence *seq) ++build_line_info_table (struct line_info_table * table, ++ struct line_sequence * seq) + { +- bfd_size_type amt; ++ bfd_size_type amt; + struct line_info** line_info_lookup; +- struct line_info* each_line; +- unsigned int num_lines; +- unsigned int index; ++ struct line_info* each_line; ++ unsigned int num_lines; ++ unsigned int line_index; + + if (seq->line_info_lookup != NULL) + return TRUE; + + /* Count the number of line information entries. We could do this while +- scanning the debug information, but some entries may be added via lcl_head +- without having a sequence handy to increment the number of lines. */ ++ scanning the debug information, but some entries may be added via ++ lcl_head without having a sequence handy to increment the number of ++ lines. */ + num_lines = 0; + for (each_line = seq->last_line; each_line; each_line = each_line->prev_line) + num_lines++; +@@ -1631,11 +1642,11 @@ build_line_info_table (struct line_info_ + return FALSE; + + /* Create the line information lookup table. */ +- index = num_lines; ++ line_index = num_lines; + for (each_line = seq->last_line; each_line; each_line = each_line->prev_line) +- line_info_lookup[--index] = each_line; ++ line_info_lookup[--line_index] = each_line; + +- BFD_ASSERT (index == 0); ++ BFD_ASSERT (line_index == 0); + + seq->num_lines = num_lines; + seq->line_info_lookup = line_info_lookup; +@@ -1648,12 +1659,12 @@ build_line_info_table (struct line_info_ + static bfd_boolean + sort_line_sequences (struct line_info_table* table) + { +- bfd_size_type amt; +- struct line_sequence* sequences; +- struct line_sequence* seq; +- unsigned int n = 0; +- unsigned int num_sequences = table->num_sequences; +- bfd_vma last_high_pc; ++ bfd_size_type amt; ++ struct line_sequence* sequences; ++ struct line_sequence* seq; ++ unsigned int n = 0; ++ unsigned int num_sequences = table->num_sequences; ++ bfd_vma last_high_pc; + + if (num_sequences == 0) + return TRUE; +@@ -1754,7 +1765,7 @@ decode_line_info (struct comp_unit *unit + + if (stash->dwarf_line_size < 16) + { +- (*_bfd_error_handler) ++ _bfd_error_handler + (_("Dwarf Error: Line info section is too small (%ld)"), + (long) stash->dwarf_line_size); + bfd_set_error (bfd_error_bad_value); +@@ -1783,7 +1794,8 @@ decode_line_info (struct comp_unit *unit + + if (lh.total_length > stash->dwarf_line_size) + { +- (*_bfd_error_handler) ++ _bfd_error_handler ++ /* xgettext: c-format */ + (_("Dwarf Error: Line info data is bigger (0x%lx) than the section (0x%lx)"), + (long) lh.total_length, (long) stash->dwarf_line_size); + bfd_set_error (bfd_error_bad_value); +@@ -1795,7 +1807,7 @@ decode_line_info (struct comp_unit *unit + lh.version = read_2_bytes (abfd, line_ptr, line_end); + if (lh.version < 2 || lh.version > 4) + { +- (*_bfd_error_handler) ++ _bfd_error_handler + (_("Dwarf Error: Unhandled .debug_line version %d."), lh.version); + bfd_set_error (bfd_error_bad_value); + return NULL; +@@ -1804,7 +1816,7 @@ decode_line_info (struct comp_unit *unit + + if (line_ptr + offset_size + (lh.version >=4 ? 6 : 5) >= line_end) + { +- (*_bfd_error_handler) ++ _bfd_error_handler + (_("Dwarf Error: Ran out of room reading prologue")); + bfd_set_error (bfd_error_bad_value); + return NULL; +@@ -1829,7 +1841,7 @@ decode_line_info (struct comp_unit *unit + + if (lh.maximum_ops_per_insn == 0) + { +- (*_bfd_error_handler) ++ _bfd_error_handler + (_("Dwarf Error: Invalid maximum operations per instruction.")); + bfd_set_error (bfd_error_bad_value); + return NULL; +@@ -1849,7 +1861,7 @@ decode_line_info (struct comp_unit *unit + + if (line_ptr + (lh.opcode_base - 1) >= line_end) + { +- (*_bfd_error_handler) (_("Dwarf Error: Ran out of room reading opcodes")); ++ _bfd_error_handler (_("Dwarf Error: Ran out of room reading opcodes")); + bfd_set_error (bfd_error_bad_value); + return NULL; + } +@@ -2036,7 +2048,7 @@ decode_line_info (struct comp_unit *unit + line_ptr += exop_len - 1; + break; + default: +- (*_bfd_error_handler) ++ _bfd_error_handler + (_("Dwarf Error: mangled line number section.")); + bfd_set_error (bfd_error_bad_value); + line_fail: +@@ -2218,45 +2230,44 @@ fail: + /* Read in the .debug_ranges section for future reference. */ + + static bfd_boolean +-read_debug_ranges (struct comp_unit *unit) ++read_debug_ranges (struct comp_unit * unit) + { +- struct dwarf2_debug *stash = unit->stash; ++ struct dwarf2_debug * stash = unit->stash; ++ + return read_section (unit->abfd, &stash->debug_sections[debug_ranges], + stash->syms, 0, +- &stash->dwarf_ranges_buffer, &stash->dwarf_ranges_size); ++ &stash->dwarf_ranges_buffer, ++ &stash->dwarf_ranges_size); + } + + /* Function table functions. */ + + static int +-compare_lookup_funcinfos (const void* a, const void* b) ++compare_lookup_funcinfos (const void * a, const void * b) + { +- const struct lookup_funcinfo *lookup1 = a; +- const struct lookup_funcinfo *lookup2 = b; +- int result; ++ const struct lookup_funcinfo * lookup1 = a; ++ const struct lookup_funcinfo * lookup2 = b; + + if (lookup1->low_addr < lookup2->low_addr) +- result = -1; +- else if (lookup1->low_addr > lookup2->low_addr) +- result = 1; +- else if (lookup1->high_addr < lookup2->high_addr) +- result = -1; +- else if (lookup1->high_addr > lookup1->high_addr) +- result = 1; +- else +- result = 0; ++ return -1; ++ if (lookup1->low_addr > lookup2->low_addr) ++ return 1; ++ if (lookup1->high_addr < lookup2->high_addr) ++ return -1; ++ if (lookup1->high_addr > lookup2->high_addr) ++ return 1; + +- return result; ++ return 0; + } + + static bfd_boolean +-build_lookup_funcinfo_table (struct comp_unit *unit) ++build_lookup_funcinfo_table (struct comp_unit * unit) + { + struct lookup_funcinfo *lookup_funcinfo_table = unit->lookup_funcinfo_table; + unsigned int number_of_functions = unit->number_of_functions; + struct funcinfo *each; + struct lookup_funcinfo *entry; +- size_t index; ++ size_t func_index; + struct arange *range; + bfd_vma low_addr, high_addr; + +@@ -2270,10 +2281,10 @@ build_lookup_funcinfo_table (struct comp + return FALSE; + + /* Populate the function info lookup table. */ +- index = number_of_functions; ++ func_index = number_of_functions; + for (each = unit->function_table; each; each = each->prev_func) + { +- entry = &lookup_funcinfo_table[--index]; ++ entry = &lookup_funcinfo_table[--func_index]; + entry->funcinfo = each; + + /* Calculate the lowest and highest address for this function entry. */ +@@ -2281,30 +2292,30 @@ build_lookup_funcinfo_table (struct comp + high_addr = entry->funcinfo->arange.high; + + for (range = entry->funcinfo->arange.next; range; range = range->next) +- { +- if (range->low < low_addr) +- low_addr = range->low; +- if (range->high > high_addr) +- high_addr = range->high; +- } ++ { ++ if (range->low < low_addr) ++ low_addr = range->low; ++ if (range->high > high_addr) ++ high_addr = range->high; ++ } + + entry->low_addr = low_addr; + entry->high_addr = high_addr; + } + +- BFD_ASSERT (index == 0); ++ BFD_ASSERT (func_index == 0); + + /* Sort the function by address. */ + qsort (lookup_funcinfo_table, +- number_of_functions, +- sizeof (struct lookup_funcinfo), +- compare_lookup_funcinfos); ++ number_of_functions, ++ sizeof (struct lookup_funcinfo), ++ compare_lookup_funcinfos); + + /* Calculate the high watermark for each function in the lookup table. */ + high_addr = lookup_funcinfo_table[0].high_addr; +- for (index = 1; index < number_of_functions; index++) ++ for (func_index = 1; func_index < number_of_functions; func_index++) + { +- entry = &lookup_funcinfo_table[index]; ++ entry = &lookup_funcinfo_table[func_index]; + if (entry->high_addr > high_addr) + high_addr = entry->high_addr; + else +@@ -2333,9 +2344,15 @@ lookup_address_in_function_table (struct + bfd_size_type low, high, mid, first; + struct arange *arange; + ++ if (number_of_functions == 0) ++ return FALSE; ++ + if (!build_lookup_funcinfo_table (unit)) + return FALSE; + ++ if (unit->lookup_funcinfo_table[number_of_functions - 1].high_addr < addr) ++ return FALSE; ++ + /* Find the first function in the lookup table which may contain the + specified address. */ + low = 0; +@@ -2474,8 +2491,8 @@ lookup_symbol_in_variable_table (struct + *linenumber_ptr = each->line; + return TRUE; + } +- else +- return FALSE; ++ ++ return FALSE; + } + + static char * +@@ -2531,7 +2548,7 @@ find_abstract_instance_name (struct comp + info_ptr = read_alt_indirect_ref (unit, die_ref); + if (info_ptr == NULL) + { +- (*_bfd_error_handler) ++ _bfd_error_handler + (_("Dwarf Error: Unable to read alt ref %u."), die_ref); + bfd_set_error (bfd_error_bad_value); + return NULL; +@@ -2555,7 +2572,7 @@ find_abstract_instance_name (struct comp + abbrev = lookup_abbrev (abbrev_number, unit->abbrevs); + if (! abbrev) + { +- (*_bfd_error_handler) ++ _bfd_error_handler + (_("Dwarf Error: Could not find abbrev number %u."), abbrev_number); + bfd_set_error (bfd_error_bad_value); + } +@@ -2699,7 +2716,7 @@ scan_unit_for_symbols (struct comp_unit + abbrev = lookup_abbrev (abbrev_number,unit->abbrevs); + if (! abbrev) + { +- (*_bfd_error_handler) ++ _bfd_error_handler + (_("Dwarf Error: Could not find abbrev number %u."), + abbrev_number); + bfd_set_error (bfd_error_bad_value); +@@ -2969,7 +2986,7 @@ parse_comp_unit (struct dwarf2_debug *st + an error, just return a NULL. */ + if (version) + { +- (*_bfd_error_handler) ++ _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); +@@ -2979,7 +2996,8 @@ parse_comp_unit (struct dwarf2_debug *st + + if (addr_size > sizeof (bfd_vma)) + { +- (*_bfd_error_handler) ++ _bfd_error_handler ++ /* xgettext: c-format */ + (_("Dwarf Error: found address size '%u', this reader" + " can not handle sizes greater than '%u'."), + addr_size, +@@ -2990,7 +3008,7 @@ parse_comp_unit (struct dwarf2_debug *st + + if (addr_size != 2 && addr_size != 4 && addr_size != 8) + { +- (*_bfd_error_handler) ++ _bfd_error_handler + ("Dwarf Error: found address size '%u', this reader" + " can only handle address sizes '2', '4' and '8'.", addr_size); + bfd_set_error (bfd_error_bad_value); +@@ -3016,8 +3034,8 @@ parse_comp_unit (struct dwarf2_debug *st + abbrev = lookup_abbrev (abbrev_number, abbrevs); + if (! abbrev) + { +- (*_bfd_error_handler) (_("Dwarf Error: Could not find abbrev number %u."), +- abbrev_number); ++ _bfd_error_handler (_("Dwarf Error: Could not find abbrev number %u."), ++ abbrev_number); + bfd_set_error (bfd_error_bad_value); + return NULL; + } +@@ -3059,7 +3077,7 @@ parse_comp_unit (struct dwarf2_debug *st + low_pc = attr.u.val; + /* If the compilation unit DIE has a DW_AT_low_pc attribute, + this is the base address to use when reading location +- lists or range lists. */ ++ lists or range lists. */ + if (abbrev->tag == DW_TAG_compile_unit) + unit->base_address = low_pc; + break; +@@ -3081,7 +3099,7 @@ parse_comp_unit (struct dwarf2_debug *st + /* PR 17512: file: 1fe726be. */ + if (! is_str_attr (attr.form)) + { +- (*_bfd_error_handler) ++ _bfd_error_handler + (_("Dwarf Error: DW_AT_comp_dir attribute encountered with a non-string form.")); + comp_dir = NULL; + } +@@ -3133,6 +3151,11 @@ comp_unit_contains_address (struct comp_ + if (unit->error) + return FALSE; + ++ if (unit->minmax.high < addr || unit->minmax.low > addr) ++ return FALSE; ++ ++ /* We know that the address *might* be contained within this comp ++ unit, but we cannot be sure until we check the specific ranges. */ + arange = &unit->arange; + do + { +@@ -3330,7 +3353,7 @@ comp_unit_hash_info (struct dwarf2_debug + each_func && okay; + each_func = each_func->prev_func) + { +- /* Skip nameless functions. */ ++ /* Skip nameless functions. */ + if (each_func->name) + /* There is no need to copy name string into hash table as + name string is either in the dwarf string buffer or +@@ -3712,7 +3735,7 @@ stash_maybe_update_info_hash_tables (str + return TRUE; + } + +-/* Check consistency of info hash tables. This is for debugging only. */ ++/* Check consistency of info hash tables. This is for debugging only. */ + + static void ATTRIBUTE_UNUSED + stash_verify_info_hash_table (struct dwarf2_debug *stash) +@@ -4146,7 +4169,7 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd + stash_maybe_enable_info_hash_tables (abfd, stash); + + /* Keep info hash table up to date if they are available. Note that we +- may disable the hash tables if there is any error duing update. */ ++ may disable the hash tables if there is any error duing update. */ + if (stash->info_hash_status == STASH_INFO_HASH_ON) + stash_maybe_update_info_hash_tables (stash); + +diff -rup binutils.orig/binutils/objdump.c binutils-2.27/binutils/objdump.c +--- binutils.orig/binutils/objdump.c 2017-01-09 10:55:15.771433447 +0000 ++++ binutils-2.27/binutils/objdump.c 2017-01-09 13:36:45.936970981 +0000 +@@ -3603,7 +3603,7 @@ display_any_bfd (bfd *file, int level) + } + + static void +-display_file (char *filename, char *target) ++display_file (char *filename, char *target, bfd_boolean last_file) + { + bfd *file; + +@@ -3622,7 +3622,14 @@ display_file (char *filename, char *targ + + display_any_bfd (file, 0); + +- bfd_close (file); ++ /* This is an optimization to improve the speed of objdump, especially when ++ dumping a file with lots of associated debug informatiom. Closing such ++ a file can take a non-trivial amount of time as there are lots of lists ++ to walk and buffers to free. This is only really necessary however if ++ we are about to load another file. Otherwise, if we are about to exit, ++ then we can save (a lot of) time by not bothering to do any tidying up. */ ++ if (! last_file) ++ bfd_close (file); + } + + int +@@ -3900,10 +3907,13 @@ main (int argc, char **argv) + else + { + if (optind == argc) +- display_file ("a.out", target); ++ display_file ("a.out", target, TRUE); + else + for (; optind < argc;) +- display_file (argv[optind++], target); ++ { ++ display_file (argv[optind], target, optind == argc - 1); ++ optind++; ++ } + } + + free_only_list (); diff --git a/binutils.spec b/binutils.spec index e797d61..650bf9d 100644 --- a/binutils.spec +++ b/binutils.spec @@ -43,7 +43,7 @@ Summary: A GNU collection of binary utilities Name: %{?cross}binutils%{?_with_debug:-debug} Version: 2.27 -Release: 12%{?dist} +Release: 13%{?dist} License: GPLv3+ Group: Development/Tools URL: http://sources.redhat.com/binutils @@ -90,6 +90,8 @@ Patch19: binutils-2.28-gold.patch Patch20: binutils-2.27-objdump-improvements.patch # Improve objdump's speed when mixing disassembly with source code Patch21: binutils-2.27-dwarf-parse-speedup.patch +# More objdump speed improvements +Patch22: binutils-2.27-objdump-improvements.2.patch Provides: bundled(libiberty) @@ -236,6 +238,7 @@ using libelf instead of BFD. %patch19 -p0 %patch20 -p1 %patch21 -p1 +%patch22 -p1 # We cannot run autotools as there is an exact requirement of autoconf-2.59. @@ -601,6 +604,10 @@ exit 0 %endif # %{isnative} %changelog +* Mon Jan 09 2017 Nick Clifton 2.27-13 +- Another speed up for objdump when displaying source code alognside disassembly. + (#1397113) + * Tue Nov 22 2016 Nick Clifton 2.27-12 - Speed up objdump when displaying source code alognside disassembly. (#1397113)