X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=bfd%2Fdwarf2.c;h=f129e0b60cb551c83087feb854c60116b20e9cd5;hb=1ee24f278e993baa8b732aa8b600dc0369210e3d;hp=550f005bfa4b743db4c91572ea2a76da4530ed2c;hpb=51b9608c3acc602ef72802af90521aa42e2ea44b;p=binutils-gdb.git 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; }