Blame SOURCES/rhbz1237098.patch

9e3eb6
commit 6121861509bf5862b2869c71c7d1bbf618f45d46
9e3eb6
Author: Josh Stone <jistone@redhat.com>
9e3eb6
Date:   Mon Jul 6 11:35:51 2015 -0700
9e3eb6
9e3eb6
    PR18555: prefer linkage_name to match the symtab
9e3eb6
    
9e3eb6
    DW_AT_name is usually only the same as the symbol table for C.  C++
9e3eb6
    names are mangled, which may be given by DW_AT_linkage_name.  So if we
9e3eb6
    want to compare a DWARF subprogram to the symbol table by name, we
9e3eb6
    should prefer the linkage name when it's available.
9e3eb6
    
9e3eb6
    This mattered especially for ppc64le, where query_dwarf_func was trying
9e3eb6
    to apply the global/local symbol offset.  When we took a DWARF C++
9e3eb6
    function and tried to find that name in the symbol table for its offset,
9e3eb6
    there was no match, so the function wouldn't be resolved at all.
9e3eb6
    
9e3eb6
    Now that lookup uses the linkage name.  If there's still no match, like
9e3eb6
    with a stripped symbol table, then it falls through to just use DWARF's
9e3eb6
    entrypc as usual.
9e3eb6
    
9e3eb6
    This patch also maintains the raw "addr" and offset "entrypc" separately
9e3eb6
    for symbol table functions, so for instance update_symtab can still
9e3eb6
    compare the original address.
9e3eb6
9e3eb6
diff --git a/tapsets.cxx b/tapsets.cxx
9e3eb6
index fed4166..54f9d3d 100644
9e3eb6
--- a/tapsets.cxx
9e3eb6
+++ b/tapsets.cxx
9e3eb6
@@ -415,7 +415,7 @@ symbol_table
9e3eb6
   // Set to SHN_UNDEF if there is no such section.
9e3eb6
   GElf_Word opd_section;
9e3eb6
   void add_symbol(const char *name, bool weak, bool descriptor,
9e3eb6
-                  Dwarf_Addr addr, Dwarf_Addr *high_addr);
9e3eb6
+                  Dwarf_Addr addr, Dwarf_Addr entrypc);
9e3eb6
   enum info_status get_from_elf();
9e3eb6
   void prepare_section_rejection(Dwfl_Module *mod);
9e3eb6
   bool reject_section(GElf_Word section);
9e3eb6
@@ -1068,19 +1068,19 @@ query_symtab_func_info (func_info & fi, dwarf_query * q)
9e3eb6
 {
9e3eb6
   assert(null_die(&fi.die));
9e3eb6
 
9e3eb6
-  Dwarf_Addr addr = fi.addr;
9e3eb6
+  Dwarf_Addr entrypc = fi.entrypc;
9e3eb6
 
9e3eb6
   // Now compensate for the dw bias because the addresses come
9e3eb6
-  // from dwfl_module_symtab, so fi->addr is NOT a normal dw address.
9e3eb6
+  // from dwfl_module_symtab, so fi->entrypc is NOT a normal dw address.
9e3eb6
   q->dw.get_module_dwarf(false, false);
9e3eb6
-  addr -= q->dw.module_bias;
9e3eb6
+  entrypc -= q->dw.module_bias;
9e3eb6
 
9e3eb6
   // If there are already probes in this module, lets not duplicate.
9e3eb6
   // This can come from other weak symbols/aliases or existing
9e3eb6
-  // matches from Dwarf DIE functions.  Try to add this addr to the
9e3eb6
+  // matches from Dwarf DIE functions.  Try to add this entrypc to the
9e3eb6
   // collection, and only continue if it was new.
9e3eb6
-  if (q->alias_dupes.insert(addr).second)
9e3eb6
-    query_func_info(addr, fi, q);
9e3eb6
+  if (q->alias_dupes.insert(entrypc).second)
9e3eb6
+    query_func_info(entrypc, fi, q);
9e3eb6
 }
9e3eb6
 
9e3eb6
 void
9e3eb6
@@ -2059,7 +2059,7 @@ query_dwarf_inline_instance (Dwarf_Die * die, dwarf_query * q)
9e3eb6
 }
9e3eb6
 
9e3eb6
 static bool
9e3eb6
-is_filtered_func_exists (func_info_map_t filtered, func_info *fi)
9e3eb6
+is_filtered_func_exists (func_info_map_t const& filtered, func_info *fi)
9e3eb6
 {
9e3eb6
   for (unsigned i = 0; i < filtered.size(); i++)
9e3eb6
     {
9e3eb6
@@ -2135,16 +2135,22 @@ query_dwarf_func (Dwarf_Die * func, dwarf_query * q)
9e3eb6
           if ((em->e_machine == EM_PPC64) && ((em->e_flags & EF_PPC64_ABI) == 2)
9e3eb6
               && (q->dw.mod_info->sym_table))
9e3eb6
             {
9e3eb6
-              set<func_info *> fis = q->dw.mod_info->sym_table->lookup_symbol(func.name);
9e3eb6
+              /* The linkage name is the best match for the symbol table. */
9e3eb6
+              const string& linkage_name = dwarf_linkage_name(&func.die)
9e3eb6
+                ?: dwarf_diename(&func.die) ?: func.name;
9e3eb6
+
9e3eb6
+              set<func_info *> fis = q->dw.mod_info->sym_table->lookup_symbol(linkage_name);
9e3eb6
               for (set<func_info*>::iterator it=fis.begin(); it!=fis.end() ; ++it)
9e3eb6
                 {
9e3eb6
-                  func.entrypc = (*it)->addr;
9e3eb6
+                  func.entrypc = (*it)->entrypc;
9e3eb6
                   if (is_filtered_func_exists(q->filtered_functions, &func))
9e3eb6
                     continue;
9e3eb6
                   q->filtered_functions.push_back(func);
9e3eb6
                 }
9e3eb6
             }
9e3eb6
-          else if (!func.entrypc && q->dw.function_entrypc (&entrypc))
9e3eb6
+
9e3eb6
+          /* If not ppc64 or not found in sym_table, try it directly. */
9e3eb6
+          if (!func.entrypc && q->dw.function_entrypc (&entrypc))
9e3eb6
             {
9e3eb6
               func.entrypc = entrypc;
9e3eb6
               q->filtered_functions.push_back (func);
9e3eb6
@@ -8201,7 +8207,7 @@ symbol_table::~symbol_table()
9e3eb6
 
9e3eb6
 void
9e3eb6
 symbol_table::add_symbol(const char *name, bool weak, bool descriptor,
9e3eb6
-                         Dwarf_Addr addr, Dwarf_Addr* /*high_addr*/)
9e3eb6
+                         Dwarf_Addr addr, Dwarf_Addr entrypc)
9e3eb6
 {
9e3eb6
   /* Does the target architecture have function descriptors?
9e3eb6
      Then we want to filter them out. When seeing a symbol with a name
9e3eb6
@@ -8224,6 +8230,7 @@ symbol_table::add_symbol(const char *name, bool weak, bool descriptor,
9e3eb6
     }
9e3eb6
 
9e3eb6
   func_info *fi = new func_info();
9e3eb6
+  fi->entrypc = entrypc;
9e3eb6
   fi->addr = addr;
9e3eb6
   fi->name = name;
9e3eb6
   fi->weak = weak;
9e3eb6
@@ -8288,7 +8295,6 @@ symbol_table::reject_section(GElf_Word section)
9e3eb6
 enum info_status
9e3eb6
 symbol_table::get_from_elf()
9e3eb6
 {
9e3eb6
-  Dwarf_Addr high_addr = 0;
9e3eb6
   Dwfl_Module *mod = mod_info->mod;
9e3eb6
   int syments = dwfl_module_getsymtab(mod);
9e3eb6
   assert(syments);
9e3eb6
@@ -8336,13 +8342,14 @@ symbol_table::get_from_elf()
9e3eb6
       *
9e3eb6
       * st_other field is currently only used with ABIv2 on ppc64
9e3eb6
       */
9e3eb6
+      Dwarf_Addr entrypc = addr;
9e3eb6
       if ((em->e_machine == EM_PPC64) && ((em->e_flags & EF_PPC64_ABI) == 2)
9e3eb6
           && (GELF_ST_TYPE(sym.st_info) == STT_FUNC) && sym.st_other)
9e3eb6
-        addr += PPC64_LOCAL_ENTRY_OFFSET(sym.st_other);
9e3eb6
+        entrypc += PPC64_LOCAL_ENTRY_OFFSET(sym.st_other);
9e3eb6
 
9e3eb6
       if (name && GELF_ST_TYPE(sym.st_info) == STT_FUNC)
9e3eb6
         add_symbol(name, (GELF_ST_BIND(sym.st_info) == STB_WEAK),
9e3eb6
-                   reject, addr, &high_addr);
9e3eb6
+                   reject, addr, entrypc);
9e3eb6
       if (name && GELF_ST_TYPE(sym.st_info) == STT_OBJECT
9e3eb6
                && GELF_ST_BIND(sym.st_info) == STB_GLOBAL)
9e3eb6
         globals[name] = addr;
9e3eb6
@@ -8486,12 +8493,13 @@ module_info::update_symtab(cu_function_cache_t *funcs)
9e3eb6
           continue;
9e3eb6
         }
9e3eb6
 
9e3eb6
-      // XXX We may want to make additional efforts to match mangled elf names
9e3eb6
-      // to dwarf too.  MIPS_linkage_name can help, but that's sometimes
9e3eb6
+      // We need to make additional efforts to match mangled elf names to dwarf
9e3eb6
+      // too.  DW_AT_linkage_name (or w/ MIPS) can help, but that's sometimes
9e3eb6
       // missing, so we may also need to try matching by address.  See also the
9e3eb6
       // notes about _Z in dwflpp::iterate_over_functions().
9e3eb6
+      const string& name = dwarf_linkage_name(&func->second) ?: func->first;
9e3eb6
 
9e3eb6
-      set<func_info*> fis = sym_table->lookup_symbol(func->first);
9e3eb6
+      set<func_info*> fis = sym_table->lookup_symbol(name);
9e3eb6
       if (fis.empty())
9e3eb6
         continue;
9e3eb6