bfd/
2005-06-06 H.J. Lu <hongjiu.lu@intel.com> PR 990 * bfd.c (bfd_find_line): New. * dwarf2.c (comp_unit): Add variable_table. (funcinfo): Add file, line, and sec. (varinfo): New. (lookup_symbol_in_function_table): New. (lookup_symbol_in_variable_table): New. (scan_unit_for_functions): Renamed to ... (scan_unit_for_symbols): This. Handle DW_TAG_entry_point and DW_TAG_variable. (comp_unit_find_nearest_line): Updated. (comp_unit_find_line): New. (_bfd_dwarf2_find_line): New. * elf-bfd.h (_bfd_elf_find_line): New. (_bfd_generic_find_line): New. Defined. * elf.c (_bfd_elf_find_line): New. * libbfd-in.h (_bfd_dwarf2_find_line): New. (_bfd_generic_find_line): New. * bfd-in2.h: Regenerated. * libbfd.h: Likewise. * libbfd.c (_bfd_generic_find_line): New. * targets.c (BFD_JUMP_TABLE_SYMBOLS): Initialize _bfd_find_line with _bfd_generic_find_line. (bfd_target): Add _bfd_find_line. binutils/ 2005-06-06 H.J. Lu <hongjiu.lu@intel.com> PR 990 * nm.c (print_symbol): Call bfd_find_line before bfd_find_nearest_line.
This commit is contained in:
parent
b42f9a05b6
commit
5420f73dbb
12 changed files with 528 additions and 7 deletions
|
@ -1,3 +1,37 @@
|
|||
2005-06-06 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR 990
|
||||
* bfd.c (bfd_find_line): New.
|
||||
|
||||
* dwarf2.c (comp_unit): Add variable_table.
|
||||
(funcinfo): Add file, line, and sec.
|
||||
(varinfo): New.
|
||||
(lookup_symbol_in_function_table): New.
|
||||
(lookup_symbol_in_variable_table): New.
|
||||
(scan_unit_for_functions): Renamed to ...
|
||||
(scan_unit_for_symbols): This. Handle DW_TAG_entry_point and
|
||||
DW_TAG_variable.
|
||||
(comp_unit_find_nearest_line): Updated.
|
||||
(comp_unit_find_line): New.
|
||||
(_bfd_dwarf2_find_line): New.
|
||||
|
||||
* elf-bfd.h (_bfd_elf_find_line): New.
|
||||
(_bfd_generic_find_line): New. Defined.
|
||||
|
||||
* elf.c (_bfd_elf_find_line): New.
|
||||
|
||||
* libbfd-in.h (_bfd_dwarf2_find_line): New.
|
||||
(_bfd_generic_find_line): New.
|
||||
|
||||
* bfd-in2.h: Regenerated.
|
||||
* libbfd.h: Likewise.
|
||||
|
||||
* libbfd.c (_bfd_generic_find_line): New.
|
||||
|
||||
* targets.c (BFD_JUMP_TABLE_SYMBOLS): Initialize _bfd_find_line
|
||||
with _bfd_generic_find_line.
|
||||
(bfd_target): Add _bfd_find_line.
|
||||
|
||||
2005-06-06 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* dwarf2.c (decode_line_info): Properly set low_pc.
|
||||
|
|
|
@ -4307,6 +4307,10 @@ bfd_boolean bfd_set_private_flags (bfd *abfd, flagword flags);
|
|||
BFD_SEND (abfd, _bfd_find_nearest_line, \
|
||||
(abfd, sec, syms, off, file, func, line))
|
||||
|
||||
#define bfd_find_line(abfd, syms, sym, file, line) \
|
||||
BFD_SEND (abfd, _bfd_find_line, \
|
||||
(abfd, syms, sym, file, line))
|
||||
|
||||
#define bfd_find_inliner_info(abfd, file, func, line) \
|
||||
BFD_SEND (abfd, _bfd_find_inliner_info, \
|
||||
(abfd, file, func, line))
|
||||
|
@ -4647,6 +4651,7 @@ typedef struct bfd_target
|
|||
NAME##_bfd_is_target_special_symbol, \
|
||||
NAME##_get_lineno, \
|
||||
NAME##_find_nearest_line, \
|
||||
_bfd_generic_find_line, \
|
||||
NAME##_find_inliner_info, \
|
||||
NAME##_bfd_make_debug_symbol, \
|
||||
NAME##_read_minisymbols, \
|
||||
|
@ -4669,6 +4674,9 @@ typedef struct bfd_target
|
|||
bfd_boolean (*_bfd_find_nearest_line)
|
||||
(bfd *, struct bfd_section *, struct bfd_symbol **, bfd_vma,
|
||||
const char **, const char **, unsigned int *);
|
||||
bfd_boolean (*_bfd_find_line)
|
||||
(bfd *, struct bfd_symbol **, struct bfd_symbol *,
|
||||
const char **, unsigned int *);
|
||||
bfd_boolean (*_bfd_find_inliner_info)
|
||||
(bfd *, const char **, const char **, unsigned int *);
|
||||
/* Back-door to allow format-aware applications to create debug symbols
|
||||
|
|
|
@ -1161,6 +1161,10 @@ DESCRIPTION
|
|||
. BFD_SEND (abfd, _bfd_find_nearest_line, \
|
||||
. (abfd, sec, syms, off, file, func, line))
|
||||
.
|
||||
.#define bfd_find_line(abfd, syms, sym, file, line) \
|
||||
. BFD_SEND (abfd, _bfd_find_line, \
|
||||
. (abfd, syms, sym, file, line))
|
||||
.
|
||||
.#define bfd_find_inliner_info(abfd, file, func, line) \
|
||||
. BFD_SEND (abfd, _bfd_find_inliner_info, \
|
||||
. (abfd, file, func, line))
|
||||
|
|
432
bfd/dwarf2.c
432
bfd/dwarf2.c
|
@ -182,6 +182,9 @@ struct comp_unit
|
|||
/* A list of the functions found in this comp. unit. */
|
||||
struct funcinfo *function_table;
|
||||
|
||||
/* A list of the variables found in this comp. unit. */
|
||||
struct varinfo *variable_table;
|
||||
|
||||
/* Pointer to dwarf2_debug structure. */
|
||||
struct dwarf2_debug *stash;
|
||||
|
||||
|
@ -697,10 +700,29 @@ struct funcinfo
|
|||
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 */
|
||||
int tag;
|
||||
int nesting_level;
|
||||
char *name;
|
||||
struct arange arange;
|
||||
asection *sec; /* Where the symbol is defined */
|
||||
};
|
||||
|
||||
struct varinfo
|
||||
{
|
||||
/* Pointer to previous variable in list of all variables */
|
||||
struct varinfo *prev_var;
|
||||
/* Source location file name */
|
||||
char *file;
|
||||
/* Source location line number */
|
||||
int line;
|
||||
int tag;
|
||||
char *name;
|
||||
/* Where the symbol is defined */
|
||||
asection *sec;
|
||||
/* Is this a stack variable? */
|
||||
unsigned int stack: 1;
|
||||
};
|
||||
|
||||
/* Adds a new entry to the line_info list in the line_info_table, ensuring
|
||||
|
@ -1424,6 +1446,84 @@ lookup_address_in_function_table (struct comp_unit *unit,
|
|||
}
|
||||
}
|
||||
|
||||
/* If SYM at ADDR is within function table of UNIT, set FILENAME_PTR
|
||||
and LINENUMBER_PTR, and return TRUE. */
|
||||
|
||||
static bfd_boolean
|
||||
lookup_symbol_in_function_table (struct comp_unit *unit,
|
||||
asymbol *sym,
|
||||
bfd_vma addr,
|
||||
const char **filename_ptr,
|
||||
unsigned int *linenumber_ptr)
|
||||
{
|
||||
struct funcinfo* each_func;
|
||||
struct funcinfo* best_fit = NULL;
|
||||
struct arange *arange;
|
||||
const char *name = bfd_asymbol_name (sym);
|
||||
asection *sec = bfd_get_section (sym);
|
||||
|
||||
for (each_func = unit->function_table;
|
||||
each_func;
|
||||
each_func = each_func->prev_func)
|
||||
{
|
||||
for (arange = &each_func->arange;
|
||||
arange;
|
||||
arange = arange->next)
|
||||
{
|
||||
if ((!each_func->sec || each_func->sec == sec)
|
||||
&& addr >= arange->low
|
||||
&& addr < arange->high
|
||||
&& strcmp (name, each_func->name) == 0
|
||||
&& (!best_fit
|
||||
|| ((arange->high - arange->low)
|
||||
< (best_fit->arange.high - best_fit->arange.low))))
|
||||
best_fit = each_func;
|
||||
}
|
||||
}
|
||||
|
||||
if (best_fit)
|
||||
{
|
||||
best_fit->sec = sec;
|
||||
*filename_ptr = best_fit->file;
|
||||
*linenumber_ptr = best_fit->line;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Variable table functions. */
|
||||
|
||||
/* If SYM is within variable table of UNIT, set FILENAME_PTR and
|
||||
LINENUMBER_PTR, and return TRUE. */
|
||||
|
||||
static bfd_boolean
|
||||
lookup_symbol_in_variable_table (struct comp_unit *unit,
|
||||
asymbol *sym,
|
||||
const char **filename_ptr,
|
||||
unsigned int *linenumber_ptr)
|
||||
{
|
||||
const char *name = bfd_asymbol_name (sym);
|
||||
asection *sec = bfd_get_section (sym);
|
||||
struct varinfo* each;
|
||||
|
||||
for (each = unit->variable_table; each; each = each->prev_var)
|
||||
if (each->stack == 0
|
||||
&& (!each->sec || each->sec == sec)
|
||||
&& strcmp (name, each->name) == 0)
|
||||
break;
|
||||
|
||||
if (each)
|
||||
{
|
||||
each->sec = sec;
|
||||
*filename_ptr = each->file;
|
||||
*linenumber_ptr = each->line;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static char *
|
||||
find_abstract_instance_name (struct comp_unit *unit, bfd_uint64_t die_ref)
|
||||
{
|
||||
|
@ -1513,10 +1613,10 @@ read_rangelist (struct comp_unit *unit, struct arange *arange, bfd_uint64_t offs
|
|||
/* DWARF2 Compilation unit functions. */
|
||||
|
||||
/* Scan over each die in a comp. unit looking for functions to add
|
||||
to the function table. */
|
||||
to the function table and variables to the variable table. */
|
||||
|
||||
static bfd_boolean
|
||||
scan_unit_for_functions (struct comp_unit *unit)
|
||||
scan_unit_for_symbols (struct comp_unit *unit)
|
||||
{
|
||||
bfd *abfd = unit->abfd;
|
||||
bfd_byte *info_ptr = unit->first_child_die_ptr;
|
||||
|
@ -1528,6 +1628,7 @@ scan_unit_for_functions (struct comp_unit *unit)
|
|||
struct abbrev_info *abbrev;
|
||||
struct attribute attr;
|
||||
struct funcinfo *func;
|
||||
struct varinfo *var;
|
||||
bfd_vma low_pc = 0;
|
||||
bfd_vma high_pc = 0;
|
||||
|
||||
|
@ -1549,7 +1650,9 @@ scan_unit_for_functions (struct comp_unit *unit)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
var = NULL;
|
||||
if (abbrev->tag == DW_TAG_subprogram
|
||||
|| abbrev->tag == DW_TAG_entry_point
|
||||
|| abbrev->tag == DW_TAG_inlined_subroutine)
|
||||
{
|
||||
bfd_size_type amt = sizeof (struct funcinfo);
|
||||
|
@ -1560,7 +1663,18 @@ scan_unit_for_functions (struct comp_unit *unit)
|
|||
unit->function_table = func;
|
||||
}
|
||||
else
|
||||
func = NULL;
|
||||
{
|
||||
func = NULL;
|
||||
if (abbrev->tag == DW_TAG_variable)
|
||||
{
|
||||
bfd_size_type amt = sizeof (struct varinfo);
|
||||
var = bfd_zalloc (abfd, amt);
|
||||
var->tag = abbrev->tag;
|
||||
var->stack = 1;
|
||||
var->prev_var = unit->variable_table;
|
||||
unit->variable_table = var;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < abbrev->num_attrs; ++i)
|
||||
{
|
||||
|
@ -1604,6 +1718,60 @@ scan_unit_for_functions (struct comp_unit *unit)
|
|||
read_rangelist (unit, &func->arange, attr.u.val);
|
||||
break;
|
||||
|
||||
case DW_AT_decl_file:
|
||||
func->file = concat_filename (unit->line_table,
|
||||
attr.u.val);
|
||||
break;
|
||||
|
||||
case DW_AT_decl_line:
|
||||
func->line = attr.u.val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (var)
|
||||
{
|
||||
switch (attr.name)
|
||||
{
|
||||
case DW_AT_name:
|
||||
var->name = attr.u.str;
|
||||
break;
|
||||
|
||||
case DW_AT_decl_file:
|
||||
var->file = concat_filename (unit->line_table,
|
||||
attr.u.val);
|
||||
break;
|
||||
|
||||
case DW_AT_decl_line:
|
||||
var->line = attr.u.val;
|
||||
break;
|
||||
|
||||
case DW_AT_external:
|
||||
if (attr.u.val != 0)
|
||||
var->stack = 0;
|
||||
break;
|
||||
|
||||
case DW_AT_location:
|
||||
if (var->stack)
|
||||
{
|
||||
switch (attr.form)
|
||||
{
|
||||
case DW_FORM_block:
|
||||
case DW_FORM_block1:
|
||||
case DW_FORM_block2:
|
||||
case DW_FORM_block4:
|
||||
if (*attr.u.blk->data == DW_OP_addr)
|
||||
var->stack = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1844,7 +2012,7 @@ comp_unit_find_nearest_line (struct comp_unit *unit,
|
|||
}
|
||||
|
||||
if (unit->first_child_die_ptr < unit->end_ptr
|
||||
&& ! scan_unit_for_functions (unit))
|
||||
&& ! scan_unit_for_symbols (unit))
|
||||
{
|
||||
unit->error = 1;
|
||||
return FALSE;
|
||||
|
@ -1862,6 +2030,58 @@ comp_unit_find_nearest_line (struct comp_unit *unit,
|
|||
return line_p || func_p;
|
||||
}
|
||||
|
||||
/* If UNIT contains SYM at ADDR, set the output parameters to the
|
||||
values for the line containing SYM. The output parameters,
|
||||
FILENAME_PTR, and LINENUMBER_PTR, are pointers to the objects to be
|
||||
filled in.
|
||||
|
||||
Return TRUE if UNIT contains SYM, and no errors were encountered;
|
||||
FALSE otherwise. */
|
||||
|
||||
static bfd_boolean
|
||||
comp_unit_find_line (struct comp_unit *unit,
|
||||
asymbol *sym,
|
||||
bfd_vma addr,
|
||||
const char **filename_ptr,
|
||||
unsigned int *linenumber_ptr,
|
||||
struct dwarf2_debug *stash)
|
||||
{
|
||||
if (unit->error)
|
||||
return FALSE;
|
||||
|
||||
if (! unit->line_table)
|
||||
{
|
||||
if (! unit->stmtlist)
|
||||
{
|
||||
unit->error = 1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
unit->line_table = decode_line_info (unit, stash);
|
||||
|
||||
if (! unit->line_table)
|
||||
{
|
||||
unit->error = 1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (unit->first_child_die_ptr < unit->end_ptr
|
||||
&& ! scan_unit_for_symbols (unit))
|
||||
{
|
||||
unit->error = 1;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (sym->flags & BSF_FUNCTION)
|
||||
return lookup_symbol_in_function_table (unit, sym, addr,
|
||||
filename_ptr,
|
||||
linenumber_ptr);
|
||||
else
|
||||
return lookup_symbol_in_variable_table (unit, sym, filename_ptr,
|
||||
linenumber_ptr);
|
||||
}
|
||||
|
||||
/* Locate a section in a BFD containing debugging info. The search starts
|
||||
from the section after AFTER_SEC, or from the first section in the BFD if
|
||||
AFTER_SEC is NULL. The search works by examining the names of the
|
||||
|
@ -2107,6 +2327,210 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
section = bfd_get_section (symbol);
|
||||
|
||||
addr = symbol->value;
|
||||
if (section->output_section)
|
||||
addr += section->output_section->vma + section->output_offset;
|
||||
else
|
||||
addr += section->vma;
|
||||
|
||||
*filename_ptr = NULL;
|
||||
stash = *pinfo;
|
||||
*filename_ptr = NULL;
|
||||
*linenumber_ptr = 0;
|
||||
|
||||
if (! stash)
|
||||
{
|
||||
bfd_size_type total_size;
|
||||
asection *msec;
|
||||
bfd_size_type amt = sizeof (struct dwarf2_debug);
|
||||
|
||||
stash = bfd_zalloc (abfd, amt);
|
||||
if (! stash)
|
||||
return FALSE;
|
||||
|
||||
*pinfo = stash;
|
||||
|
||||
msec = find_debug_info (abfd, NULL);
|
||||
if (! msec)
|
||||
/* No dwarf2 info. Note that at this point the stash
|
||||
has been allocated, but contains zeros, this lets
|
||||
future calls to this function fail quicker. */
|
||||
return FALSE;
|
||||
|
||||
/* 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 (abfd, msec))
|
||||
total_size += msec->size;
|
||||
|
||||
stash->info_ptr = bfd_alloc (abfd, total_size);
|
||||
if (stash->info_ptr == NULL)
|
||||
return FALSE;
|
||||
|
||||
stash->info_ptr_end = stash->info_ptr;
|
||||
|
||||
for (msec = find_debug_info (abfd, NULL);
|
||||
msec;
|
||||
msec = find_debug_info (abfd, 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
|
||||
(abfd, 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 (abfd, NULL);
|
||||
stash->sec_info_ptr = stash->info_ptr;
|
||||
stash->syms = symbols;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
return FALSE;
|
||||
|
||||
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)
|
||||
return found;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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 (abfd, 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 (abfd, 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 (abfd, stash->info_ptr + 4);
|
||||
stash->info_ptr += 8;
|
||||
}
|
||||
/* In the absence of the hints above, we assume addr_size-sized
|
||||
offsets, for backward-compatibility with pre-DWARF3 64-bit
|
||||
platforms. */
|
||||
else if (addr_size == 8)
|
||||
{
|
||||
length = read_8_bytes (abfd, stash->info_ptr);
|
||||
stash->info_ptr += 8;
|
||||
}
|
||||
else
|
||||
stash->info_ptr += 4;
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
each = parse_comp_unit (abfd, 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 (abfd, 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. */
|
||||
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 (found)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bfd_boolean
|
||||
_bfd_dwarf2_find_inliner_info (bfd *abfd ATTRIBUTE_UNUSED,
|
||||
const char **filename_ptr,
|
||||
|
|
|
@ -1488,6 +1488,9 @@ extern bfd_boolean _bfd_elf_set_arch_mach
|
|||
extern bfd_boolean _bfd_elf_find_nearest_line
|
||||
(bfd *, asection *, asymbol **, bfd_vma, const char **, const char **,
|
||||
unsigned int *);
|
||||
extern bfd_boolean _bfd_elf_find_line
|
||||
(bfd *, asymbol **, asymbol *, const char **, unsigned int *);
|
||||
#define _bfd_generic_find_line _bfd_elf_find_line
|
||||
extern bfd_boolean _bfd_elf_find_inliner_info
|
||||
(bfd *, const char **, const char **, unsigned int *);
|
||||
#define _bfd_elf_read_minisymbols _bfd_generic_read_minisymbols
|
||||
|
|
11
bfd/elf.c
11
bfd/elf.c
|
@ -6672,6 +6672,17 @@ _bfd_elf_find_nearest_line (bfd *abfd,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* Find the line for a symbol. */
|
||||
|
||||
bfd_boolean
|
||||
_bfd_elf_find_line (bfd *abfd, asymbol **symbols, asymbol *symbol,
|
||||
const char **filename_ptr, unsigned int *line_ptr)
|
||||
{
|
||||
return _bfd_dwarf2_find_line (abfd, symbols, symbol,
|
||||
filename_ptr, line_ptr, 0,
|
||||
&elf_tdata (abfd)->dwarf2_find_line_info);
|
||||
}
|
||||
|
||||
/* After a call to bfd_find_nearest_line, successive calls to
|
||||
bfd_find_inliner_info can be used to get source information about
|
||||
each level of function inlining that terminated at the address
|
||||
|
|
|
@ -428,6 +428,14 @@ extern bfd_boolean _bfd_dwarf2_find_nearest_line
|
|||
(bfd *, asection *, asymbol **, bfd_vma, const char **, const char **,
|
||||
unsigned int *, unsigned int, void **);
|
||||
|
||||
/* Find the line using DWARF 2 debugging information. */
|
||||
extern bfd_boolean _bfd_dwarf2_find_line
|
||||
(bfd *, asymbol **, asymbol *, const char **,
|
||||
unsigned int *, unsigned int, void **);
|
||||
|
||||
bfd_boolean _bfd_generic_find_line
|
||||
(bfd *, asymbol **, asymbol *, const char **, unsigned int *);
|
||||
|
||||
/* Find inliner info after calling bfd_find_nearest_line. */
|
||||
extern bfd_boolean _bfd_dwarf2_find_inliner_info
|
||||
(bfd *, const char **, const char **, unsigned int *, void **);
|
||||
|
|
10
bfd/libbfd.c
10
bfd/libbfd.c
|
@ -918,3 +918,13 @@ read_signed_leb128 (bfd *abfd ATTRIBUTE_UNUSED,
|
|||
*bytes_read_ptr = num_read;
|
||||
return result;
|
||||
}
|
||||
|
||||
bfd_boolean
|
||||
_bfd_generic_find_line (bfd *abfd ATTRIBUTE_UNUSED,
|
||||
asymbol **symbols ATTRIBUTE_UNUSED,
|
||||
asymbol *symbol ATTRIBUTE_UNUSED,
|
||||
const char **filename_ptr ATTRIBUTE_UNUSED,
|
||||
unsigned int *linenumber_ptr ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -433,6 +433,14 @@ extern bfd_boolean _bfd_dwarf2_find_nearest_line
|
|||
(bfd *, asection *, asymbol **, bfd_vma, const char **, const char **,
|
||||
unsigned int *, unsigned int, void **);
|
||||
|
||||
/* Find the line using DWARF 2 debugging information. */
|
||||
extern bfd_boolean _bfd_dwarf2_find_line
|
||||
(bfd *, asymbol **, asymbol *, const char **,
|
||||
unsigned int *, unsigned int, void **);
|
||||
|
||||
bfd_boolean _bfd_generic_find_line
|
||||
(bfd *, asymbol **, asymbol *, const char **, unsigned int *);
|
||||
|
||||
/* Find inliner info after calling bfd_find_nearest_line. */
|
||||
extern bfd_boolean _bfd_dwarf2_find_inliner_info
|
||||
(bfd *, const char **, const char **, unsigned int *, void **);
|
||||
|
|
|
@ -349,6 +349,7 @@ BFD_JUMP_TABLE macros.
|
|||
. NAME##_bfd_is_target_special_symbol, \
|
||||
. NAME##_get_lineno, \
|
||||
. NAME##_find_nearest_line, \
|
||||
. _bfd_generic_find_line, \
|
||||
. NAME##_find_inliner_info, \
|
||||
. NAME##_bfd_make_debug_symbol, \
|
||||
. NAME##_read_minisymbols, \
|
||||
|
@ -371,6 +372,9 @@ BFD_JUMP_TABLE macros.
|
|||
. bfd_boolean (*_bfd_find_nearest_line)
|
||||
. (bfd *, struct bfd_section *, struct bfd_symbol **, bfd_vma,
|
||||
. const char **, const char **, unsigned int *);
|
||||
. bfd_boolean (*_bfd_find_line)
|
||||
. (bfd *, struct bfd_symbol **, struct bfd_symbol *,
|
||||
. const char **, unsigned int *);
|
||||
. bfd_boolean (*_bfd_find_inliner_info)
|
||||
. (bfd *, const char **, const char **, unsigned int *);
|
||||
. {* Back-door to allow format-aware applications to create debug symbols
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2005-06-06 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR 990
|
||||
* nm.c (print_symbol): Call bfd_find_line before
|
||||
bfd_find_nearest_line.
|
||||
|
||||
2005-06-06 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* NEWS: Mention new powerpc ld support.
|
||||
|
|
|
@ -905,9 +905,10 @@ print_symbol (bfd *abfd, asymbol *sym, bfd_vma ssize, bfd *archive_bfd)
|
|||
}
|
||||
else if (bfd_get_section (sym)->owner == abfd)
|
||||
{
|
||||
if (bfd_find_nearest_line (abfd, bfd_get_section (sym), syms,
|
||||
sym->value, &filename, &functionname,
|
||||
&lineno)
|
||||
if ((bfd_find_line (abfd, syms, sym, &filename, &lineno)
|
||||
|| bfd_find_nearest_line (abfd, bfd_get_section (sym),
|
||||
syms, sym->value, &filename,
|
||||
&functionname, &lineno))
|
||||
&& filename != NULL
|
||||
&& lineno != 0)
|
||||
printf ("\t%s:%u", filename, lineno);
|
||||
|
|
Loading…
Reference in a new issue