diff options
author | Jim Wilson <wilson@tuliptree.org> | 2005-09-22 19:50:27 +0000 |
---|---|---|
committer | Jim Wilson <wilson@tuliptree.org> | 2005-09-22 19:50:27 +0000 |
commit | c955f9cdcb2a9dba8a598dda71a9f8d37a17c641 (patch) | |
tree | fe05ca98deb77f2f7c2cd79c97850d01848d9d1b | |
parent | 82b19eb91fb133174b1a6d35e65b7178c6106a94 (diff) | |
download | gdb-c955f9cdcb2a9dba8a598dda71a9f8d37a17c641.zip gdb-c955f9cdcb2a9dba8a598dda71a9f8d37a17c641.tar.gz gdb-c955f9cdcb2a9dba8a598dda71a9f8d37a17c641.tar.bz2 |
Fix addr2line -i problem; reports incorrect function nesting for inline funcs.
* dwarf2.c (struct funcinfo): Delete nesting_level field.
(lookup_address_in_function_table): Delete code to set funcinfo
caller_func field. Delete local curr_func.
(scan_unit_for_symbols): New locals nested_funcs, nested_funcs_size.
Delete code setting funcinfo nesting_level field. Add code to set
funcinfo caller_func field.
-rw-r--r-- | bfd/ChangeLog | 9 | ||||
-rw-r--r-- | bfd/dwarf2.c | 67 |
2 files changed, 53 insertions, 23 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index ad1c251..9828b5e 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2005-09-22 James E. Wilson <wilson@specifix.com> + + * dwarf2.c (struct funcinfo): Delete nesting_level field. + (lookup_address_in_function_table): Delete code to set funcinfo + caller_func field. Delete local curr_func. + (scan_unit_for_symbols): New locals nested_funcs, nested_funcs_size. + Delete code setting funcinfo nesting_level field. Add code to set + funcinfo caller_func field. + 2005-09-20 James E. Wilson <wilson@specifix.com> * dwarf2.c (find_abstract_instance_name): Don't early exit when name diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c index ca792f4..5cfcc90 100644 --- a/bfd/dwarf2.c +++ b/bfd/dwarf2.c @@ -722,7 +722,6 @@ struct funcinfo char *file; /* Source location file name */ int line; /* Source location line number */ int tag; - int nesting_level; char *name; struct arange arange; asection *sec; /* Where the symbol is defined */ @@ -1431,28 +1430,8 @@ lookup_address_in_function_table (struct comp_unit *unit, if (best_fit) { - struct funcinfo* curr_func = best_fit; - *functionname_ptr = best_fit->name; *function_ptr = best_fit; - - /* If we found a match and it is a function that was inlined, - traverse the function list looking for the function at the - next higher scope and save a pointer to it for future use. - Note that because of the way the DWARF info is generated, and - the way we build the function list, the first function at the - next higher level is the one we want. */ - - for (each_func = best_fit -> prev_func; - each_func && (curr_func->tag == DW_TAG_inlined_subroutine); - each_func = each_func->prev_func) - { - if (each_func->nesting_level < curr_func->nesting_level) - { - curr_func->caller_func = each_func; - curr_func = each_func; - } - } return TRUE; } else @@ -1645,6 +1624,16 @@ scan_unit_for_symbols (struct comp_unit *unit) bfd *abfd = unit->abfd; bfd_byte *info_ptr = unit->first_child_die_ptr; int nesting_level = 1; + struct funcinfo **nested_funcs; + int nested_funcs_size; + + /* Maintain a stack of in-scope functions and inlined functions, which we + can use to set the caller_func field. */ + nested_funcs_size = 32; + nested_funcs = bfd_malloc (nested_funcs_size * sizeof (struct funcinfo *)); + if (nested_funcs == NULL) + return FALSE; + nested_funcs[nesting_level] = 0; while (nesting_level) { @@ -1671,6 +1660,7 @@ scan_unit_for_symbols (struct comp_unit *unit) (*_bfd_error_handler) (_("Dwarf Error: Could not find abbrev number %u."), abbrev_number); bfd_set_error (bfd_error_bad_value); + free (nested_funcs); return FALSE; } @@ -1682,9 +1672,17 @@ scan_unit_for_symbols (struct comp_unit *unit) bfd_size_type amt = sizeof (struct funcinfo); func = bfd_zalloc (abfd, amt); func->tag = abbrev->tag; - func->nesting_level = nesting_level; func->prev_func = unit->function_table; unit->function_table = func; + + if (func->tag == DW_TAG_inlined_subroutine) + for (i = nesting_level - 1; i >= 1; i--) + if (nested_funcs[i]) + { + func->caller_func = nested_funcs[i]; + break; + } + nested_funcs[nesting_level] = func; } else { @@ -1698,6 +1696,9 @@ scan_unit_for_symbols (struct comp_unit *unit) var->prev_var = unit->variable_table; unit->variable_table = var; } + + /* No inline function in scope at this nesting level. */ + nested_funcs[nesting_level] = 0; } for (i = 0; i < abbrev->num_attrs; ++i) @@ -1818,9 +1819,29 @@ scan_unit_for_symbols (struct comp_unit *unit) } if (abbrev->has_children) - nesting_level++; + { + nesting_level++; + + if (nesting_level >= nested_funcs_size) + { + struct funcinfo **tmp; + + nested_funcs_size *= 2; + tmp = bfd_realloc (nested_funcs, + (nested_funcs_size + * sizeof (struct funcinfo *))); + if (tmp == NULL) + { + free (nested_funcs); + return FALSE; + } + nested_funcs = tmp; + } + nested_funcs[nesting_level] = 0; + } } + free (nested_funcs); return TRUE; } |