Update to correctly decode (non-standard DWARF2) out-of-order address sequences.

This commit is contained in:
Nick Clifton 2002-09-23 16:13:52 +00:00
parent 1b67de929e
commit e2f6d27741
2 changed files with 67 additions and 63 deletions

View File

@ -1,3 +1,9 @@
2002-09-23 Nathan Tallent <eraxxon@alumni.rice.edu>
* dwarf2.c (decode_line_info): Update to correctly decode
the (non-standard DWARF2) out-of-order address sequences
generated by the Intel C++ 6.0 compiler for ia64-Linux.
2002-09-23 Mark Elbrecht <snowball3@softhome.net>
* config.bfd: For DJGPP targets, match with any cpu and any machine.

View File

@ -13,21 +13,21 @@
based on Fred Fish's (Cygnus Support) implementation of DWARF 1
support in dwarfread.c
This file is part of BFD.
This file is part of BFD.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h"
#include "sysdep.h"
@ -1084,13 +1084,19 @@ decode_line_info (unit, stash)
{
/* State machine registers. */
bfd_vma address = 0;
char* filename = concat_filename (table, 1);
char * filename = concat_filename (table, 1);
unsigned int line = 1;
unsigned int column = 0;
int is_stmt = lh.default_is_stmt;
int basic_block = 0;
int end_sequence = 0, need_low_pc = 1;
int end_sequence = 0;
/* eraxxon@alumni.rice.edu: Against the DWARF2 specs, some
compilers generate address sequences that are wildly out of
order using DW_LNE_set_address (e.g. Intel C++ 6.0 compiler
for ia64-Linux). Thus, to determine the low and high
address, we must compare on every DW_LNS_copy, etc. */
bfd_vma low_pc = 0;
bfd_vma high_pc = 0;
/* Decode the table. */
while (! end_sequence)
@ -1099,7 +1105,8 @@ decode_line_info (unit, stash)
line_ptr += 1;
if (op_code >= lh.opcode_base)
{ /* Special operand. */
{
/* Special operand. */
adj_opcode = op_code - lh.opcode_base;
address += (adj_opcode / lh.line_range)
* lh.minimum_instruction_length;
@ -1107,29 +1114,30 @@ decode_line_info (unit, stash)
/* 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;
if (low_pc == 0 || address < low_pc)
low_pc = address;
}
if (address > high_pc)
high_pc = address;
}
else switch (op_code)
{
case DW_LNS_extended_op:
line_ptr += 1; /* Ignore length. */
/* Ignore length. */
line_ptr += 1;
extended_op = read_1_byte (abfd, line_ptr);
line_ptr += 1;
switch (extended_op)
{
case DW_LNE_end_sequence:
end_sequence = 1;
add_line_info (table, address, filename, line, column,
end_sequence);
if (need_low_pc)
{
need_low_pc = 0;
arange_add (unit, low_pc, high_pc);
if (low_pc == 0 || address < low_pc)
low_pc = address;
}
if (address > high_pc)
high_pc = address;
arange_add (unit, low_pc, address);
break;
case DW_LNE_set_address:
@ -1169,11 +1177,10 @@ decode_line_info (unit, stash)
case DW_LNS_copy:
add_line_info (table, address, filename, line, column, 0);
basic_block = 0;
if (need_low_pc)
{
need_low_pc = 0;
if (low_pc == 0 || address < low_pc)
low_pc = address;
}
if (address > high_pc)
high_pc = address;
break;
case DW_LNS_advance_pc:
address += lh.minimum_instruction_length
@ -1188,8 +1195,8 @@ decode_line_info (unit, stash)
{
unsigned int file;
/* The file and directory tables are 0 based, the references
are 1 based. */
/* The file and directory tables are 0
based, the references are 1 based. */
file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
line_ptr += bytes_read;
filename = concat_filename (table, file);
@ -1214,8 +1221,9 @@ decode_line_info (unit, stash)
line_ptr += 2;
break;
default:
{ /* Unknown standard opcode, ignore it. */
{
int i;
/* Unknown standard opcode, ignore it. */
for (i = 0; i < lh.standard_opcode_lengths[op_code]; i++)
{
(void) read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
@ -1234,10 +1242,7 @@ decode_line_info (unit, stash)
LINENUMBER_PTR, are pointers to the objects to be filled in. */
static boolean
lookup_address_in_line_info_table (table,
addr,
function,
filename_ptr,
lookup_address_in_line_info_table (table, addr, function, filename_ptr,
linenumber_ptr)
struct line_info_table* table;
bfd_vma addr;
@ -1298,9 +1303,7 @@ lookup_address_in_line_info_table (table,
/* If ADDR is within TABLE, set FUNCTIONNAME_PTR, and return true. */
static boolean
lookup_address_in_function_table (table,
addr,
function_ptr,
lookup_address_in_function_table (table, addr, function_ptr,
functionname_ptr)
struct funcinfo* table;
bfd_vma addr;
@ -1666,9 +1669,8 @@ comp_unit_contains_address (unit, addr)
false otherwise. */
static boolean
comp_unit_find_nearest_line (unit, addr,
filename_ptr, functionname_ptr, linenumber_ptr,
stash)
comp_unit_find_nearest_line (unit, addr, filename_ptr, functionname_ptr,
linenumber_ptr, stash)
struct comp_unit* unit;
bfd_vma addr;
const char **filename_ptr;
@ -1708,26 +1710,23 @@ comp_unit_find_nearest_line (unit, addr,
}
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,
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);
return line_p || func_p;
}
/* 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 sections. There are two
permissiable names. The first is .debug_info. This is the standard DWARF2 name.
The second is a prefix .gnu.linkonce.wi. This is a variation on the .debug_info
section which has a checksum describing the contents appended onto the name. This
allows the linker to identify and discard duplicate debugging sections for
different compilation units. */
/* 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
sections. There are two permissiable names. The first is .debug_info.
This is the standard DWARF2 name. The second is a prefix .gnu.linkonce.wi.
This is a variation on the .debug_info section which has a checksum
describing the contents appended onto the name. This allows the linker to
identify and discard duplicate debugging sections for different
compilation units. */
#define DWARF2_DEBUG_INFO ".debug_info"
#define GNU_LINKONCE_INFO ".gnu.linkonce.wi."
@ -1766,8 +1765,7 @@ find_debug_info (abfd, after_sec)
boolean
_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
filename_ptr, functionname_ptr,
linenumber_ptr,
addr_size, pinfo)
linenumber_ptr, addr_size, pinfo)
bfd *abfd;
asection *section;
asymbol **symbols;