mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-26 04:15:28 +00: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:
parent
3d3e6f9a7c
commit
bec42b1574
@ -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>
|
||||
|
||||
* elf32-arm.c (copy_eabi_attributes): Copy type of attributes.
|
||||
|
385
bfd/dwarf2.c
385
bfd/dwarf2.c
@ -2301,22 +2301,28 @@ place_sections (bfd *abfd, struct dwarf2_debug *stash)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* The DWARF2 version of find_nearest_line. Return TRUE if the line
|
||||
is found without error. ADDR_SIZE is the number of bytes in the
|
||||
initial .debug_info length field and in the abbreviation offset.
|
||||
You may use zero to indicate that the default value should be
|
||||
used. */
|
||||
/* Find the source code location of SYMBOL. If SYMBOL is NULL
|
||||
then find the nearest source code location corresponding to
|
||||
the address SECTION + OFFSET.
|
||||
Returns TRUE if the line is found without error and fills in
|
||||
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
|
||||
_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)
|
||||
static bfd_boolean
|
||||
find_line (bfd *abfd,
|
||||
asection *section,
|
||||
bfd_vma offset,
|
||||
asymbol *symbol,
|
||||
asymbol **symbols,
|
||||
const char **filename_ptr,
|
||||
const char **functionname_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,
|
||||
@ -2331,6 +2337,7 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
|
||||
bfd_vma addr;
|
||||
struct comp_unit* each;
|
||||
bfd_vma found = FALSE;
|
||||
bfd_boolean do_line;
|
||||
|
||||
stash = *pinfo;
|
||||
|
||||
@ -2351,7 +2358,22 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
addr = offset;
|
||||
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;
|
||||
else
|
||||
abort ();
|
||||
|
||||
if (section->output_section)
|
||||
addr += section->output_section->vma + section->output_offset;
|
||||
else
|
||||
@ -2360,13 +2382,6 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
|
||||
*functionname_ptr = NULL;
|
||||
*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)
|
||||
{
|
||||
bfd *debug_bfd;
|
||||
@ -2452,254 +2467,24 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
|
||||
|
||||
/* Check the previously read comp. units first. */
|
||||
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;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
if (do_line)
|
||||
found = (((symbol->flags & BSF_FUNCTION) == 0
|
||||
|| comp_unit_contains_address (each, addr))
|
||||
&& comp_unit_find_line (each, symbol, addr,
|
||||
filename_ptr, linenumber_ptr,
|
||||
stash));
|
||||
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_find_nearest_line (each, addr,
|
||||
filename_ptr,
|
||||
functionname_ptr,
|
||||
linenumber_ptr,
|
||||
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)
|
||||
found = (comp_unit_contains_address (each, addr)
|
||||
&& comp_unit_find_nearest_line (each, addr,
|
||||
filename_ptr,
|
||||
functionname_ptr,
|
||||
linenumber_ptr,
|
||||
stash));
|
||||
if (found)
|
||||
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)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
@ -2715,8 +2500,8 @@ _bfd_dwarf2_find_line (bfd *abfd,
|
||||
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. */
|
||||
/* 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;
|
||||
@ -2772,13 +2557,22 @@ _bfd_dwarf2_find_line (bfd *abfd,
|
||||
unit->high == 0), we need to consult the line info
|
||||
table to see if a compilation unit contains the given
|
||||
address. */
|
||||
found = (((symbol->flags & BSF_FUNCTION) == 0
|
||||
|| each->arange.high <= 0
|
||||
|| comp_unit_contains_address (each, addr))
|
||||
&& comp_unit_find_line (each, symbol, addr,
|
||||
filename_ptr,
|
||||
linenumber_ptr,
|
||||
stash));
|
||||
if (do_line)
|
||||
found = (((symbol->flags & BSF_FUNCTION) == 0
|
||||
|| each->arange.high == 0
|
||||
|| comp_unit_contains_address (each, addr))
|
||||
&& comp_unit_find_line (each, symbol, addr,
|
||||
filename_ptr,
|
||||
linenumber_ptr,
|
||||
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)
|
||||
goto done;
|
||||
}
|
||||
@ -2792,6 +2586,42 @@ done:
|
||||
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_dwarf2_find_inliner_info (bfd *abfd ATTRIBUTE_UNUSED,
|
||||
const char **filename_ptr,
|
||||
@ -2805,17 +2635,18 @@ _bfd_dwarf2_find_inliner_info (bfd *abfd ATTRIBUTE_UNUSED,
|
||||
if (stash)
|
||||
{
|
||||
struct funcinfo *func = stash->inliner_chain;
|
||||
|
||||
if (func && func->caller_func)
|
||||
{
|
||||
*filename_ptr = func->caller_file;
|
||||
*functionname_ptr = func->caller_func->name;
|
||||
*linenumber_ptr = func->caller_line;
|
||||
stash->inliner_chain = func->caller_func;
|
||||
return (TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return (FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
x
Reference in New Issue
Block a user