From e2f6d27741cf176ba409df2c74952a4089dc521d Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Mon, 23 Sep 2002 16:13:52 +0000 Subject: [PATCH] Update to correctly decode (non-standard DWARF2) out-of-order address sequences. --- bfd/ChangeLog | 6 +++ bfd/dwarf2.c | 124 +++++++++++++++++++++++++++++----------------------------- 2 files changed, 67 insertions(+), 63 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 1512d1d..6a31f77 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2002-09-23 Nathan Tallent + + * 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 * config.bfd: For DJGPP targets, match with any cpu and any machine. diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c index 1cdd461..5aadadd 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; -- 2.7.4