/* DWARF 2 support.
- Copyright (C) 1994-2015 Free Software Foundation, Inc.
+ Copyright (C) 1994-2016 Free Software Foundation, Inc.
Adapted from gdb/dwarf2read.c by Gavin Koch of Cygnus Solutions
(gavin@cygnus.com).
}
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;
}
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);
+ _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;
}
struct dwarf_block *blk;
bfd_size_type amt;
- if (info_ptr >= info_ptr_end)
+ 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;
}
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;
}
{
/* FILE == 0 means unknown. */
if (file)
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("Dwarf Error: mangled line number section (bad file number)."));
return strdup ("<unknown>");
}
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);
if (lh.total_length > stash->dwarf_line_size)
{
- (*_bfd_error_handler)
+ _bfd_error_handler
(_("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);
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;
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;
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;
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;
}
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:
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;
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);
}
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);
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;
+ /* PR 19872: A version number of 0 probably means that there is padding
+ at the end of the .debug_info section. Gold puts it there when
+ performing an incremental link, for example. So do not generate
+ an error, just return a NULL. */
+ if (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 NULL;
}
if (addr_size > sizeof (bfd_vma))
{
- (*_bfd_error_handler)
+ _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;
+ return NULL;
}
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);
- return 0;
+ return NULL;
}
/* Read the abbrevs for this compilation unit into a table. */
abbrevs = read_abbrevs (abfd, abbrev_offset, stash);
if (! abbrevs)
- return 0;
+ return NULL;
abbrev_number = safe_read_leb128 (abfd, info_ptr, &bytes_read, FALSE, end_ptr);
info_ptr += bytes_read;
if (! abbrev_number)
{
- (*_bfd_error_handler) (_("Dwarf Error: Bad abbrev number: %u."),
- abbrev_number);
- bfd_set_error (bfd_error_bad_value);
- return 0;
+ /* PR 19872: An abbrev number of 0 probably means that there is padding
+ at the end of the .debug_abbrev section. Gold puts it there when
+ performing an incremental link, for example. So do not generate
+ an error, just return a NULL. */
+ return NULL;
}
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 0;
+ return NULL;
}
amt = sizeof (struct comp_unit);
/* 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;
}
/* Align the new address to the current section
alignment. */
last_vma = ((last_vma
- + ~((bfd_vma) -1 << sect->alignment_power))
- & ((bfd_vma) -1 << sect->alignment_power));
+ + ~(-((bfd_vma) 1 << sect->alignment_power)))
+ & (-((bfd_vma) 1 << sect->alignment_power)));
sect->vma = last_vma;
last_vma += sz;
}
fail more quickly. */
return FALSE;
+ /* Set BFD_DECOMPRESS to decompress debug sections. */
if ((debug_bfd = bfd_openr (debug_filename, NULL)) == NULL
- || ! bfd_check_format (debug_bfd, bfd_object)
+ || !(debug_bfd->flags |= BFD_DECOMPRESS,
+ bfd_check_format (debug_bfd, bfd_object))
|| (msec = find_debug_info (debug_bfd,
debug_sections, NULL)) == NULL
|| !bfd_generic_link_read_symbols (debug_bfd))
return TRUE;
}
+/* Scan the debug information in PINFO looking for a DW_TAG_subprogram
+ abbrev with a DW_AT_low_pc attached to it. Then lookup that same
+ symbol in SYMBOLS and return the difference between the low_pc and
+ the symbol's address. Returns 0 if no suitable symbol could be found. */
+
+bfd_signed_vma
+_bfd_dwarf2_find_symbol_bias (asymbol ** symbols, void ** pinfo)
+{
+ struct dwarf2_debug *stash;
+ struct comp_unit * unit;
+
+ stash = (struct dwarf2_debug *) *pinfo;
+
+ if (stash == NULL)
+ return 0;
+
+ for (unit = stash->all_comp_units; unit; unit = unit->next_unit)
+ {
+ struct funcinfo * func;
+
+ if (unit->function_table == NULL)
+ {
+ if (unit->line_table == NULL)
+ unit->line_table = decode_line_info (unit, stash);
+ if (unit->line_table != NULL)
+ scan_unit_for_symbols (unit);
+ }
+
+ for (func = unit->function_table; func != NULL; func = func->prev_func)
+ if (func->name && func->arange.low)
+ {
+ asymbol ** psym;
+
+ /* FIXME: Do we need to scan the aranges looking for the lowest pc value ? */
+
+ for (psym = symbols; * psym != NULL; psym++)
+ {
+ asymbol * sym = * psym;
+
+ if (sym->flags & BSF_FUNCTION
+ && sym->section != NULL
+ && strcmp (sym->name, func->name) == 0)
+ return ((bfd_signed_vma) func->arange.low) -
+ ((bfd_signed_vma) (sym->value + sym->section->vma));
+ }
+ }
+ }
+
+ return 0;
+}
+
/* Find the source code location of SYMBOL. If SYMBOL is NULL
then find the nearest source code location corresponding to
the address SECTION + OFFSET.
done:
if (function)
{
- if (!function->is_linkage
- && _bfd_elf_find_function (abfd, symbols, section, offset,
- *filename_ptr ? NULL : filename_ptr,
- functionname_ptr))
+ if (!function->is_linkage)
{
- function->name = *functionname_ptr;
+ asymbol *fun;
+ bfd_vma sec_vma;
+
+ fun = _bfd_elf_find_function (abfd, symbols, section, offset,
+ *filename_ptr ? NULL : filename_ptr,
+ functionname_ptr);
+ sec_vma = section->vma;
+ if (section->output_section != NULL)
+ sec_vma = section->output_section->vma + section->output_offset;
+ if (fun != NULL
+ && fun->value + sec_vma == function->arange.low)
+ function->name = *functionname_ptr;
+ /* Even if we didn't find a linkage name, say that we have
+ to stop a repeated search of symbols. */
function->is_linkage = TRUE;
}
- else
- *functionname_ptr = function->name;
+ *functionname_ptr = function->name;
}
if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
unset_sections (stash);
/* Find the function to a particular section and offset,
for error reporting. */
-bfd_boolean
+asymbol *
_bfd_elf_find_function (bfd *abfd,
asymbol **symbols,
asection *section,
} *cache;
if (symbols == NULL)
- return FALSE;
+ return NULL;
if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
- return FALSE;
+ return NULL;
cache = elf_tdata (abfd)->elf_find_function_cache;
if (cache == NULL)
cache = bfd_zalloc (abfd, sizeof (*cache));
elf_tdata (abfd)->elf_find_function_cache = cache;
if (cache == NULL)
- return FALSE;
+ return NULL;
}
if (cache->last_section != section
|| cache->func == NULL
}
if (cache->func == NULL)
- return FALSE;
+ return NULL;
if (filename_ptr)
*filename_ptr = cache->filename;
if (functionname_ptr)
*functionname_ptr = bfd_asymbol_name (cache->func);
- return TRUE;
+ return cache->func;
}