aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog13
-rw-r--r--bfd/dwarf2.c64
-rw-r--r--bfd/syms.c15
3 files changed, 74 insertions, 18 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 13dc43b..d559557 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,16 @@
+2002-03-20 Daniel Jacobowitz <drow@mvista.com>
+
+ * dwarf2.c (struct funcinfo): Move up.
+ (lookup_address_in_function_table): New argument function_ptr.
+ Set it.
+ (lookup_address_in_line_table): New argument function. If function
+ is non-NULL, use it to handle ``addr'' before the first line note of
+ the function.
+ (comp_unit_find_nearest_line): Update and swap calls to
+ lookup_address_in_function_table and lookup_address_in_line_table.
+ * syms.c (_bfd_stab_section_find_nearest_line): Use the first
+ N_SLINE encountered if we see an N_FUN before any N_SLINE.
+
2002-03-20 Tom Rix <trix@redhat.com>
* coff-rs6000.c (_bfd_xcoff_stat_arch_elt): Renamed from
diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c
index 550f005..f129e0b 100644
--- a/bfd/dwarf2.c
+++ b/bfd/dwarf2.c
@@ -240,9 +240,10 @@ static void arange_add PARAMS ((struct comp_unit *, bfd_vma, bfd_vma));
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**));
@@ -808,6 +809,14 @@ struct line_info_table
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;
@@ -1215,10 +1224,12 @@ decode_line_info (unit, stash)
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;
{
@@ -1235,35 +1246,53 @@ lookup_address_in_line_info_table (table,
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;
@@ -1275,6 +1304,7 @@ lookup_address_in_function_table (table,
if (addr >= each_func->low && addr < each_func->high)
{
*functionname_ptr = each_func->name;
+ *function_ptr = each_func;
return true;
}
}
@@ -1636,6 +1666,7 @@ comp_unit_find_nearest_line (unit, addr,
{
boolean line_p;
boolean func_p;
+ struct funcinfo *function;
if (unit->error)
return false;
@@ -1664,13 +1695,16 @@ 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,
linenumber_ptr);
- func_p = lookup_address_in_function_table (unit->function_table,
- addr,
- functionname_ptr);
return line_p || func_p;
}
diff --git a/bfd/syms.c b/bfd/syms.c
index f0ffaa5..4309c0d 100644
--- a/bfd/syms.c
+++ b/bfd/syms.c
@@ -1238,9 +1238,11 @@ _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset, pfound,
for (; stab < (indexentry+1)->stab; stab += STABSIZE)
{
- boolean done;
+ boolean done, saw_line, saw_func;
bfd_vma val;
+ saw_line = false;
+ saw_func = false;
done = false;
switch (stab[TYPEOFF])
@@ -1261,7 +1263,11 @@ _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset, pfound,
/* A line number. The value is relative to the start of the
current function. */
val = indexentry->val + bfd_get_32 (abfd, stab + VALOFF);
- if (val <= offset)
+ /* If this line starts before our desired offset, or if it's
+ the first line we've been able to find, use it. The
+ !saw_line check works around a bug in GCC 2.95.3, which emits
+ the first N_SLINE late. */
+ if (!saw_line || val <= offset)
{
*pline = bfd_get_16 (abfd, stab + DESCOFF);
@@ -1274,11 +1280,14 @@ _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset, pfound,
}
if (val > offset)
done = true;
+ saw_line = true;
break;
case N_FUN:
case N_SO:
- done = true;
+ if (saw_func || saw_line)
+ done = true;
+ saw_func = true;
break;
}