{
bfd_vma total_length;
unsigned short version;
- unsigned int prologue_length;
+ bfd_vma prologue_length;
unsigned char minimum_instruction_length;
unsigned char default_is_stmt;
int line_base;
static struct abbrev_info *lookup_abbrev
PARAMS ((unsigned int, struct abbrev_info **));
static struct abbrev_info **read_abbrevs
- PARAMS ((bfd *, unsigned int, struct dwarf2_debug *));
+ PARAMS ((bfd *, bfd_vma, struct dwarf2_debug *));
static char *read_attribute
PARAMS ((struct attribute *, struct attr_abbrev *,
struct comp_unit *, char *));
static struct line_info_table *decode_line_info
PARAMS ((struct comp_unit *, struct dwarf2_debug *));
static boolean lookup_address_in_line_info_table
- PARAMS ((struct line_info_table *, bfd_vma, const char **, unsigned int *));
+ PARAMS ((struct line_info_table *, bfd_vma, struct funcinfo *,
+ const char **, unsigned int *));
static boolean lookup_address_in_function_table
- PARAMS ((struct funcinfo *, bfd_vma, const char **));
+ PARAMS ((struct funcinfo *, bfd_vma, struct funcinfo **, const char **));
static boolean scan_unit_for_functions PARAMS ((struct comp_unit *));
static bfd_vma find_rela_addend
PARAMS ((bfd *, asection *, bfd_size_type, asymbol**));
if (offset >= stash->dwarf_str_size)
{
- (*_bfd_error_handler) (_("Dwarf Error: DW_FORM_strp offset (%u) greater than or equal to .debug_str size (%u)."),
- offset, stash->dwarf_str_size);
+ (*_bfd_error_handler) (_("Dwarf Error: DW_FORM_strp offset (%lu) greater than or equal to .debug_str size (%lu)."),
+ (unsigned long) offset, stash->dwarf_str_size);
bfd_set_error (bfd_error_bad_value);
return NULL;
}
static struct abbrev_info**
read_abbrevs (abfd, offset, stash)
bfd * abfd;
- unsigned int offset;
+ bfd_vma offset;
struct dwarf2_debug *stash;
{
struct abbrev_info **abbrevs;
if (offset >= stash->dwarf_abbrev_size)
{
- (*_bfd_error_handler) (_("Dwarf Error: Abbrev offset (%u) greater than or equal to .debug_abbrev size (%u)."),
- offset, stash->dwarf_abbrev_size);
+ (*_bfd_error_handler) (_("Dwarf Error: Abbrev offset (%lu) greater than or equal to .debug_abbrev size (%lu)."),
+ (unsigned long) offset, stash->dwarf_abbrev_size);
bfd_set_error (bfd_error_bad_value);
return 0;
}
info_ptr = read_attribute_value (attr, form, unit, info_ptr);
break;
default:
- (*_bfd_error_handler) (_("Dwarf Error: Invalid or unhandled FORM value: %d."),
+ (*_bfd_error_handler) (_("Dwarf Error: Invalid or unhandled FORM value: %u."),
form);
bfd_set_error (bfd_error_bad_value);
}
struct line_info* last_line;
};
+struct funcinfo
+{
+ struct funcinfo *prev_func;
+ char* name;
+ bfd_vma low;
+ bfd_vma high;
+};
+
static void
add_line_info (table, address, filename, line, column, end_sequence)
struct line_info_table* table;
below. */
if (unit->line_offset >= stash->dwarf_line_size)
{
- (*_bfd_error_handler) (_("Dwarf Error: Line offset (%u) greater than or equal to .debug_line size (%u)."),
+ (*_bfd_error_handler) (_("Dwarf Error: Line offset (%lu) greater than or equal to .debug_line size (%lu)."),
unit->line_offset, stash->dwarf_line_size);
bfd_set_error (bfd_error_bad_value);
return 0;
line_ptr += 8;
offset_size = 8;
}
+ else if (lh.total_length == 0 && unit->addr_size == 8)
+ {
+ /* Handle (non-standard) 64-bit DWARF2 formats. */
+ lh.total_length = read_4_bytes (abfd, line_ptr);
+ line_ptr += 4;
+ offset_size = 8;
+ }
line_end = line_ptr + lh.total_length;
lh.version = read_2_bytes (abfd, line_ptr);
line_ptr += 2;
static boolean
lookup_address_in_line_info_table (table,
addr,
+ function,
filename_ptr,
linenumber_ptr)
struct line_info_table* table;
bfd_vma addr;
+ struct funcinfo *function;
const char **filename_ptr;
unsigned int *linenumber_ptr;
{
if (!each_line->end_sequence
&& addr >= each_line->address && addr < next_line->address)
{
- *filename_ptr = each_line->filename;
- *linenumber_ptr = each_line->line;
+ /* If this line appears to span functions, and addr is in the
+ later function, return the first line of that function instead
+ of the last line of the earlier one. This check is for GCC
+ 2.95, which emits the first line number for a function late. */
+ if (function != NULL
+ && each_line->address < function->low
+ && next_line->address > function->low)
+ {
+ *filename_ptr = next_line->filename;
+ *linenumber_ptr = next_line->line;
+ }
+ else
+ {
+ *filename_ptr = each_line->filename;
+ *linenumber_ptr = each_line->line;
+ }
return true;
}
next_line = each_line;
each_line = each_line->prev_line;
}
+ /* At this point each_line is NULL but next_line is not. If we found the
+ containing function in this compilation unit, return the first line we
+ have a number for. This is also for compatibility with GCC 2.95. */
+ if (function != NULL)
+ {
+ *filename_ptr = next_line->filename;
+ *linenumber_ptr = next_line->line;
+ return true;
+ }
+
return false;
}
/* Function table functions. */
-struct funcinfo
-{
- struct funcinfo *prev_func;
- char* name;
- bfd_vma low;
- bfd_vma high;
-};
-
/* If ADDR is within TABLE, set FUNCTIONNAME_PTR, and return true. */
static boolean
lookup_address_in_function_table (table,
addr,
+ function_ptr,
functionname_ptr)
struct funcinfo* table;
bfd_vma addr;
+ struct funcinfo** function_ptr;
const char **functionname_ptr;
{
struct funcinfo* each_func;
if (addr >= each_func->low && addr < each_func->high)
{
*functionname_ptr = each_func->name;
+ *function_ptr = each_func;
return true;
}
}
abbrev = lookup_abbrev (abbrev_number,unit->abbrevs);
if (! abbrev)
{
- (*_bfd_error_handler) (_("Dwarf Error: Could not find abbrev number %d."),
+ (*_bfd_error_handler) (_("Dwarf Error: Could not find abbrev number %u."),
abbrev_number);
bfd_set_error (bfd_error_bad_value);
return false;
unsigned int offset_size;
{
struct comp_unit* unit;
- unsigned short version;
- unsigned int abbrev_offset = 0;
- unsigned char addr_size;
+ unsigned int version;
+ bfd_vma abbrev_offset = 0;
+ unsigned int addr_size;
struct abbrev_info** abbrevs;
unsigned int abbrev_number, bytes_read, i;
struct abbrev_info *abbrev;
if (version != 2)
{
- (*_bfd_error_handler) (_("Dwarf Error: found dwarf version '%hu', this reader only handles version 2 information."), version);
+ (*_bfd_error_handler) (_("Dwarf Error: found dwarf version '%u', this reader only handles version 2 information."), version);
bfd_set_error (bfd_error_bad_value);
return 0;
}
{
(*_bfd_error_handler) (_("Dwarf Error: found address size '%u', this reader can not handle sizes greater than '%u'."),
addr_size,
- sizeof (bfd_vma));
+ (unsigned int) sizeof (bfd_vma));
bfd_set_error (bfd_error_bad_value);
return 0;
}
info_ptr += bytes_read;
if (! abbrev_number)
{
- (*_bfd_error_handler) (_("Dwarf Error: Bad abbrev number: %d."),
+ (*_bfd_error_handler) (_("Dwarf Error: Bad abbrev number: %u."),
abbrev_number);
bfd_set_error (bfd_error_bad_value);
return 0;
abbrev = lookup_abbrev (abbrev_number, abbrevs);
if (! abbrev)
{
- (*_bfd_error_handler) (_("Dwarf Error: Could not find abbrev number %d."),
+ (*_bfd_error_handler) (_("Dwarf Error: Could not find abbrev number %u."),
abbrev_number);
bfd_set_error (bfd_error_bad_value);
return 0;
{
boolean line_p;
boolean func_p;
+ struct funcinfo *function;
if (unit->error)
return false;
}
}
+ function = NULL;
+ func_p = lookup_address_in_function_table (unit->function_table,
+ addr,
+ &function,
+ functionname_ptr);
line_p = lookup_address_in_line_info_table (unit->line_table,
addr,
+ function,
filename_ptr,
linenumber_ptr);
- func_p = lookup_address_in_function_table (unit->function_table,
- addr,
- functionname_ptr);
return line_p || func_p;
}