[00/11] Fixing GNU ifunc support

Message ID 20180309211612.12941-1-palves@redhat.com
Headers show
Series
  • Fixing GNU ifunc support
Related show

Message

Pedro Alves March 9, 2018, 9:16 p.m.
Jakub Jelinek noticed that on Fedora 28, GDB can't call strlen:

  (top-gdb) p strlen("hello")
  $1 = (size_t (*)(const char *)) 0x7ffff554aac0 <__strlen_avx2>

That's clearly GDB printing the pointer to the ifunc target function
that implements strlen, instead of calling that function and printing
the result...

Suspecting that that might have been caused by my earlier improvements
to calling functions with no debug info, and improved support for
function aliases, I took a look.  And then I started writing a test,
which then uncovered a ton of problems...  All fixed by this series.

The main issue is that GDB's current ifunc support assumes that (and
the testcase exercises that) the resolver must be compiled without
debug info, and that the resolver has the same name as the user
visible function.

However, glibc nowadays implements ifunc resolvers in C using GCC's
__attribute__((ifunc)), and compiles them with debug info.
With __attribute__((ifunc)), the ifunc symbol has the user visible
name, and the resolver gets a regular function symbol with a different
name (what is passed to the attribute).

While fixing that, I thought I'd extend the existing testcase to
exercise all combination of

 - An ifunc set with __attribute__(ifunc) [different name as the
   user-visible symbol], vs set with

     asm (".type gnu_ifunc, %gnu_indirect_function");

   i.e., with the same name as the user-visible symbol.

 - ifunc resolver compiled with and without debug info.

 - ifunc target function compiled with and without debug info.

Of course that uncovered a whole slew of problems...

And then along the way noticed several other issues and added several
tests for them.  The testcase patch is added torward the end of the
series, because I honestly don't think I can effectively split it down
and split chunks into the patches that implement the fix.  Most of the
testcase changes need all the fixes in place to do any meaningful
testing.  The exception is the last patch in the series.

Pedro Alves (11):
  eval.c: reverse minsym and sym
  Fix breakpoints in ifunc after inferior resolved it (@got.plt symbol
    creation)
  Fix calling ifunc functions when resolver has debug info and different
    name
  Calling ifunc functions when target has no debug info but resolver has
  Calling ifunc functions when resolver has debug info, user symbol same
    name
  Fix setting breakpoints on ifunc functions after they're already
    resolved
  Breakpoints, don't skip prologue of ifunc resolvers with debug info
  Eliminate find_pc_partial_function_gnu_ifunc
  Factor out minsym_found/find_function_start_sal overload
  Extend GNU ifunc testcases
  Fix resolving GNU ifunc bp locations when inferior runs resolver

 gdb/blockframe.c                        |  62 +++--
 gdb/breakpoint.c                        |  31 ++-
 gdb/breakpoint.h                        |   8 +
 gdb/c-exp.y                             |  39 +++-
 gdb/elfread.c                           |  15 +-
 gdb/eval.c                              |  33 +--
 gdb/gdbtypes.c                          |   4 -
 gdb/infcall.c                           |  58 +++--
 gdb/infcall.h                           |   9 +-
 gdb/linespec.c                          | 151 ++++++++----
 gdb/minsyms.c                           |  91 ++++----
 gdb/minsyms.h                           |  26 ++-
 gdb/symtab.c                            |  45 ++--
 gdb/symtab.h                            |  29 ++-
 gdb/testsuite/gdb.base/gnu-ifunc-lib.c  |  12 +-
 gdb/testsuite/gdb.base/gnu-ifunc-resd.c |  22 ++
 gdb/testsuite/gdb.base/gnu-ifunc.c      |   6 -
 gdb/testsuite/gdb.base/gnu-ifunc.exp    | 394 +++++++++++++++++++++++++-------
 18 files changed, 728 insertions(+), 307 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/gnu-ifunc-resd.c

-- 
2.14.3

Comments

Pedro Alves March 9, 2018, 9:18 p.m. | #1
On 03/09/2018 09:16 PM, Pedro Alves wrote:

> Pedro Alves (11):

>   eval.c: reverse minsym and sym

>   Fix breakpoints in ifunc after inferior resolved it (@got.plt symbol

>     creation)

>   Fix calling ifunc functions when resolver has debug info and different

>     name

>   Calling ifunc functions when target has no debug info but resolver has

>   Calling ifunc functions when resolver has debug info, user symbol same

>     name

>   Fix setting breakpoints on ifunc functions after they're already

>     resolved

>   Breakpoints, don't skip prologue of ifunc resolvers with debug info

>   Eliminate find_pc_partial_function_gnu_ifunc

>   Factor out minsym_found/find_function_start_sal overload

>   Extend GNU ifunc testcases

>   Fix resolving GNU ifunc bp locations when inferior runs resolver


As always, I forgot to say that I pushed this to the
"users/palves/ifunc" branch on sourceware.org.

Thanks,
Pedro Alves
Alan Hayward March 12, 2018, 11:16 a.m. | #2
> On 9 Mar 2018, at 21:18, Pedro Alves <palves@redhat.com> wrote:

> 

> On 03/09/2018 09:16 PM, Pedro Alves wrote:

> 

>> Pedro Alves (11):

>>  eval.c: reverse minsym and sym

>>  Fix breakpoints in ifunc after inferior resolved it (@got.plt symbol

>>    creation)

>>  Fix calling ifunc functions when resolver has debug info and different

>>    name

>>  Calling ifunc functions when target has no debug info but resolver has

>>  Calling ifunc functions when resolver has debug info, user symbol same

>>    name

>>  Fix setting breakpoints on ifunc functions after they're already

>>    resolved

>>  Breakpoints, don't skip prologue of ifunc resolvers with debug info

>>  Eliminate find_pc_partial_function_gnu_ifunc

>>  Factor out minsym_found/find_function_start_sal overload

>>  Extend GNU ifunc testcases

>>  Fix resolving GNU ifunc bp locations when inferior runs resolver

> 

> As always, I forgot to say that I pushed this to the

> "users/palves/ifunc" branch on sourceware.org.

> 


I was using your branch to try a few things, and debugging gdb gave me a segfault:

$ ./gdb/gdb ./gdb/gdb

(gdb) b amd64_push_dummy_call
Segmentation fault (core dumped)

Backtrace of core file gives me:

#0  get_objfile_arch (objfile=0x0) at ../../src/binutils-gdb/gdb/objfiles.c:448
#1  0x000000000067a889 in find_function_start_sal (func_addr=4335952, section=0x1a4eb20, funfirstline=<optimised out>)
    at ../../src/binutils-gdb/gdb/symtab.c:3590
#2  0x000000000067a934 in find_function_start_sal (sym=sym@entry=0x2b78980, funfirstline=<optimised out>)
    at ../../src/binutils-gdb/gdb/symtab.c:3625
#3  0x00000000005e77f2 in symbol_to_sal (result=result@entry=0x7fff8467b1a0, funfirstline=<optimised out>, sym=sym@entry=0x2b78980)
    at ../../src/binutils-gdb/gdb/linespec.c:4679
#4  0x00000000005ebbd0 in convert_linespec_to_sals (state=state@entry=0x7fff8467b560, ls=ls@entry=0x7fff8467b5b0)
    at ../../src/binutils-gdb/gdb/linespec.c:2384
#5  0x00000000005ed26d in parse_linespec (parser=parser@entry=0x7fff8467b530, arg=<optimised out>, match_type=<optimised out>)
    at ../../src/binutils-gdb/gdb/linespec.c:2771

This was running on Ubuntu 14.04.5 LTS on x86, gdb built with gcc 5.4.0.
Using gdb git HEAD 0dec80227990d5cc2fddd5e5e5bce92fd6629260

Alan.
Pedro Alves March 12, 2018, 5:49 p.m. | #3
On 03/12/2018 11:16 AM, Alan Hayward wrote:
> 

> 

>> On 9 Mar 2018, at 21:18, Pedro Alves <palves@redhat.com> wrote:

>>

>> On 03/09/2018 09:16 PM, Pedro Alves wrote:

>>

>>> Pedro Alves (11):

>>>  eval.c: reverse minsym and sym

>>>  Fix breakpoints in ifunc after inferior resolved it (@got.plt symbol

>>>    creation)

>>>  Fix calling ifunc functions when resolver has debug info and different

>>>    name

>>>  Calling ifunc functions when target has no debug info but resolver has

>>>  Calling ifunc functions when resolver has debug info, user symbol same

>>>    name

>>>  Fix setting breakpoints on ifunc functions after they're already

>>>    resolved

>>>  Breakpoints, don't skip prologue of ifunc resolvers with debug info

>>>  Eliminate find_pc_partial_function_gnu_ifunc

>>>  Factor out minsym_found/find_function_start_sal overload

>>>  Extend GNU ifunc testcases

>>>  Fix resolving GNU ifunc bp locations when inferior runs resolver

>>

>> As always, I forgot to say that I pushed this to the

>> "users/palves/ifunc" branch on sourceware.org.

>>

> 

> I was using your branch to try a few things, and debugging gdb gave me a segfault:

> 

> $ ./gdb/gdb ./gdb/gdb

> 

> (gdb) b amd64_push_dummy_call

> Segmentation fault (core dumped)


Thanks, I can reproduce this.  Looks like the sal has a symtab, but sal.objfile
is left NULL.

Pedro Alves