From 1ee24f278e993baa8b732aa8b600dc0369210e3d Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Wed, 20 Mar 2002 19:15:30 +0000 Subject: [PATCH] 2002-03-20 Daniel Jacobowitz * 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. --- bfd/ChangeLog | 13 +++++++++++ bfd/dwarf2.c | 64 +++++++++++++++++++++++++++++++++++++++------------ bfd/syms.c | 15 +++++++++--- 3 files changed, 74 insertions(+), 18 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 13dc43bd698..d559557c18f 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,16 @@ +2002-03-20 Daniel Jacobowitz + + * 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 * coff-rs6000.c (_bfd_xcoff_stat_arch_elt): Renamed from diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c index 550f005bfa4..f129e0b60cb 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 f0ffaa5a33f..4309c0d94f8 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; } -- 2.30.2