/* 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).
* bytes_read_ptr = 0;
return NULL;
}
-
+
if (unit->offset_size == 4)
offset = read_4_bytes (unit->abfd, buf, buf_end);
else
* bytes_read_ptr = 0;
return NULL;
}
-
+
if (unit->offset_size == 4)
offset = read_4_bytes (unit->abfd, buf, buf_end);
else
}
stash->alt_bfd_ptr = debug_bfd;
}
-
+
if (! read_section (unit->stash->alt_bfd_ptr,
stash->debug_sections + debug_str_alt,
NULL, /* FIXME: Do we need to load alternate symbols ? */
}
stash->alt_bfd_ptr = debug_bfd;
}
-
+
if (! read_section (unit->stash->alt_bfd_ptr,
stash->debug_sections + debug_info_alt,
NULL, /* FIXME: Do we need to load alternate symbols ? */
bfd_set_error (bfd_error_bad_value);
return NULL;
}
-
+
line_end = line_ptr + lh.total_length;
-
+
lh.version = read_2_bytes (abfd, line_ptr, line_end);
if (lh.version < 2 || lh.version > 4)
{
bfd_set_error (bfd_error_bad_value);
return NULL;
}
-
+
amt = lh.opcode_base * sizeof (unsigned char);
lh.standard_opcode_lengths = (unsigned char *) bfd_alloc (abfd, amt);
if (ranges_ptr < unit->stash->dwarf_ranges_buffer)
return FALSE;
ranges_end = unit->stash->dwarf_ranges_buffer + unit->stash->dwarf_ranges_size;
-
+
for (;;)
{
bfd_vma low_pc;
bfd_vma high_pc;
/* PR 17512: file: 62cada7d. */
- if (ranges_ptr + 2 * unit->addr_size >= ranges_end)
+ if (ranges_ptr + 2 * unit->addr_size > ranges_end)
return FALSE;
low_pc = read_address (unit, ranges_ptr, ranges_end);
/* PR 17512: file: 9f405d9d. */
if (info_ptr >= info_ptr_end)
goto fail;
-
+
abbrev_number = safe_read_leb128 (abfd, info_ptr, &bytes_read, FALSE, info_ptr_end);
info_ptr += bytes_read;
/* 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.
found = FALSE;
break;
}
- else
+ else
stash->info_ptr = new_ptr;
-
+
if (stash->all_comp_units)
stash->all_comp_units->prev_unit = each;
else
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;
}