binutils/binutils-2.27-objdump-improvements.2.patch

695 lines
23 KiB
Diff
Raw Normal View History

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 ("<unknown>");
}
@@ -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 ();