mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-26 05:47:26 +08:00
* dwarf2.c (find_line): New. Contains the duplicated code from:
(_bfd_dwarf2_find_nearest_line): Use it. (_bfd_dwarf2_find_line): Use it.
This commit is contained in:
@ -1,3 +1,9 @@
|
|||||||
|
2007-06-26 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
* dwarf2.c (find_line): New. Contains the duplicated code from:
|
||||||
|
(_bfd_dwarf2_find_nearest_line): Use it.
|
||||||
|
(_bfd_dwarf2_find_line): Use it.
|
||||||
|
|
||||||
2007-06-26 Joseph Myers <joseph@codesourcery.com>
|
2007-06-26 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
* elf32-arm.c (copy_eabi_attributes): Copy type of attributes.
|
* elf32-arm.c (copy_eabi_attributes): Copy type of attributes.
|
||||||
|
347
bfd/dwarf2.c
347
bfd/dwarf2.c
@ -2301,17 +2301,23 @@ place_sections (bfd *abfd, struct dwarf2_debug *stash)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The DWARF2 version of find_nearest_line. Return TRUE if the line
|
/* Find the source code location of SYMBOL. If SYMBOL is NULL
|
||||||
is found without error. ADDR_SIZE is the number of bytes in the
|
then find the nearest source code location corresponding to
|
||||||
initial .debug_info length field and in the abbreviation offset.
|
the address SECTION + OFFSET.
|
||||||
You may use zero to indicate that the default value should be
|
Returns TRUE if the line is found without error and fills in
|
||||||
used. */
|
FILENAME_PTR and LINENUMBER_PTR. In the case where SYMBOL was
|
||||||
|
NULL the FUNCTIONNAME_PTR is also filled in.
|
||||||
|
SYMBOLS contains the symbol table for ABFD.
|
||||||
|
ADDR_SIZE is the number of bytes in the initial .debug_info length
|
||||||
|
field and in the abbreviation offset, or zero to indicate that the
|
||||||
|
default value should be used. */
|
||||||
|
|
||||||
bfd_boolean
|
static bfd_boolean
|
||||||
_bfd_dwarf2_find_nearest_line (bfd *abfd,
|
find_line (bfd *abfd,
|
||||||
asection *section,
|
asection *section,
|
||||||
asymbol **symbols,
|
|
||||||
bfd_vma offset,
|
bfd_vma offset,
|
||||||
|
asymbol *symbol,
|
||||||
|
asymbol **symbols,
|
||||||
const char **filename_ptr,
|
const char **filename_ptr,
|
||||||
const char **functionname_ptr,
|
const char **functionname_ptr,
|
||||||
unsigned int *linenumber_ptr,
|
unsigned int *linenumber_ptr,
|
||||||
@ -2331,6 +2337,7 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
|
|||||||
bfd_vma addr;
|
bfd_vma addr;
|
||||||
struct comp_unit* each;
|
struct comp_unit* each;
|
||||||
bfd_vma found = FALSE;
|
bfd_vma found = FALSE;
|
||||||
|
bfd_boolean do_line;
|
||||||
|
|
||||||
stash = *pinfo;
|
stash = *pinfo;
|
||||||
|
|
||||||
@ -2351,7 +2358,22 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_line = (section == NULL
|
||||||
|
&& offset == 0
|
||||||
|
&& functionname_ptr == NULL
|
||||||
|
&& symbol != NULL);
|
||||||
|
if (do_line)
|
||||||
|
{
|
||||||
|
addr = symbol->value;
|
||||||
|
section = bfd_get_section (symbol);
|
||||||
|
}
|
||||||
|
else if (section != NULL
|
||||||
|
&& functionname_ptr != NULL
|
||||||
|
&& symbol == NULL)
|
||||||
addr = offset;
|
addr = offset;
|
||||||
|
else
|
||||||
|
abort ();
|
||||||
|
|
||||||
if (section->output_section)
|
if (section->output_section)
|
||||||
addr += section->output_section->vma + section->output_offset;
|
addr += section->output_section->vma + section->output_offset;
|
||||||
else
|
else
|
||||||
@ -2360,13 +2382,6 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
|
|||||||
*functionname_ptr = NULL;
|
*functionname_ptr = NULL;
|
||||||
*linenumber_ptr = 0;
|
*linenumber_ptr = 0;
|
||||||
|
|
||||||
/* The DWARF2 spec says that the initial length field, and the
|
|
||||||
offset of the abbreviation table, should both be 4-byte values.
|
|
||||||
However, some compilers do things differently. */
|
|
||||||
if (addr_size == 0)
|
|
||||||
addr_size = 4;
|
|
||||||
BFD_ASSERT (addr_size == 4 || addr_size == 8);
|
|
||||||
|
|
||||||
if (! *pinfo)
|
if (! *pinfo)
|
||||||
{
|
{
|
||||||
bfd *debug_bfd;
|
bfd *debug_bfd;
|
||||||
@ -2452,250 +2467,20 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
|
|||||||
|
|
||||||
/* Check the previously read comp. units first. */
|
/* Check the previously read comp. units first. */
|
||||||
for (each = stash->all_comp_units; each; each = each->next_unit)
|
for (each = stash->all_comp_units; each; each = each->next_unit)
|
||||||
if (comp_unit_contains_address (each, addr)
|
|
||||||
&& comp_unit_find_nearest_line (each, addr, filename_ptr,
|
|
||||||
functionname_ptr,
|
|
||||||
linenumber_ptr, stash))
|
|
||||||
{
|
{
|
||||||
found = TRUE;
|
if (do_line)
|
||||||
goto done;
|
found = (((symbol->flags & BSF_FUNCTION) == 0
|
||||||
}
|
|
||||||
|
|
||||||
/* Read each remaining comp. units checking each as they are read. */
|
|
||||||
while (stash->info_ptr < stash->info_ptr_end)
|
|
||||||
{
|
|
||||||
bfd_vma length;
|
|
||||||
unsigned int offset_size = addr_size;
|
|
||||||
bfd_byte *info_ptr_unit = stash->info_ptr;
|
|
||||||
|
|
||||||
length = read_4_bytes (stash->bfd, stash->info_ptr);
|
|
||||||
/* A 0xffffff length is the DWARF3 way of indicating we use
|
|
||||||
64-bit offsets, instead of 32-bit offsets. */
|
|
||||||
if (length == 0xffffffff)
|
|
||||||
{
|
|
||||||
offset_size = 8;
|
|
||||||
length = read_8_bytes (stash->bfd, stash->info_ptr + 4);
|
|
||||||
stash->info_ptr += 12;
|
|
||||||
}
|
|
||||||
/* A zero length is the IRIX way of indicating 64-bit offsets,
|
|
||||||
mostly because the 64-bit length will generally fit in 32
|
|
||||||
bits, and the endianness helps. */
|
|
||||||
else if (length == 0)
|
|
||||||
{
|
|
||||||
offset_size = 8;
|
|
||||||
length = read_4_bytes (stash->bfd, stash->info_ptr + 4);
|
|
||||||
stash->info_ptr += 8;
|
|
||||||
}
|
|
||||||
/* In the absence of the hints above, we assume 32-bit DWARF2
|
|
||||||
offsets even for targets with 64-bit addresses, because:
|
|
||||||
a) most of the time these targets will not have generated
|
|
||||||
more than 2Gb of debug info and so will not need 64-bit
|
|
||||||
offsets,
|
|
||||||
and
|
|
||||||
b) if they do use 64-bit offsets but they are not using
|
|
||||||
the size hints that are tested for above then they are
|
|
||||||
not conforming to the DWARF3 standard anyway. */
|
|
||||||
else if (addr_size == 8)
|
|
||||||
{
|
|
||||||
offset_size = 4;
|
|
||||||
stash->info_ptr += 4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
stash->info_ptr += 4;
|
|
||||||
|
|
||||||
if (length > 0)
|
|
||||||
{
|
|
||||||
each = parse_comp_unit (stash, length, info_ptr_unit,
|
|
||||||
offset_size);
|
|
||||||
stash->info_ptr += length;
|
|
||||||
|
|
||||||
if ((bfd_vma) (stash->info_ptr - stash->sec_info_ptr)
|
|
||||||
== stash->sec->size)
|
|
||||||
{
|
|
||||||
stash->sec = find_debug_info (stash->bfd, stash->sec);
|
|
||||||
stash->sec_info_ptr = stash->info_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (each)
|
|
||||||
{
|
|
||||||
each->next_unit = stash->all_comp_units;
|
|
||||||
stash->all_comp_units = each;
|
|
||||||
|
|
||||||
/* DW_AT_low_pc and DW_AT_high_pc are optional for
|
|
||||||
compilation units. If we don't have them (i.e.,
|
|
||||||
unit->high == 0), we need to consult the line info
|
|
||||||
table to see if a compilation unit contains the given
|
|
||||||
address. */
|
|
||||||
if ((each->arange.high == 0
|
|
||||||
|| comp_unit_contains_address (each, addr))
|
|| comp_unit_contains_address (each, addr))
|
||||||
|
&& comp_unit_find_line (each, symbol, addr,
|
||||||
|
filename_ptr, linenumber_ptr,
|
||||||
|
stash));
|
||||||
|
else
|
||||||
|
found = (comp_unit_contains_address (each, addr)
|
||||||
&& comp_unit_find_nearest_line (each, addr,
|
&& comp_unit_find_nearest_line (each, addr,
|
||||||
filename_ptr,
|
filename_ptr,
|
||||||
functionname_ptr,
|
functionname_ptr,
|
||||||
linenumber_ptr,
|
linenumber_ptr,
|
||||||
stash))
|
stash));
|
||||||
{
|
|
||||||
found = TRUE;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
|
|
||||||
unset_sections (stash);
|
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The DWARF2 version of find_line. Return TRUE if the line is found
|
|
||||||
without error. */
|
|
||||||
|
|
||||||
bfd_boolean
|
|
||||||
_bfd_dwarf2_find_line (bfd *abfd,
|
|
||||||
asymbol **symbols,
|
|
||||||
asymbol *symbol,
|
|
||||||
const char **filename_ptr,
|
|
||||||
unsigned int *linenumber_ptr,
|
|
||||||
unsigned int addr_size,
|
|
||||||
void **pinfo)
|
|
||||||
{
|
|
||||||
/* Read each compilation unit from the section .debug_info, and check
|
|
||||||
to see if it contains the address we are searching for. If yes,
|
|
||||||
lookup the address, and return the line number info. If no, go
|
|
||||||
on to the next compilation unit.
|
|
||||||
|
|
||||||
We keep a list of all the previously read compilation units, and
|
|
||||||
a pointer to the next un-read compilation unit. Check the
|
|
||||||
previously read units before reading more. */
|
|
||||||
struct dwarf2_debug *stash;
|
|
||||||
/* What address are we looking for? */
|
|
||||||
bfd_vma addr;
|
|
||||||
struct comp_unit* each;
|
|
||||||
asection *section;
|
|
||||||
bfd_boolean found = FALSE;
|
|
||||||
|
|
||||||
section = bfd_get_section (symbol);
|
|
||||||
|
|
||||||
stash = *pinfo;
|
|
||||||
|
|
||||||
if (! stash)
|
|
||||||
{
|
|
||||||
bfd_size_type amt = sizeof (struct dwarf2_debug);
|
|
||||||
|
|
||||||
stash = bfd_zalloc (abfd, amt);
|
|
||||||
if (! stash)
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* In a relocatable file, 2 functions may have the same address.
|
|
||||||
We change the section vma so that they won't overlap. */
|
|
||||||
if (!stash && (abfd->flags & (EXEC_P | DYNAMIC)) == 0)
|
|
||||||
{
|
|
||||||
if (! place_sections (abfd, stash))
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
addr = symbol->value;
|
|
||||||
if (section->output_section)
|
|
||||||
addr += section->output_section->vma + section->output_offset;
|
|
||||||
else
|
|
||||||
addr += section->vma;
|
|
||||||
|
|
||||||
*filename_ptr = NULL;
|
|
||||||
*filename_ptr = NULL;
|
|
||||||
*linenumber_ptr = 0;
|
|
||||||
|
|
||||||
if (! *pinfo)
|
|
||||||
{
|
|
||||||
bfd *debug_bfd;
|
|
||||||
bfd_size_type total_size;
|
|
||||||
asection *msec;
|
|
||||||
|
|
||||||
*pinfo = stash;
|
|
||||||
|
|
||||||
msec = find_debug_info (abfd, NULL);
|
|
||||||
if (msec == NULL)
|
|
||||||
{
|
|
||||||
char * debug_filename = bfd_follow_gnu_debuglink (abfd, DEBUGDIR);
|
|
||||||
|
|
||||||
if (debug_filename == NULL)
|
|
||||||
/* No dwarf2 info, and no gnu_debuglink to follow.
|
|
||||||
Note that at this point the stash has been allocated, but
|
|
||||||
contains zeros. This lets future calls to this function
|
|
||||||
fail more quickly. */
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
if ((debug_bfd = bfd_openr (debug_filename, NULL)) == NULL
|
|
||||||
|| ! bfd_check_format (debug_bfd, bfd_object)
|
|
||||||
|| (msec = find_debug_info (debug_bfd, NULL)) == NULL)
|
|
||||||
{
|
|
||||||
if (debug_bfd)
|
|
||||||
bfd_close (debug_bfd);
|
|
||||||
/* FIXME: Should we report our failure to follow the debuglink ? */
|
|
||||||
free (debug_filename);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
debug_bfd = abfd;
|
|
||||||
|
|
||||||
/* There can be more than one DWARF2 info section in a BFD these days.
|
|
||||||
Read them all in and produce one large stash. We do this in two
|
|
||||||
passes - in the first pass we just accumulate the section sizes.
|
|
||||||
In the second pass we read in the section's contents. The allows
|
|
||||||
us to avoid reallocing the data as we add sections to the stash. */
|
|
||||||
for (total_size = 0; msec; msec = find_debug_info (debug_bfd, msec))
|
|
||||||
total_size += msec->size;
|
|
||||||
|
|
||||||
stash->info_ptr = bfd_alloc (debug_bfd, total_size);
|
|
||||||
if (stash->info_ptr == NULL)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
stash->info_ptr_end = stash->info_ptr;
|
|
||||||
|
|
||||||
for (msec = find_debug_info (debug_bfd, NULL);
|
|
||||||
msec;
|
|
||||||
msec = find_debug_info (debug_bfd, msec))
|
|
||||||
{
|
|
||||||
bfd_size_type size;
|
|
||||||
bfd_size_type start;
|
|
||||||
|
|
||||||
size = msec->size;
|
|
||||||
if (size == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
start = stash->info_ptr_end - stash->info_ptr;
|
|
||||||
|
|
||||||
if ((bfd_simple_get_relocated_section_contents
|
|
||||||
(debug_bfd, msec, stash->info_ptr + start, symbols)) == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
stash->info_ptr_end = stash->info_ptr + start + size;
|
|
||||||
}
|
|
||||||
|
|
||||||
BFD_ASSERT (stash->info_ptr_end == stash->info_ptr + total_size);
|
|
||||||
|
|
||||||
stash->sec = find_debug_info (debug_bfd, NULL);
|
|
||||||
stash->sec_info_ptr = stash->info_ptr;
|
|
||||||
stash->syms = symbols;
|
|
||||||
stash->bfd = debug_bfd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* A null info_ptr indicates that there is no dwarf2 info
|
|
||||||
(or that an error occured while setting up the stash). */
|
|
||||||
if (! stash->info_ptr)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
stash->inliner_chain = NULL;
|
|
||||||
|
|
||||||
/* Check the previously read comp. units first. */
|
|
||||||
for (each = stash->all_comp_units; each; each = each->next_unit)
|
|
||||||
if ((symbol->flags & BSF_FUNCTION) == 0
|
|
||||||
|| comp_unit_contains_address (each, addr))
|
|
||||||
{
|
|
||||||
found = comp_unit_find_line (each, symbol, addr, filename_ptr,
|
|
||||||
linenumber_ptr, stash);
|
|
||||||
if (found)
|
if (found)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -2715,8 +2500,8 @@ _bfd_dwarf2_find_line (bfd *abfd,
|
|||||||
bfd_byte *info_ptr_unit = stash->info_ptr;
|
bfd_byte *info_ptr_unit = stash->info_ptr;
|
||||||
|
|
||||||
length = read_4_bytes (stash->bfd, stash->info_ptr);
|
length = read_4_bytes (stash->bfd, stash->info_ptr);
|
||||||
/* A 0xffffff length is the DWARF3 way of indicating we use
|
/* A 0xffffff length is the DWARF3 way of indicating
|
||||||
64-bit offsets, instead of 32-bit offsets. */
|
we use 64-bit offsets, instead of 32-bit offsets. */
|
||||||
if (length == 0xffffffff)
|
if (length == 0xffffffff)
|
||||||
{
|
{
|
||||||
offset_size = 8;
|
offset_size = 8;
|
||||||
@ -2772,13 +2557,22 @@ _bfd_dwarf2_find_line (bfd *abfd,
|
|||||||
unit->high == 0), we need to consult the line info
|
unit->high == 0), we need to consult the line info
|
||||||
table to see if a compilation unit contains the given
|
table to see if a compilation unit contains the given
|
||||||
address. */
|
address. */
|
||||||
|
if (do_line)
|
||||||
found = (((symbol->flags & BSF_FUNCTION) == 0
|
found = (((symbol->flags & BSF_FUNCTION) == 0
|
||||||
|| each->arange.high <= 0
|
|| each->arange.high == 0
|
||||||
|| comp_unit_contains_address (each, addr))
|
|| comp_unit_contains_address (each, addr))
|
||||||
&& comp_unit_find_line (each, symbol, addr,
|
&& comp_unit_find_line (each, symbol, addr,
|
||||||
filename_ptr,
|
filename_ptr,
|
||||||
linenumber_ptr,
|
linenumber_ptr,
|
||||||
stash));
|
stash));
|
||||||
|
else
|
||||||
|
found = ((each->arange.high == 0
|
||||||
|
|| comp_unit_contains_address (each, addr))
|
||||||
|
&& comp_unit_find_nearest_line (each, addr,
|
||||||
|
filename_ptr,
|
||||||
|
functionname_ptr,
|
||||||
|
linenumber_ptr,
|
||||||
|
stash));
|
||||||
if (found)
|
if (found)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -2792,6 +2586,42 @@ done:
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The DWARF2 version of find_nearest_line.
|
||||||
|
Return TRUE if the line is found without error. */
|
||||||
|
|
||||||
|
bfd_boolean
|
||||||
|
_bfd_dwarf2_find_nearest_line (bfd *abfd,
|
||||||
|
asection *section,
|
||||||
|
asymbol **symbols,
|
||||||
|
bfd_vma offset,
|
||||||
|
const char **filename_ptr,
|
||||||
|
const char **functionname_ptr,
|
||||||
|
unsigned int *linenumber_ptr,
|
||||||
|
unsigned int addr_size,
|
||||||
|
void **pinfo)
|
||||||
|
{
|
||||||
|
return find_line (abfd, section, offset, NULL, symbols, filename_ptr,
|
||||||
|
functionname_ptr, linenumber_ptr, addr_size,
|
||||||
|
pinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The DWARF2 version of find_line.
|
||||||
|
Return TRUE if the line is found without error. */
|
||||||
|
|
||||||
|
bfd_boolean
|
||||||
|
_bfd_dwarf2_find_line (bfd *abfd,
|
||||||
|
asymbol **symbols,
|
||||||
|
asymbol *symbol,
|
||||||
|
const char **filename_ptr,
|
||||||
|
unsigned int *linenumber_ptr,
|
||||||
|
unsigned int addr_size,
|
||||||
|
void **pinfo)
|
||||||
|
{
|
||||||
|
return find_line (abfd, NULL, 0, symbol, symbols, filename_ptr,
|
||||||
|
NULL, linenumber_ptr, addr_size,
|
||||||
|
pinfo);
|
||||||
|
}
|
||||||
|
|
||||||
bfd_boolean
|
bfd_boolean
|
||||||
_bfd_dwarf2_find_inliner_info (bfd *abfd ATTRIBUTE_UNUSED,
|
_bfd_dwarf2_find_inliner_info (bfd *abfd ATTRIBUTE_UNUSED,
|
||||||
const char **filename_ptr,
|
const char **filename_ptr,
|
||||||
@ -2805,17 +2635,18 @@ _bfd_dwarf2_find_inliner_info (bfd *abfd ATTRIBUTE_UNUSED,
|
|||||||
if (stash)
|
if (stash)
|
||||||
{
|
{
|
||||||
struct funcinfo *func = stash->inliner_chain;
|
struct funcinfo *func = stash->inliner_chain;
|
||||||
|
|
||||||
if (func && func->caller_func)
|
if (func && func->caller_func)
|
||||||
{
|
{
|
||||||
*filename_ptr = func->caller_file;
|
*filename_ptr = func->caller_file;
|
||||||
*functionname_ptr = func->caller_func->name;
|
*functionname_ptr = func->caller_func->name;
|
||||||
*linenumber_ptr = func->caller_line;
|
*linenumber_ptr = func->caller_line;
|
||||||
stash->inliner_chain = func->caller_func;
|
stash->inliner_chain = func->caller_func;
|
||||||
return (TRUE);
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (FALSE);
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Reference in New Issue
Block a user