David Mosberger <davidm@hpl.hp.com>
* dwarf2.c (struct arange): New type. (struct comp_unit): Replace LOW and HIGH by member ARANGE. (arange_add): New function. (decode_line_info): Keep track of address ranges that a compilation unit covers. (comp_unit_contains_address): Return true if address is contained in _any_ of the address ranges associated with a compilation unit. (_bfd_dwarf2_find_nearest_line): Call comp_unit_find_nearest_line on the first comp_unit that contains the address.
This commit is contained in:
parent
69dd2e2d55
commit
f623be2b68
@ -1,3 +1,15 @@
|
||||
1999-06-26 David Mosberger <davidm@hpl.hp.com>
|
||||
|
||||
* dwarf2.c (struct arange): New type.
|
||||
(struct comp_unit): Replace LOW and HIGH by member ARANGE.
|
||||
(arange_add): New function.
|
||||
(decode_line_info): Keep track of address ranges that a compilation
|
||||
unit covers.
|
||||
(comp_unit_contains_address): Return true if address is contained
|
||||
in _any_ of the address ranges associated with a compilation unit.
|
||||
(_bfd_dwarf2_find_nearest_line): Call comp_unit_find_nearest_line
|
||||
on the first comp_unit that contains the address.
|
||||
|
||||
1999-06-26 David Mosberger <davidm@hpl.hp.com>
|
||||
|
||||
* dwarf2.c (struct dwarf2_debug): Add member dwarf_line_buffer.
|
||||
|
147
bfd/dwarf2.c
147
bfd/dwarf2.c
@ -104,6 +104,11 @@ struct dwarf2_debug {
|
||||
char *dwarf_line_buffer;
|
||||
};
|
||||
|
||||
struct arange {
|
||||
struct arange *next;
|
||||
bfd_vma low;
|
||||
bfd_vma high;
|
||||
};
|
||||
|
||||
|
||||
/* A minimal decoding of DWARF2 compilation units. We only decode
|
||||
@ -119,8 +124,7 @@ struct comp_unit {
|
||||
|
||||
/* The lowest and higest addresses contained in this compilation
|
||||
unit as specified in the compilation unit header. */
|
||||
bfd_vma low;
|
||||
bfd_vma high;
|
||||
struct arange arange;
|
||||
|
||||
/* The DW_AT_name attribute (for error messages). */
|
||||
char* name;
|
||||
@ -705,6 +709,50 @@ concat_filename (table, file)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
arange_add (unit, low_pc, high_pc)
|
||||
struct comp_unit *unit;
|
||||
bfd_vma low_pc;
|
||||
bfd_vma high_pc;
|
||||
{
|
||||
struct arange *arange;
|
||||
|
||||
/* first see if we can cheaply extend an existing range: */
|
||||
arange = &unit->arange;
|
||||
do
|
||||
{
|
||||
if (low_pc == arange->high)
|
||||
{
|
||||
arange->high = high_pc;
|
||||
return;
|
||||
}
|
||||
if (high_pc == arange->low)
|
||||
{
|
||||
arange->low = low_pc;
|
||||
return;
|
||||
}
|
||||
arange = arange->next;
|
||||
}
|
||||
while (arange);
|
||||
|
||||
if (unit->arange.high == 0)
|
||||
{
|
||||
/* this is the first address range: store it in unit->arange: */
|
||||
unit->arange.next = 0;
|
||||
unit->arange.low = low_pc;
|
||||
unit->arange.high = high_pc;
|
||||
return;
|
||||
}
|
||||
|
||||
/* need to allocate a new arange and insert it into the arange list: */
|
||||
arange = bfd_zalloc (unit->abfd, sizeof (*arange));
|
||||
arange->low = low_pc;
|
||||
arange->high = high_pc;
|
||||
|
||||
arange->next = unit->arange.next;
|
||||
unit->arange.next = arange;
|
||||
}
|
||||
|
||||
/* Decode the line number information for UNIT. */
|
||||
|
||||
static struct line_info_table*
|
||||
@ -723,12 +771,6 @@ decode_line_info (unit)
|
||||
unsigned int i, bytes_read;
|
||||
char *cur_file, *cur_dir;
|
||||
unsigned char op_code, extended_op, adj_opcode;
|
||||
#if 0
|
||||
/* This optimization unfortunately does not work well on programs
|
||||
that have multiple sections containing text (such as Linux which
|
||||
uses .text, and .text.init, for example. */
|
||||
bfd_vma hi_pc = 0, lo_pc = ~ (bfd_vma) 0;
|
||||
#endif
|
||||
|
||||
stash = elf_tdata (abfd)->dwarf2_find_line_info;
|
||||
|
||||
@ -747,11 +789,11 @@ decode_line_info (unit)
|
||||
|
||||
size = bfd_get_section_size_before_reloc (msec);
|
||||
stash->dwarf_line_buffer = (char *) bfd_alloc (abfd, size);
|
||||
if (! dwarf_line_buffer)
|
||||
if (! stash->dwarf_line_buffer)
|
||||
return 0;
|
||||
|
||||
if (! bfd_get_section_contents (abfd, msec,
|
||||
dwarf_line_buffer, 0,
|
||||
stash->dwarf_line_buffer, 0,
|
||||
size))
|
||||
return 0;
|
||||
|
||||
@ -856,7 +898,8 @@ decode_line_info (unit)
|
||||
unsigned int column = 0;
|
||||
int is_stmt = lh.default_is_stmt;
|
||||
int basic_block = 0;
|
||||
int end_sequence = 0;
|
||||
int end_sequence = 0, need_low_pc = 1;
|
||||
bfd_vma low_pc = 0;
|
||||
|
||||
/* Decode the table. */
|
||||
while (! end_sequence)
|
||||
@ -873,7 +916,14 @@ decode_line_info (unit)
|
||||
{
|
||||
case DW_LNE_end_sequence:
|
||||
end_sequence = 1;
|
||||
add_line_info (table, address, filename, line, column, end_sequence);
|
||||
add_line_info (table, address, filename, line, column,
|
||||
end_sequence);
|
||||
if (need_low_pc)
|
||||
{
|
||||
need_low_pc = 0;
|
||||
low_pc = address;
|
||||
}
|
||||
arange_add (unit, low_pc, address);
|
||||
break;
|
||||
case DW_LNE_set_address:
|
||||
address = read_address (unit, line_ptr);
|
||||
@ -912,6 +962,11 @@ decode_line_info (unit)
|
||||
case DW_LNS_copy:
|
||||
add_line_info (table, address, filename, line, column, 0);
|
||||
basic_block = 0;
|
||||
if (need_low_pc)
|
||||
{
|
||||
need_low_pc = 0;
|
||||
low_pc = address;
|
||||
}
|
||||
break;
|
||||
case DW_LNS_advance_pc:
|
||||
address += lh.minimum_instruction_length
|
||||
@ -959,25 +1014,14 @@ decode_line_info (unit)
|
||||
/* append row to matrix using current values */
|
||||
add_line_info (table, address, filename, line, column, 0);
|
||||
basic_block = 1;
|
||||
if (need_low_pc)
|
||||
{
|
||||
need_low_pc = 0;
|
||||
low_pc = address;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
if (unit->high == 0)
|
||||
{
|
||||
if (address > hi_pc)
|
||||
hi_pc = address;
|
||||
if (address < lo_pc)
|
||||
lo_pc = address;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
if (unit->high == 0 && hi_pc != 0)
|
||||
{
|
||||
unit->high = hi_pc;
|
||||
unit->low = lo_pc;
|
||||
}
|
||||
#endif
|
||||
|
||||
return table;
|
||||
}
|
||||
@ -1275,11 +1319,11 @@ parse_comp_unit (abfd, info_ptr, end_ptr)
|
||||
break;
|
||||
|
||||
case DW_AT_low_pc:
|
||||
unit->low = DW_ADDR (&attr);
|
||||
unit->arange.low = DW_ADDR (&attr);
|
||||
break;
|
||||
|
||||
case DW_AT_high_pc:
|
||||
unit->high = DW_ADDR (&attr);
|
||||
unit->arange.high = DW_ADDR (&attr);
|
||||
break;
|
||||
|
||||
case DW_AT_comp_dir:
|
||||
@ -1318,8 +1362,20 @@ comp_unit_contains_address (unit, addr)
|
||||
struct comp_unit* unit;
|
||||
bfd_vma addr;
|
||||
{
|
||||
return ! unit->error
|
||||
&& (addr >= unit->low && addr <= unit->high);
|
||||
struct arange *arange;
|
||||
|
||||
if (unit->error)
|
||||
return 0;
|
||||
|
||||
arange = &unit->arange;
|
||||
do
|
||||
{
|
||||
if (addr >= arange->low && addr < arange->high)
|
||||
return 1;
|
||||
arange = arange->next;
|
||||
}
|
||||
while (arange);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1410,8 +1466,6 @@ _bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
|
||||
|
||||
struct comp_unit* each;
|
||||
|
||||
boolean found;
|
||||
|
||||
*filename_ptr = NULL;
|
||||
*functionname_ptr = NULL;
|
||||
*linenumber_ptr = 0;
|
||||
@ -1478,31 +1532,16 @@ _bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
|
||||
/* Check the previously read comp. units first. */
|
||||
|
||||
for (each = stash->all_comp_units; each; each = each->next_unit)
|
||||
{
|
||||
if (each->high > 0)
|
||||
{
|
||||
if (comp_unit_contains_address (each, addr))
|
||||
return comp_unit_find_nearest_line (each, addr,
|
||||
filename_ptr,
|
||||
functionname_ptr,
|
||||
linenumber_ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
found = comp_unit_find_nearest_line (each, addr,
|
||||
filename_ptr,
|
||||
functionname_ptr,
|
||||
linenumber_ptr);
|
||||
if (found)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (comp_unit_contains_address (each, addr))
|
||||
return comp_unit_find_nearest_line (each, addr, filename_ptr,
|
||||
functionname_ptr, linenumber_ptr);
|
||||
|
||||
/* Read each remaining comp. units checking each as they are read. */
|
||||
while (stash->info_ptr < stash->info_ptr_end)
|
||||
{
|
||||
struct comp_unit* each;
|
||||
unsigned int length;
|
||||
boolean found;
|
||||
|
||||
length = read_4_bytes (abfd, stash->info_ptr);
|
||||
stash->info_ptr += 4;
|
||||
@ -1523,7 +1562,7 @@ _bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
|
||||
unit->high == 0), we need to consult the line info
|
||||
table to see if a compilation unit contains the given
|
||||
address. */
|
||||
if (each->high > 0)
|
||||
if (each->arange.high > 0)
|
||||
{
|
||||
if (comp_unit_contains_address (each, addr))
|
||||
return comp_unit_find_nearest_line (each, addr,
|
||||
|
Loading…
Reference in New Issue
Block a user