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>
|
1999-06-26 David Mosberger <davidm@hpl.hp.com>
|
||||||
|
|
||||||
* dwarf2.c (struct dwarf2_debug): Add member dwarf_line_buffer.
|
* 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;
|
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
|
/* 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
|
/* The lowest and higest addresses contained in this compilation
|
||||||
unit as specified in the compilation unit header. */
|
unit as specified in the compilation unit header. */
|
||||||
bfd_vma low;
|
struct arange arange;
|
||||||
bfd_vma high;
|
|
||||||
|
|
||||||
/* The DW_AT_name attribute (for error messages). */
|
/* The DW_AT_name attribute (for error messages). */
|
||||||
char* name;
|
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. */
|
/* Decode the line number information for UNIT. */
|
||||||
|
|
||||||
static struct line_info_table*
|
static struct line_info_table*
|
||||||
|
@ -723,12 +771,6 @@ decode_line_info (unit)
|
||||||
unsigned int i, bytes_read;
|
unsigned int i, bytes_read;
|
||||||
char *cur_file, *cur_dir;
|
char *cur_file, *cur_dir;
|
||||||
unsigned char op_code, extended_op, adj_opcode;
|
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;
|
stash = elf_tdata (abfd)->dwarf2_find_line_info;
|
||||||
|
|
||||||
|
@ -747,11 +789,11 @@ decode_line_info (unit)
|
||||||
|
|
||||||
size = bfd_get_section_size_before_reloc (msec);
|
size = bfd_get_section_size_before_reloc (msec);
|
||||||
stash->dwarf_line_buffer = (char *) bfd_alloc (abfd, size);
|
stash->dwarf_line_buffer = (char *) bfd_alloc (abfd, size);
|
||||||
if (! dwarf_line_buffer)
|
if (! stash->dwarf_line_buffer)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (! bfd_get_section_contents (abfd, msec,
|
if (! bfd_get_section_contents (abfd, msec,
|
||||||
dwarf_line_buffer, 0,
|
stash->dwarf_line_buffer, 0,
|
||||||
size))
|
size))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -856,7 +898,8 @@ decode_line_info (unit)
|
||||||
unsigned int column = 0;
|
unsigned int column = 0;
|
||||||
int is_stmt = lh.default_is_stmt;
|
int is_stmt = lh.default_is_stmt;
|
||||||
int basic_block = 0;
|
int basic_block = 0;
|
||||||
int end_sequence = 0;
|
int end_sequence = 0, need_low_pc = 1;
|
||||||
|
bfd_vma low_pc = 0;
|
||||||
|
|
||||||
/* Decode the table. */
|
/* Decode the table. */
|
||||||
while (! end_sequence)
|
while (! end_sequence)
|
||||||
|
@ -873,7 +916,14 @@ decode_line_info (unit)
|
||||||
{
|
{
|
||||||
case DW_LNE_end_sequence:
|
case DW_LNE_end_sequence:
|
||||||
end_sequence = 1;
|
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;
|
break;
|
||||||
case DW_LNE_set_address:
|
case DW_LNE_set_address:
|
||||||
address = read_address (unit, line_ptr);
|
address = read_address (unit, line_ptr);
|
||||||
|
@ -912,6 +962,11 @@ decode_line_info (unit)
|
||||||
case DW_LNS_copy:
|
case DW_LNS_copy:
|
||||||
add_line_info (table, address, filename, line, column, 0);
|
add_line_info (table, address, filename, line, column, 0);
|
||||||
basic_block = 0;
|
basic_block = 0;
|
||||||
|
if (need_low_pc)
|
||||||
|
{
|
||||||
|
need_low_pc = 0;
|
||||||
|
low_pc = address;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case DW_LNS_advance_pc:
|
case DW_LNS_advance_pc:
|
||||||
address += lh.minimum_instruction_length
|
address += lh.minimum_instruction_length
|
||||||
|
@ -959,25 +1014,14 @@ decode_line_info (unit)
|
||||||
/* append row to matrix using current values */
|
/* append row to matrix using current values */
|
||||||
add_line_info (table, address, filename, line, column, 0);
|
add_line_info (table, address, filename, line, column, 0);
|
||||||
basic_block = 1;
|
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;
|
return table;
|
||||||
}
|
}
|
||||||
|
@ -1275,11 +1319,11 @@ parse_comp_unit (abfd, info_ptr, end_ptr)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_AT_low_pc:
|
case DW_AT_low_pc:
|
||||||
unit->low = DW_ADDR (&attr);
|
unit->arange.low = DW_ADDR (&attr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_AT_high_pc:
|
case DW_AT_high_pc:
|
||||||
unit->high = DW_ADDR (&attr);
|
unit->arange.high = DW_ADDR (&attr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_AT_comp_dir:
|
case DW_AT_comp_dir:
|
||||||
|
@ -1318,8 +1362,20 @@ comp_unit_contains_address (unit, addr)
|
||||||
struct comp_unit* unit;
|
struct comp_unit* unit;
|
||||||
bfd_vma addr;
|
bfd_vma addr;
|
||||||
{
|
{
|
||||||
return ! unit->error
|
struct arange *arange;
|
||||||
&& (addr >= unit->low && addr <= unit->high);
|
|
||||||
|
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;
|
struct comp_unit* each;
|
||||||
|
|
||||||
boolean found;
|
|
||||||
|
|
||||||
*filename_ptr = NULL;
|
*filename_ptr = NULL;
|
||||||
*functionname_ptr = NULL;
|
*functionname_ptr = NULL;
|
||||||
*linenumber_ptr = 0;
|
*linenumber_ptr = 0;
|
||||||
|
@ -1478,31 +1532,16 @@ _bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
|
||||||
/* 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))
|
||||||
if (each->high > 0)
|
return comp_unit_find_nearest_line (each, addr, filename_ptr,
|
||||||
{
|
functionname_ptr, linenumber_ptr);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read each remaining comp. units checking each as they are read. */
|
/* Read each remaining comp. units checking each as they are read. */
|
||||||
while (stash->info_ptr < stash->info_ptr_end)
|
while (stash->info_ptr < stash->info_ptr_end)
|
||||||
{
|
{
|
||||||
struct comp_unit* each;
|
struct comp_unit* each;
|
||||||
unsigned int length;
|
unsigned int length;
|
||||||
|
boolean found;
|
||||||
|
|
||||||
length = read_4_bytes (abfd, stash->info_ptr);
|
length = read_4_bytes (abfd, stash->info_ptr);
|
||||||
stash->info_ptr += 4;
|
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
|
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 (each->high > 0)
|
if (each->arange.high > 0)
|
||||||
{
|
{
|
||||||
if (comp_unit_contains_address (each, addr))
|
if (comp_unit_contains_address (each, addr))
|
||||||
return comp_unit_find_nearest_line (each, addr,
|
return comp_unit_find_nearest_line (each, addr,
|
||||||
|
|
Loading…
Reference in New Issue