summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2002-09-23 16:13:52 +0000
committerNick Clifton <nickc@redhat.com>2002-09-23 16:13:52 +0000
commitd113b7536e3e33296899e8ed908fcd3ef02739b0 (patch)
tree5bf701a7dc0906790534564e6196db02e073cd8e
parentdcbf209754cc62ad119452a976bb4c02b8a33b8c (diff)
downloadgdb-d113b7536e3e33296899e8ed908fcd3ef02739b0.tar.gz
Update to correctly decode (non-standard DWARF2) out-of-order address sequences.
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/dwarf2.c124
2 files changed, 67 insertions, 63 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 1512d1d075c..6a31f773038 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c
index 1cdd46156bb..5aadaddf2b1 100644
--- a/bfd/dwarf2.c
+++ b/bfd/dwarf2.c
@@ -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;
- bfd_vma low_pc = 0;
+ 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;
- low_pc = address;
- }
+ 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;
- low_pc = address;
- }
+ 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;
- low_pc = address;
- }
+ 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;