PR29573, addr2line doesn't display file/line for local symbols
authorAlan Modra <amodra@gmail.com>
Wed, 21 Sep 2022 05:24:49 +0000 (14:54 +0930)
committerAlan Modra <amodra@gmail.com>
Wed, 21 Sep 2022 06:38:38 +0000 (16:08 +0930)
The DWARF standard is clear that DW_AT_linkage_name is optional.
Compilers may not provide the attribute on functions and variables,
even though the language mangles names.  g++ does not for local
variables and functions.  Without DW_AT_linkage_name, mangled object
file symbols can't be directly matched against the source-level
DW_AT_name in DWARF info.  One possibility is demangling the object
file symbols, but that comes with its own set of problems:
1) A demangler might not be available for the compiler/language.
2) Demangling doesn't give the source function name as stored in
   DW_AT_name.  Class and template parameters must be stripped at
   least.

So this patch takes a simpler approach.  A symbol matches DWARF info
if the DWARF address matches the symbol address, and if the symbol
name contains the DWARF name as a sub-string.  Very likely the name
matching is entirely superfluous.

PR 29573
* dwarf.c (lookup_symbol_in_function_table): Match a symbol
containing the DWARF source name as a substring.
(lookup_symbol_in_variable_table): Likewise.
(_bfd_dwarf2_find_nearest_line_with_alt): If stash_find_line_fast
returns false, fall back to comp_unit_find_line.

bfd/dwarf2.c

index b8dad5cb3f496f62deaa6172aa888371ef7bb206..4a6a1e40185bff7363c8b9f5148341561b61b24b 100644 (file)
@@ -3379,7 +3379,7 @@ lookup_symbol_in_function_table (struct comp_unit *unit,
          && arange->high - arange->low < best_fit_len
          && each->file
          && each->name
-         && strcmp (name, each->name) == 0)
+         && strstr (name, each->name) != NULL)
        {
          best_fit = each;
          best_fit_len = arange->high - arange->low;
@@ -3415,7 +3415,7 @@ lookup_symbol_in_variable_table (struct comp_unit *unit,
        && !each->stack
        && each->file != NULL
        && each->name != NULL
-       && strcmp (name, each->name) == 0)
+       && strstr (name, each->name) != NULL)
       break;
 
   if (each)
@@ -5867,25 +5867,23 @@ _bfd_dwarf2_find_nearest_line_with_alt
 
       if (stash->info_hash_status == STASH_INFO_HASH_ON)
        {
-         found = stash_find_line_fast (stash, symbol, addr, filename_ptr,
-                                       linenumber_ptr);
+         found = stash_find_line_fast (stash, symbol, addr,
+                                       filename_ptr, linenumber_ptr);
          if (found)
            goto done;
        }
-      else
-       {
-         /* Check the previously read comp. units first.  */
-         for (each = stash->f.all_comp_units; each; each = each->next_unit)
-           if ((symbol->flags & BSF_FUNCTION) == 0
-               || each->arange.high == 0
-               || comp_unit_contains_address (each, addr))
-             {
-               found = comp_unit_find_line (each, symbol, addr, filename_ptr,
-                                            linenumber_ptr);
-               if (found)
-                 goto done;
-             }
-       }
+
+      /* Check the previously read comp. units first.  */
+      for (each = stash->f.all_comp_units; each; each = each->next_unit)
+       if ((symbol->flags & BSF_FUNCTION) == 0
+           || each->arange.high == 0
+           || comp_unit_contains_address (each, addr))
+         {
+           found = comp_unit_find_line (each, symbol, addr, filename_ptr,
+                                        linenumber_ptr);
+           if (found)
+             goto done;
+         }
     }
   else
     {