aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2012-05-16 13:57:11 +0000
committerAlan Modra <amodra@gmail.com>2012-05-16 13:57:11 +0000
commita2a5095467760e431d692bee57d524bf218c6ab7 (patch)
tree1674b9fe5e41123cdfeac10eddbab0a6681fadde
parentdf35687a29fb72e43be9fdfe884ef45f82b8f206 (diff)
downloadgdb-a2a5095467760e431d692bee57d524bf218c6ab7.zip
gdb-a2a5095467760e431d692bee57d524bf218c6ab7.tar.gz
gdb-a2a5095467760e431d692bee57d524bf218c6ab7.tar.bz2
* dwarf2.c: Formatting.
(arange_add): Pass in unit rather than bfd. Update callers. Ignore empty ranges. Don't ask for cleared memory. (parse_comp_unit): Only set unit->base_address if processing DW_TAG_compile_unit. (find_debug_info): Optimise section lookup. (place_sections): Use bfd_alloc for stash->adjusted_sections. (find_line): Match previously parsed comp unit addresses as we do for newly parsed comp units.
-rw-r--r--bfd/ChangeLog12
-rw-r--r--bfd/dwarf2.c188
2 files changed, 127 insertions, 73 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 9db6ed3..760d4d9 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,17 @@
2012-05-16 Alan Modra <amodra@gmail.com>
+ * dwarf2.c: Formatting.
+ (arange_add): Pass in unit rather than bfd. Update callers.
+ Ignore empty ranges. Don't ask for cleared memory.
+ (parse_comp_unit): Only set unit->base_address if processing
+ DW_TAG_compile_unit.
+ (find_debug_info): Optimise section lookup.
+ (place_sections): Use bfd_alloc for stash->adjusted_sections.
+ (find_line): Match previously parsed comp unit addresses as we
+ do for newly parsed comp units.
+
+2012-05-16 Alan Modra <amodra@gmail.com>
+
* archive.c (_bfd_generic_read_ar_hdr_mag): Ensure sscanf
stops at end of ar_size field.
diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c
index f7d5d4a..d31b849 100644
--- a/bfd/dwarf2.c
+++ b/bfd/dwarf2.c
@@ -405,8 +405,8 @@ create_info_hash_table (bfd *abfd)
{
struct info_hash_table *hash_table;
- hash_table = (struct info_hash_table *)
- bfd_alloc (abfd, sizeof (struct info_hash_table));
+ hash_table = ((struct info_hash_table *)
+ bfd_alloc (abfd, sizeof (struct info_hash_table)));
if (!hash_table)
return hash_table;
@@ -503,7 +503,7 @@ read_section (bfd * abfd,
if (syms)
{
*section_buffer
- = bfd_simple_get_relocated_section_contents (abfd, msec, NULL, syms);
+ = bfd_simple_get_relocated_section_contents (abfd, msec, NULL, syms);
if (! *section_buffer)
return FALSE;
}
@@ -522,7 +522,8 @@ 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)."),
+ (*_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;
@@ -1014,20 +1015,27 @@ struct line_info_table
/* Remember some information about each function. If the function is
inlined (DW_TAG_inlined_subroutine) it may have two additional
attributes, DW_AT_call_file and DW_AT_call_line, which specify the
- source code location where this function was inlined. */
+ source code location where this function was inlined. */
struct funcinfo
{
- struct funcinfo *prev_func; /* Pointer to previous function in list of all functions */
- struct funcinfo *caller_func; /* Pointer to function one scope higher */
- char *caller_file; /* Source location file name where caller_func inlines this func */
- int caller_line; /* Source location line number where caller_func inlines this func */
- char *file; /* Source location file name */
- int line; /* Source location line number */
+ /* Pointer to previous function in list of all functions. */
+ struct funcinfo *prev_func;
+ /* Pointer to function one scope higher. */
+ struct funcinfo *caller_func;
+ /* Source location file name where caller_func inlines this func. */
+ char *caller_file;
+ /* Source location line number where caller_func inlines this func. */
+ int caller_line;
+ /* Source location file name. */
+ char *file;
+ /* Source location line number. */
+ int line;
int tag;
char *name;
struct arange arange;
- asection *sec; /* Where the symbol is defined */
+ /* Where the symbol is defined. */
+ asection *sec;
};
struct varinfo
@@ -1248,12 +1256,16 @@ concat_filename (struct line_info_table *table, unsigned int file)
}
static bfd_boolean
-arange_add (bfd *abfd, struct arange *first_arange,
+arange_add (const struct comp_unit *unit, struct arange *first_arange,
bfd_vma low_pc, bfd_vma high_pc)
{
struct arange *arange;
- /* If the first arange is empty, use it. */
+ /* Ignore empty ranges. */
+ if (low_pc == high_pc)
+ return TRUE;
+
+ /* If the first arange is empty, use it. */
if (first_arange->high == 0)
{
first_arange->low = low_pc;
@@ -1281,7 +1293,7 @@ arange_add (bfd *abfd, struct arange *first_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. */
- arange = (struct arange *) bfd_zalloc (abfd, sizeof (*arange));
+ arange = (struct arange *) bfd_alloc (unit->abfd, sizeof (*arange));
if (arange == NULL)
return FALSE;
arange->low = low_pc;
@@ -1582,15 +1594,15 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
/* 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;
+ 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;
+ 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. */
@@ -1605,7 +1617,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
else switch (op_code)
{
case DW_LNS_extended_op:
- exop_len = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ exop_len = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
line_ptr += bytes_read;
extended_op = read_1_byte (abfd, line_ptr);
line_ptr += 1;
@@ -1621,7 +1633,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
low_pc = address;
if (address > high_pc)
high_pc = address;
- if (!arange_add (unit->abfd, &unit->arange, low_pc, high_pc))
+ if (!arange_add (unit, &unit->arange, low_pc, high_pc))
goto line_fail;
break;
case DW_LNE_set_address:
@@ -1659,11 +1671,12 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
(void) read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
line_ptr += bytes_read;
break;
- case DW_LNE_HP_source_file_correlation:
- line_ptr += exop_len - 1;
- break;
+ case DW_LNE_HP_source_file_correlation:
+ line_ptr += exop_len - 1;
+ break;
default:
- (*_bfd_error_handler) (_("Dwarf Error: mangled line number section."));
+ (*_bfd_error_handler)
+ (_("Dwarf Error: mangled line number section."));
bfd_set_error (bfd_error_bad_value);
line_fail:
if (filename != NULL)
@@ -1682,15 +1695,15 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
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);
+ 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;
+ 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;
@@ -1723,13 +1736,14 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
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);
+ 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);
+ address += (lh.minimum_instruction_length
+ * ((op_index + adjust)
+ / lh.maximum_ops_per_insn));
op_index = (op_index + adjust) % lh.maximum_ops_per_insn;
}
break;
@@ -1855,8 +1869,9 @@ lookup_address_in_function_table (struct comp_unit *unit,
{
if (addr >= arange->low && addr < arange->high)
{
- if (!best_fit ||
- ((arange->high - arange->low) < (best_fit->arange.high - best_fit->arange.low)))
+ if (!best_fit
+ || (arange->high - arange->low
+ < best_fit->arange.high - best_fit->arange.low))
best_fit = each_func;
}
}
@@ -1904,8 +1919,8 @@ lookup_symbol_in_function_table (struct comp_unit *unit,
&& each_func->name
&& strcmp (name, each_func->name) == 0
&& (!best_fit
- || ((arange->high - arange->low)
- < (best_fit->arange.high - best_fit->arange.low))))
+ || (arange->high - arange->low
+ < best_fit->arange.high - best_fit->arange.low)))
best_fit = each_func;
}
}
@@ -1990,8 +2005,8 @@ find_abstract_instance_name (struct comp_unit *unit,
abbrev = lookup_abbrev (abbrev_number, unit->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);
}
else
@@ -2056,7 +2071,7 @@ read_rangelist (struct comp_unit *unit, struct arange *arange,
base_address = high_pc;
else
{
- if (!arange_add (unit->abfd, arange,
+ if (!arange_add (unit, arange,
base_address + low_pc, base_address + high_pc))
return FALSE;
}
@@ -2082,7 +2097,7 @@ scan_unit_for_symbols (struct comp_unit *unit)
can use to set the caller_func field. */
nested_funcs_size = 32;
nested_funcs = (struct funcinfo **)
- bfd_malloc (nested_funcs_size * sizeof (struct funcinfo *));
+ bfd_malloc (nested_funcs_size * sizeof (struct funcinfo *));
if (nested_funcs == NULL)
return FALSE;
nested_funcs[nesting_level] = 0;
@@ -2286,7 +2301,7 @@ scan_unit_for_symbols (struct comp_unit *unit)
if (func && high_pc != 0)
{
- if (!arange_add (unit->abfd, &func->arange, low_pc, high_pc))
+ if (!arange_add (unit, &func->arange, low_pc, high_pc))
goto fail;
}
@@ -2300,8 +2315,8 @@ scan_unit_for_symbols (struct comp_unit *unit)
nested_funcs_size *= 2;
tmp = (struct funcinfo **)
- bfd_realloc (nested_funcs,
- (nested_funcs_size * sizeof (struct funcinfo *)));
+ bfd_realloc (nested_funcs,
+ nested_funcs_size * sizeof (struct funcinfo *));
if (tmp == NULL)
goto fail;
nested_funcs = tmp;
@@ -2362,23 +2377,29 @@ parse_comp_unit (struct dwarf2_debug *stash,
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_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;
}
if (addr_size > sizeof (bfd_vma))
{
- (*_bfd_error_handler) (_("Dwarf Error: found address size '%u', this reader can not handle sizes greater than '%u'."),
- addr_size,
- (unsigned int) sizeof (bfd_vma));
+ (*_bfd_error_handler)
+ (_("Dwarf Error: found address size '%u', this reader"
+ " can not handle sizes greater than '%u'."),
+ addr_size,
+ (unsigned int) sizeof (bfd_vma));
bfd_set_error (bfd_error_bad_value);
return 0;
}
if (addr_size != 2 && addr_size != 4 && addr_size != 8)
{
- (*_bfd_error_handler) ("Dwarf Error: found address size '%u', this reader can only handle address sizes '2', '4' and '8'.", addr_size);
+ (*_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);
return 0;
}
@@ -2386,14 +2407,14 @@ parse_comp_unit (struct dwarf2_debug *stash,
/* Read the abbrevs for this compilation unit into a table. */
abbrevs = read_abbrevs (abfd, abbrev_offset, stash);
if (! abbrevs)
- return 0;
+ return 0;
abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
if (! abbrev_number)
{
(*_bfd_error_handler) (_("Dwarf Error: Bad abbrev number: %u."),
- abbrev_number);
+ abbrev_number);
bfd_set_error (bfd_error_bad_value);
return 0;
}
@@ -2402,7 +2423,7 @@ parse_comp_unit (struct dwarf2_debug *stash,
if (! abbrev)
{
(*_bfd_error_handler) (_("Dwarf Error: Could not find abbrev number %u."),
- abbrev_number);
+ abbrev_number);
bfd_set_error (bfd_error_bad_value);
return 0;
}
@@ -2445,7 +2466,8 @@ parse_comp_unit (struct dwarf2_debug *stash,
/* 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. */
- unit->base_address = low_pc;
+ if (abbrev->tag == DW_TAG_compile_unit)
+ unit->base_address = low_pc;
break;
case DW_AT_high_pc:
@@ -2482,7 +2504,7 @@ parse_comp_unit (struct dwarf2_debug *stash,
high_pc += low_pc;
if (high_pc != 0)
{
- if (!arange_add (unit->abfd, &unit->arange, low_pc, high_pc))
+ if (!arange_add (unit, &unit->arange, low_pc, high_pc))
return NULL;
}
@@ -2752,25 +2774,43 @@ static asection *
find_debug_info (bfd *abfd, const struct dwarf_debug_section *debug_sections,
asection *after_sec)
{
- asection * msec;
+ asection *msec;
+ const char *look;
+
+ if (after_sec == NULL)
+ {
+ look = debug_sections[debug_info].uncompressed_name;
+ msec = bfd_get_section_by_name (abfd, look);
+ if (msec != NULL)
+ return msec;
- msec = after_sec != NULL ? after_sec->next : abfd->sections;
+ look = debug_sections[debug_info].compressed_name;
+ if (look != NULL)
+ {
+ msec = bfd_get_section_by_name (abfd, look);
+ if (msec != NULL)
+ return msec;
+ }
- while (msec)
+ for (msec = abfd->sections; msec != NULL; msec = msec->next)
+ if (CONST_STRNEQ (msec->name, GNU_LINKONCE_INFO))
+ return msec;
+
+ return NULL;
+ }
+
+ for (msec = after_sec->next; msec != NULL; msec = msec->next)
{
- if (strcmp (msec->name,
- debug_sections[debug_info].uncompressed_name) == 0)
+ look = debug_sections[debug_info].uncompressed_name;
+ if (strcmp (msec->name, look) == 0)
return msec;
- if (debug_sections[debug_info].compressed_name != NULL
- && strcmp (msec->name,
- debug_sections[debug_info].compressed_name) == 0)
+ look = debug_sections[debug_info].compressed_name;
+ if (look != NULL && strcmp (msec->name, look) == 0)
return msec;
if (CONST_STRNEQ (msec->name, GNU_LINKONCE_INFO))
return msec;
-
- msec = msec->next;
}
return NULL;
@@ -2844,7 +2884,7 @@ place_sections (bfd *abfd, struct dwarf2_debug *stash)
}
amt = i * sizeof (struct adjusted_section);
- p = (struct adjusted_section *) bfd_zalloc (abfd, amt);
+ p = (struct adjusted_section *) bfd_alloc (abfd, amt);
if (! p)
return FALSE;
@@ -2938,8 +2978,8 @@ info_hash_lookup_funcinfo (struct info_hash_table *hash_table,
&& addr >= arange->low
&& addr < arange->high
&& (!best_fit
- || ((arange->high - arange->low)
- < (best_fit->arange.high - best_fit->arange.low))))
+ || (arange->high - arange->low
+ < best_fit->arange.high - best_fit->arange.low)))
best_fit = each_func;
}
}
@@ -3359,6 +3399,7 @@ find_line (bfd *abfd,
/* Check the previously read comp. units first. */
for (each = stash->all_comp_units; each; each = each->next_unit)
if ((symbol->flags & BSF_FUNCTION) == 0
+ || each->arange.high == 0
|| comp_unit_contains_address (each, addr))
{
found = comp_unit_find_line (each, symbol, addr, filename_ptr,
@@ -3372,7 +3413,8 @@ find_line (bfd *abfd,
{
for (each = stash->all_comp_units; each; each = each->next_unit)
{
- found = (comp_unit_contains_address (each, addr)
+ found = ((each->arange.high == 0
+ || comp_unit_contains_address (each, addr))
&& comp_unit_find_nearest_line (each, addr,
filename_ptr,
functionname_ptr,
@@ -3485,7 +3527,7 @@ find_line (bfd *abfd,
}
}
-done:
+ done:
if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
unset_sections (stash);