3dc5bde Calling ifunc functions when resolver has debug info, user symbol same name

Authored and Committed by palves 6 years ago
    Calling ifunc functions when resolver has debug info, user symbol same name
    
    In v2:
    
      - find_gnu_ifunc is now based on name search.  Need exposed by
        PP64 (see later patches in the series).
      - Added iterate_over_minimal_symbols function_view overload for
        that, and made it possible to stop the search if the callback says
        so.
    
    If the GNU ifunc resolver has the same name as the user visible
    symbol, and the resolver has debug info, then the DWARF info for the
    resolver masks the ifunc minsym.  In that scenario, if you try calling
    the ifunc from GDB, you call the resolver instead.  With the
    gnu-ifunc.exp testcase added in a following patch, you'd see:
    
      (gdb) p gnu_ifunc (3)
      $1 = (int (*)(int)) 0x400753 <final>
      (gdb) FAIL: gdb.base/gnu-ifunc.exp: resolver_attr=0: resolver_debug=1: resolved_debug=0: p gnu_ifunc (3)
                                                           ^^^^^^^^^^^^^^^^
    
    That is, we called the ifunc resolver manually, which returned a
    pointer to the ifunc target function ("final").  The "final" symbol is
    the function that GDB should have called automatically,
    
      ~~~~~~~~~~~~
      int
      final (int arg)
      {
        return arg + 1;
      }
      ~~~~~~~~~
    
    which is what happens if you don't have debug info for the resolver:
    
      (gdb) p gnu_ifunc (3)
      $1 = 4
      (gdb) PASS: gdb.base/gnu-ifunc.exp: resolver_attr=0: resolver_debug=0: resolved_debug=1: p gnu_ifunc (3)
                                                           ^^^^^^^^^^^^^^^^
    
    or if the resolver's symbol has a different name from the ifunc (as is
    the case with modern uses of ifunc via __attribute__ ifunc, such as
    glibc uses):
    
      (gdb) p gnu_ifunc (3)
      $1 = 4
      (gdb) PASS: gdb.base/gnu-ifunc.exp: resolver_attr=1: resolver_debug=1: resolved_debug=0: p gnu_ifunc (3)
                                          ^^^^^^^^^^^^^^^
    
    in which case after this patch, you can still call the resolver
    directly if you want:
    
      (gdb) p gnu_ifunc_resolver (3)
      $1 = (int (*)(int)) 0x400753 <final>
    
    gdb/ChangeLog:
    yyyy-mm-dd  Pedro Alves  <palves@redhat.com>
    
    	* c-exp.y (variable production): Prefer ifunc minsyms over
    	regular function symbols.
    	* symtab.c (find_gnu_ifunc): New function.
    	* minsyms.h (lookup_msym_prefer): New enum.
    	(lookup_minimal_symbol_by_pc_section): Replace 'want_trampoline'
    	parameter by a lookup_msym_prefer parameter.
    	* symtab.h (find_gnu_ifunc): New declaration.
    
        
file modified
+16 -4
file modified
+3 -0
file modified
+5 -3
file modified
+1 -1
file modified
+32 -0
file modified
+3 -0