Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Simon Marchi <simark@simark.ca>
To: Pedro Alves <palves@redhat.com>, gdb-patches@sourceware.org
Subject: Re: [PATCH v2 01/15] Fix breakpoints in ifunc after inferior resolved it (@got.plt symbol creation)
Date: Sun, 01 Apr 2018 03:35:00 -0000	[thread overview]
Message-ID: <4c13e43f-bbad-3b55-12a2-d93f90196dc4@simark.ca> (raw)
In-Reply-To: <20180325191943.8246-2-palves@redhat.com>

On 2018-03-25 03:19 PM, Pedro Alves wrote:
> In v2: - reworked to keep supporting rel.plt sections for .plt, and
>          to handle jump slot offsets pointing to .plt.
> 
> Setting a breakpoint on an ifunc symbol after the ifunc has already
> been resolved by the inferior should result in creating a breakpoint
> location at the ifunc target.  However, that's not what happens on
> current Fedora:
> 
>   (gdb) n
>   53        i = gnu_ifunc (1);    /* break-at-call */
>   (gdb)
>   54        assert (i == 2);
>   (gdb) b gnu_ifunc
>   Breakpoint 2 at gnu-indirect-function resolver at 0x7ffff7bd36ee
>   (gdb) info breakpoints
>   Num     Type                   Disp Enb Address            What
>   2       STT_GNU_IFUNC resolver keep y   0x00007ffff7bd36ee <gnu_ifunc+4>
> 
> The problem is that elf_gnu_ifunc_resolve_by_got never manages to
> resolve an ifunc target.  The reason is that GDB never actually
> creates the internal got.plt symbols:
> 
>  (gdb) p 'gnu_ifunc@got.plt'
>  No symbol "gnu_ifunc@got.plt" in current context.
> 
> and this is because GDB expects that rela.plt has relocations for
> .plt, while it actually has relocations for .got.plt:
> 
>  Relocation section [10] '.rela.plt' for section [22] '.got.plt' at offset 0x570 contains 2 entries:
>    Offset              Type            Value               Addend Name
>    0x0000000000601018  X86_64_JUMP_SLOT 000000000000000000      +0 __assert_fail
>    0x0000000000601020  X86_64_JUMP_SLOT 000000000000000000      +0 gnu_ifunc
> 
> 
> Using an older system on the GCC compile farm (machine gcc15, an
> x86-64 running Debian 6.0.8, with GNU ld 2.20.1), we see that it used
> to be that we'd get a .rela.plt section for .plt:
> 
>  Relocation section [ 9] '.rela.plt' for section [11] '.plt' at offset 0x578 contains 3 entries:
>    Offset              Type            Value               Addend Name
>    0x0000000000600cc0  X86_64_JUMP_SLOT 000000000000000000      +0 __assert_fail
>    0x0000000000600cc8  X86_64_JUMP_SLOT 000000000000000000      +0 __libc_start_main
>    0x0000000000600cd0  X86_64_JUMP_SLOT 000000000000000000      +0 gnu_ifunc
> 
> Those offsets did point into .got.plt, as seen with objdump -h:
> 
>   20 .got.plt      00000030  0000000000600ca8  0000000000600ca8  00000ca8  2**3
>      		   CONTENTS, ALLOC, LOAD, DATA
> 
> I also tested on gcc110 on the compile farm (PPC64 running CentOS
> 7.4.1708, with GNU ld 2.25.1), and there we see instead:
> 
>  Relocation section [ 9] '.rela.plt' for section [23] '.plt' at offset 0x5d0 contains 4 entries:
>    Offset              Type            Value               Addend Name
>    0x0000000010020148  PPC64_JMP_SLOT  000000000000000000      +0 __libc_start_main
>    0x0000000010020160  PPC64_JMP_SLOT  000000000000000000      +0 __gmon_start__
>    0x0000000010020178  PPC64_JMP_SLOT  000000000000000000      +0 __assert_fail
>    0x0000000010020190  PPC64_JMP_SLOT  000000000000000000      +0 gnu_ifunc
> 
> But note that those offsets point into .plt, not .got.plt, as seen
> with objdump -h:
> 
>  22 .plt          00000078  0000000010020130  0000000010020130  00010130  2**3
>                   ALLOC
> 
> This commit makes us support all the different combinations above.
> 
> With that addressed, we now get:
> 
>  (gdb) p 'gnu_ifunc@got.plt'
>  $1 = (<text from jump slot in .got.plt, no debug info>) 0x400753 <final>
> 
> And setting a breakpoint on the ifunc finds the ifunc target:
> 
>  (gdb) b gnu_ifunc
>  Breakpoint 2 at 0x400753
>  (gdb) info breakpoints
>  Num     Type           Disp Enb Address            What
>  2       breakpoint     keep y   0x0000000000400753 <final>
> 
> gdb/ChangeLog:
> yyyy-mm-dd  Pedro Alves  <palves@redhat.com>
> 
> 	* elfread.c (elf_rel_plt_read): Look for relocations for .got.plt too.
> 	not .plt.
> ---
>  gdb/elfread.c | 64 +++++++++++++++++++++++++++++++++++++++++++----------------
>  1 file changed, 47 insertions(+), 17 deletions(-)
> 
> diff --git a/gdb/elfread.c b/gdb/elfread.c
> index 260789062d0..9ffbf99db6e 100644
> --- a/gdb/elfread.c
> +++ b/gdb/elfread.c
> @@ -535,8 +535,7 @@ elf_rel_plt_read (minimal_symbol_reader &reader,
>  {
>    bfd *obfd = objfile->obfd;
>    const struct elf_backend_data *bed = get_elf_backend_data (obfd);
> -  asection *plt, *relplt, *got_plt;
> -  int plt_elf_idx;
> +  asection *relplt, *got_plt;
>    bfd_size_type reloc_count, reloc;
>    struct gdbarch *gdbarch = get_objfile_arch (objfile);
>    struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
> @@ -545,11 +544,6 @@ elf_rel_plt_read (minimal_symbol_reader &reader,
>    if (objfile->separate_debug_objfile_backlink)
>      return;
>  
> -  plt = bfd_get_section_by_name (obfd, ".plt");
> -  if (plt == NULL)
> -    return;
> -  plt_elf_idx = elf_section_data (plt)->this_idx;
> -
>    got_plt = bfd_get_section_by_name (obfd, ".got.plt");
>    if (got_plt == NULL)
>      {
> @@ -559,12 +553,31 @@ elf_rel_plt_read (minimal_symbol_reader &reader,
>  	return;
>      }
>  
> +  /* Depending on system, we may find jump slots in a relocation
> +     section for either .got.plt or .plt.  */
> +  asection *plt = bfd_get_section_by_name (obfd, ".plt");
> +  int plt_elf_idx = (plt != NULL) ? elf_section_data (plt)->this_idx : -1;
> +
> +  int got_plt_elf_idx = elf_section_data (got_plt)->this_idx;
> +
>    /* This search algorithm is from _bfd_elf_canonicalize_dynamic_reloc.  */
>    for (relplt = obfd->sections; relplt != NULL; relplt = relplt->next)
> -    if (elf_section_data (relplt)->this_hdr.sh_info == plt_elf_idx
> -	&& (elf_section_data (relplt)->this_hdr.sh_type == SHT_REL
> -	    || elf_section_data (relplt)->this_hdr.sh_type == SHT_RELA))
> -      break;
> +    {
> +      const auto &this_hdr = elf_section_data (relplt)->this_hdr;
> +
> +      if (this_hdr.sh_type == SHT_REL || this_hdr.sh_type == SHT_RELA)
> +	{
> +	  asection *target_section = NULL;
> +
> +	  if (this_hdr.sh_info == plt_elf_idx)
> +	    target_section = plt;
> +	  else if (this_hdr.sh_info == got_plt_elf_idx)
> +	    target_section = got_plt;
> +
> +	  if (target_section != NULL)
> +	    break;

Is it really useful to have/set target_section?  Couldn't we just break out of the
loop like this?

  if (this_hdr.sh_info == plt_elf_idx
      || this_hdr.sh_info == got_plt_elf_idx)
    break;

> +	}
> +    }
>    if (relplt == NULL)
>      return;
>  
> @@ -573,6 +586,18 @@ elf_rel_plt_read (minimal_symbol_reader &reader,
>  
>    std::string string_buffer;
>  
> +  /* Does ADDRESS reside in SECTION of OBFD?  */
> +  auto within_section = [obfd] (asection *section, CORE_ADDR address)
> +    {
> +      if (section == NULL)
> +	return false;
> +
> +      /* Does the pointer reside in the .got.plt section?  */

That comment should change, since it's not stricly .got.plt.

> +      return (bfd_get_section_vma (obfd, section) <= address
> +	      && (address < bfd_get_section_vma (obfd, section)
> +		  + bfd_get_section_size (section)));
> +    };
> +
>    reloc_count = relplt->size / elf_section_data (relplt)->this_hdr.sh_entsize;
>    for (reloc = 0; reloc < reloc_count; reloc++)
>      {
> @@ -585,10 +610,15 @@ elf_rel_plt_read (minimal_symbol_reader &reader,
>        name = bfd_asymbol_name (*relplt->relocation[reloc].sym_ptr_ptr);
>        address = relplt->relocation[reloc].address;
>  
> -      /* Does the pointer reside in the .got.plt section?  */
> -      if (!(bfd_get_section_vma (obfd, got_plt) <= address
> -            && address < bfd_get_section_vma (obfd, got_plt)
> -			 + bfd_get_section_size (got_plt)))
> +      asection *msym_section;
> +
> +      /* Does the pointer reside in either the .got.plt or .plt
> +	 sections?  */
> +      if (within_section (got_plt, address))
> +	msym_section = got_plt;
> +      else if (within_section (plt, address))
> +	msym_section = plt;
> +      else
>  	continue;

Or maybe you intended to use target_section here at some point?  Is there a
relationship between the section that matched in the for loop above and the
section that will contain the address?  In other words, could we save the
target_section from above and do

  if (!within_section (target_section, address))
    continue;

>  
>        /* We cannot check if NAME is a reference to mst_text_gnu_ifunc as in
> @@ -600,8 +630,8 @@ elf_rel_plt_read (minimal_symbol_reader &reader,
>  
>        msym = record_minimal_symbol (reader, string_buffer.c_str (),
>  				    string_buffer.size (),
> -                                    true, address, mst_slot_got_plt, got_plt,
> -				    objfile);
> +				    true, address, mst_slot_got_plt,
> +				    msym_section, objfile);
>        if (msym)
>  	SET_MSYMBOL_SIZE (msym, ptr_size);
>      }
> 

Simon


  reply	other threads:[~2018-04-01  3:35 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-25 19:19 [PATCH v2 00/15] Fixing GNU ifunc support Pedro Alves
2018-03-25 19:19 ` [PATCH v2 08/15] Eliminate find_pc_partial_function_gnu_ifunc Pedro Alves
2018-03-25 19:19 ` [PATCH v2 02/15] Fix calling ifunc functions when resolver has debug info and different name Pedro Alves
2018-04-01  3:44   ` Simon Marchi
2018-04-10 21:20     ` Pedro Alves
2018-03-25 19:19 ` [PATCH v2 03/15] Calling ifunc functions when target has no debug info but resolver has Pedro Alves
2018-04-01  4:22   ` Simon Marchi
2018-04-10 21:48     ` Pedro Alves
2018-04-10 21:54       ` Pedro Alves
2018-03-25 19:19 ` [PATCH v2 05/15] Fix elf_gnu_ifunc_resolve_by_got buglet Pedro Alves
2018-04-01  4:32   ` Simon Marchi
2018-04-10 21:52     ` Pedro Alves
2018-03-25 19:19 ` [PATCH v2 01/15] Fix breakpoints in ifunc after inferior resolved it (@got.plt symbol creation) Pedro Alves
2018-04-01  3:35   ` Simon Marchi [this message]
2018-04-10 21:20     ` Pedro Alves
2018-04-14 16:36       ` Simon Marchi
2018-03-25 19:19 ` [PATCH v2 11/15] Fix stepping past GNU ifunc resolvers (introduce lookup_msym_prefer) Pedro Alves
2018-06-18 20:26   ` [PATCH] Silence GCC "uninitialized" warning on minsyms.c:lookup_minimal_symbol_by_pc_section Sergio Durigan Junior
2018-06-19 15:22     ` Pedro Alves
2018-06-19 16:55       ` Sergio Durigan Junior
2018-06-19 18:47       ` Tom Tromey
2018-03-25 19:19 ` [PATCH v2 15/15] Fix resolving GNU ifunc bp locations when inferior runs resolver Pedro Alves
2018-03-25 19:19 ` [PATCH v2 12/15] For PPC64/ELFv1: Introduce mst_data_gnu_ifunc Pedro Alves
2018-03-25 19:19 ` [PATCH v2 07/15] Breakpoints, don't skip prologue of ifunc resolvers with debug info Pedro Alves
2018-03-25 19:25 ` [PATCH v2 04/15] Calling ifunc functions when resolver has debug info, user symbol same name Pedro Alves
2018-03-25 19:25 ` [PATCH v2 09/15] Factor out minsym_found/find_function_start_sal overload Pedro Alves
2018-03-25 19:28 ` [PATCH v2 14/15] Extend GNU ifunc testcases Pedro Alves
2018-03-25 19:29 ` [PATCH v2 13/15] PPC64: always make synthetic .text symbols for GNU ifunc symbols Pedro Alves
2018-03-25 19:33   ` Pedro Alves
2018-03-26  7:54   ` Alan Modra
2018-03-25 19:29 ` [PATCH v2 10/15] For PPC64: elf_gnu_ifunc_record_cache: handle plt symbols in .text section Pedro Alves
2018-03-25 19:29 ` [PATCH v2 06/15] Fix setting breakpoints on ifunc functions after they're already resolved Pedro Alves
2018-04-26 12:23 ` [PATCH v2 00/15] Fixing GNU ifunc support Pedro Alves

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4c13e43f-bbad-3b55-12a2-d93f90196dc4@simark.ca \
    --to=simark@simark.ca \
    --cc=gdb-patches@sourceware.org \
    --cc=palves@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox