mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-22 02:50:08 +08:00
Update to correctly decode (non-standard DWARF2) out-of-order address sequences.
This commit is contained in:
@ -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>
|
2002-09-23 Mark Elbrecht <snowball3@softhome.net>
|
||||||
|
|
||||||
* config.bfd: For DJGPP targets, match with any cpu and any machine.
|
* config.bfd: For DJGPP targets, match with any cpu and any machine.
|
||||||
|
124
bfd/dwarf2.c
124
bfd/dwarf2.c
@ -13,21 +13,21 @@
|
|||||||
based on Fred Fish's (Cygnus Support) implementation of DWARF 1
|
based on Fred Fish's (Cygnus Support) implementation of DWARF 1
|
||||||
support in dwarfread.c
|
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
|
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
|
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
|
the Free Software Foundation; either version 2 of the License, or (at
|
||||||
your option) any later version.
|
your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful, but
|
This program is distributed in the hope that it will be useful, but
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
General Public License for more details.
|
General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
#include "bfd.h"
|
#include "bfd.h"
|
||||||
#include "sysdep.h"
|
#include "sysdep.h"
|
||||||
@ -1084,13 +1084,19 @@ decode_line_info (unit, stash)
|
|||||||
{
|
{
|
||||||
/* State machine registers. */
|
/* State machine registers. */
|
||||||
bfd_vma address = 0;
|
bfd_vma address = 0;
|
||||||
char* filename = concat_filename (table, 1);
|
char * filename = concat_filename (table, 1);
|
||||||
unsigned int line = 1;
|
unsigned int line = 1;
|
||||||
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, need_low_pc = 1;
|
int end_sequence = 0;
|
||||||
bfd_vma low_pc = 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. */
|
/* Decode the table. */
|
||||||
while (! end_sequence)
|
while (! end_sequence)
|
||||||
@ -1099,7 +1105,8 @@ decode_line_info (unit, stash)
|
|||||||
line_ptr += 1;
|
line_ptr += 1;
|
||||||
|
|
||||||
if (op_code >= lh.opcode_base)
|
if (op_code >= lh.opcode_base)
|
||||||
{ /* Special operand. */
|
{
|
||||||
|
/* Special operand. */
|
||||||
adj_opcode = op_code - lh.opcode_base;
|
adj_opcode = op_code - lh.opcode_base;
|
||||||
address += (adj_opcode / lh.line_range)
|
address += (adj_opcode / lh.line_range)
|
||||||
* lh.minimum_instruction_length;
|
* lh.minimum_instruction_length;
|
||||||
@ -1107,29 +1114,30 @@ decode_line_info (unit, stash)
|
|||||||
/* 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)
|
if (low_pc == 0 || address < low_pc)
|
||||||
{
|
low_pc = address;
|
||||||
need_low_pc = 0;
|
if (address > high_pc)
|
||||||
low_pc = address;
|
high_pc = address;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else switch (op_code)
|
else switch (op_code)
|
||||||
{
|
{
|
||||||
case DW_LNS_extended_op:
|
case DW_LNS_extended_op:
|
||||||
line_ptr += 1; /* Ignore length. */
|
/* Ignore length. */
|
||||||
|
line_ptr += 1;
|
||||||
extended_op = read_1_byte (abfd, line_ptr);
|
extended_op = read_1_byte (abfd, line_ptr);
|
||||||
line_ptr += 1;
|
line_ptr += 1;
|
||||||
|
|
||||||
switch (extended_op)
|
switch (extended_op)
|
||||||
{
|
{
|
||||||
case DW_LNE_end_sequence:
|
case DW_LNE_end_sequence:
|
||||||
end_sequence = 1;
|
end_sequence = 1;
|
||||||
add_line_info (table, address, filename, line, column,
|
add_line_info (table, address, filename, line, column,
|
||||||
end_sequence);
|
end_sequence);
|
||||||
if (need_low_pc)
|
arange_add (unit, low_pc, high_pc);
|
||||||
{
|
if (low_pc == 0 || address < low_pc)
|
||||||
need_low_pc = 0;
|
low_pc = address;
|
||||||
low_pc = address;
|
if (address > high_pc)
|
||||||
}
|
high_pc = address;
|
||||||
arange_add (unit, low_pc, address);
|
arange_add (unit, low_pc, address);
|
||||||
break;
|
break;
|
||||||
case DW_LNE_set_address:
|
case DW_LNE_set_address:
|
||||||
@ -1169,11 +1177,10 @@ decode_line_info (unit, stash)
|
|||||||
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)
|
if (low_pc == 0 || address < low_pc)
|
||||||
{
|
low_pc = address;
|
||||||
need_low_pc = 0;
|
if (address > high_pc)
|
||||||
low_pc = address;
|
high_pc = address;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case DW_LNS_advance_pc:
|
case DW_LNS_advance_pc:
|
||||||
address += lh.minimum_instruction_length
|
address += lh.minimum_instruction_length
|
||||||
@ -1188,8 +1195,8 @@ decode_line_info (unit, stash)
|
|||||||
{
|
{
|
||||||
unsigned int file;
|
unsigned int file;
|
||||||
|
|
||||||
/* The file and directory tables are 0 based, the references
|
/* The file and directory tables are 0
|
||||||
are 1 based. */
|
based, the references are 1 based. */
|
||||||
file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
|
file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
|
||||||
line_ptr += bytes_read;
|
line_ptr += bytes_read;
|
||||||
filename = concat_filename (table, file);
|
filename = concat_filename (table, file);
|
||||||
@ -1214,8 +1221,9 @@ decode_line_info (unit, stash)
|
|||||||
line_ptr += 2;
|
line_ptr += 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
{ /* Unknown standard opcode, ignore it. */
|
{
|
||||||
int i;
|
int i;
|
||||||
|
/* Unknown standard opcode, ignore it. */
|
||||||
for (i = 0; i < lh.standard_opcode_lengths[op_code]; i++)
|
for (i = 0; i < lh.standard_opcode_lengths[op_code]; i++)
|
||||||
{
|
{
|
||||||
(void) read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
|
(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. */
|
LINENUMBER_PTR, are pointers to the objects to be filled in. */
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
lookup_address_in_line_info_table (table,
|
lookup_address_in_line_info_table (table, addr, function, filename_ptr,
|
||||||
addr,
|
|
||||||
function,
|
|
||||||
filename_ptr,
|
|
||||||
linenumber_ptr)
|
linenumber_ptr)
|
||||||
struct line_info_table* table;
|
struct line_info_table* table;
|
||||||
bfd_vma addr;
|
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. */
|
/* If ADDR is within TABLE, set FUNCTIONNAME_PTR, and return true. */
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
lookup_address_in_function_table (table,
|
lookup_address_in_function_table (table, addr, function_ptr,
|
||||||
addr,
|
|
||||||
function_ptr,
|
|
||||||
functionname_ptr)
|
functionname_ptr)
|
||||||
struct funcinfo* table;
|
struct funcinfo* table;
|
||||||
bfd_vma addr;
|
bfd_vma addr;
|
||||||
@ -1666,9 +1669,8 @@ comp_unit_contains_address (unit, addr)
|
|||||||
false otherwise. */
|
false otherwise. */
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
comp_unit_find_nearest_line (unit, addr,
|
comp_unit_find_nearest_line (unit, addr, filename_ptr, functionname_ptr,
|
||||||
filename_ptr, functionname_ptr, linenumber_ptr,
|
linenumber_ptr, stash)
|
||||||
stash)
|
|
||||||
struct comp_unit* unit;
|
struct comp_unit* unit;
|
||||||
bfd_vma addr;
|
bfd_vma addr;
|
||||||
const char **filename_ptr;
|
const char **filename_ptr;
|
||||||
@ -1708,26 +1710,23 @@ comp_unit_find_nearest_line (unit, addr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
function = NULL;
|
function = NULL;
|
||||||
func_p = lookup_address_in_function_table (unit->function_table,
|
func_p = lookup_address_in_function_table (unit->function_table, addr,
|
||||||
addr,
|
&function, functionname_ptr);
|
||||||
&function,
|
line_p = lookup_address_in_line_info_table (unit->line_table, addr,
|
||||||
functionname_ptr);
|
function, filename_ptr,
|
||||||
line_p = lookup_address_in_line_info_table (unit->line_table,
|
|
||||||
addr,
|
|
||||||
function,
|
|
||||||
filename_ptr,
|
|
||||||
linenumber_ptr);
|
linenumber_ptr);
|
||||||
return line_p || func_p;
|
return line_p || func_p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Locate a section in a BFD containing debugging info. The search starts from the
|
/* Locate a section in a BFD containing debugging info. The search starts
|
||||||
section after AFTER_SEC, or from the first section in the BFD if AFTER_SEC is
|
from the section after AFTER_SEC, or from the first section in the BFD if
|
||||||
NULL. The search works by examining the names of the sections. There are two
|
AFTER_SEC is NULL. The search works by examining the names of the
|
||||||
permissiable names. The first is .debug_info. This is the standard DWARF2 name.
|
sections. There are two permissiable names. The first is .debug_info.
|
||||||
The second is a prefix .gnu.linkonce.wi. This is a variation on the .debug_info
|
This is the standard DWARF2 name. The second is a prefix .gnu.linkonce.wi.
|
||||||
section which has a checksum describing the contents appended onto the name. This
|
This is a variation on the .debug_info section which has a checksum
|
||||||
allows the linker to identify and discard duplicate debugging sections for
|
describing the contents appended onto the name. This allows the linker to
|
||||||
different compilation units. */
|
identify and discard duplicate debugging sections for different
|
||||||
|
compilation units. */
|
||||||
#define DWARF2_DEBUG_INFO ".debug_info"
|
#define DWARF2_DEBUG_INFO ".debug_info"
|
||||||
#define GNU_LINKONCE_INFO ".gnu.linkonce.wi."
|
#define GNU_LINKONCE_INFO ".gnu.linkonce.wi."
|
||||||
|
|
||||||
@ -1766,8 +1765,7 @@ find_debug_info (abfd, after_sec)
|
|||||||
boolean
|
boolean
|
||||||
_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
|
_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
|
||||||
filename_ptr, functionname_ptr,
|
filename_ptr, functionname_ptr,
|
||||||
linenumber_ptr,
|
linenumber_ptr, addr_size, pinfo)
|
||||||
addr_size, pinfo)
|
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
asection *section;
|
asection *section;
|
||||||
asymbol **symbols;
|
asymbol **symbols;
|
||||||
|
Reference in New Issue
Block a user