public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: will schmidt <will_schmidt@vnet.ibm.com>
To: Alan Modra <amodra@gmail.com>, Ulrich Weigand <uweigand@de.ibm.com>
Cc: gdb-patches@sourceware.org, rogerio <rogealve@br.ibm.com>,
	"Carl E. Love" <cel@us.ibm.com>
Subject: Re: gdb compile for powerpc64 target - Could not find symbol ".TOC."
Date: Fri, 09 Jul 2021 11:51:35 -0500	[thread overview]
Message-ID: <7a410f448ecddd3e5c4175344be639f68ab3be47.camel@vnet.ibm.com> (raw)
In-Reply-To: <YNUPtenqZ6/tlttm@squeak.grove.modra.org>

On Fri, 2021-06-25 at 08:35 +0930, Alan Modra wrote:
> On Thu, Jun 24, 2021 at 05:32:50PM +0200, Ulrich Weigand wrote:
> > On Thu, Jun 24, 2021 at 12:41:18PM +0930, Alan Modra wrote:
> > 
> > > I'm not at all familiar with gdb/compile, but it looks like
> > > anything
> > > to do with the GOT is unsupported.  I can't see any handling for
> > > GOT
> > > relocs, for example.  
> > 
> > The basic approach seems to be:
> > - Allocate memory in the inferior for each section
> > - Use bfd_set_section_vma on all sections to provide the address
> > - Load the symbol table via bfd_canonicalize_symtab
> > - Modify the symbol table to provide values for all undefined
> > symbols
> >   (via GDB looking them up in the rest of the inferior)
> > - Use bfd_get_relocated_section_contents to load the contents of
> >   all sections, using the symbol table from above
> > 
> > I think the assumption is that bfd_get_relocated_section_contents
> > will handle any relocation type, including GOT/TOC relocs.
> >  
> > > Now .TOC. should be handled exactly as _GLOBAL_OFFSET_TABLE_, but
> > > compile-object-load.c is just broken, I think.  You can't set
> > > .TOC. or
> > > _GLOBAL_OFFSET_TABLE_ to zero and expect everything to be rosy,
> > > for
> > > code that uses those symbols.
> > 
> > Agreed, it looks like this makes the Intel-specific assumption that
> > code uses PC-relative addressing for everything and does not
> > actually
> > rely on the value of _GLOBAL_OFFSET_TABLE_.   I'm not sure this is
> > even completely true for Intel, but it certainly isn't on Power.
> > 
> > > > > Yes, we probably do need a proper value for .TOC.  Usually,
> > > > > this
> > > > > is set by the linker to 0x8000 bytes after the beginning of
> > > > > the .toc
> > > > > section, I think.
> > > 
> > > Again, I'm not familiar enough with the gdb compile support to
> > > give
> > > proper advice.  If calls to functions in the newly
> > > compiled/loaded
> > > code is always via global entry points then you have some freedom
> > > in
> > > choosing your own .TOC. value.  If direct calls to the local
> > > entry
> > > point are made then .TOC. should be set to the value used in
> > > whatever
> > > context is going to call the newly loaded object.  That would be
> > > tricky.
> > 
> > Inferior calls should always use the global entry point, so that
> > should be OK.   I'm more concerned that we have to use the same
> > value for .TOC. as will be used by
> > bfd_get_relocated_section_contents
> > for handling TOC-relative relocations.  If we just define a value
> > for the .TOC. symbol in the symbol table passed to
> > bfd_get_relocated_section_contents, will this be used?
> 

Hi,

> No, just defining .TOC. won't be sufficient.  A .TOC. symbol value
> is used if the symbol is found in the linker hash table, but here we
> aren't even invoking the linker.  I think the gdb code should call
> _bfd_set_gp_value,

I've made some local changes so I'm now calling bfd_set_gp_value when
the ".TOC." symbol is handled in compile_object_load. 
i.e. 
      if (strcmp (sym->name, ".TOC.") == 0)
        bfd_set_gp_value(abfd.get(), sym->value);

This is either wrong, or insufficient.  :-)

By plugging in different values in place of "sym->value" I can see that
this affects a ld/lwa sequence later on, and I wonder if the offsets we
are trying to load from are simply too large here.

Some helpful(?) debug and recap,..
Our test is a "(gdb) compile print varint"  per
gdb/testsuite/compile/compile-print.exp.  I've changed the varint value
to 0x12345678 to server better as an eyecatcher.
I've got a small number of local changes allowing us to at least find
our compiler (patch attached for reference).

When we enter _gdb_expr, r12 points to the function entry point, so 
in this case has the value 0x0000200000080000. 

>(gdb) disas
>Dump of assembler code for function _gdb_expr:
>    0x0000200000080000 <+0>:	addis   r2,r12,-8
>    0x0000200000080004 <+4>:	addi    r2,r2,0
>    0x0000200000080008 <+8>:	std     r31,-8(r1)
>    0x000020000008000c <+12>:	stdu    r1,-80(r1)
>    0x0000200000080010 <+16>:	mr      r31,r1
>    0x0000200000080014 <+20>:	std     r3,48(r31)
>    0x0000200000080018 <+24>:	std     r4,56(r31)
>    0x000020000008001c <+28>:	addis   r9,r2,0         <<--[1]
>    0x0000200000080020 <+32>:	ld      r9,-32768(r9)	<<--[2]
> => 0x0000200000080024 <+36>:	lwa     r9,0(r9)	<<--[3]
>    0x0000200000080028 <+40>:	stw     r9,32(r31)
>    0x000020000008002c <+44>:	lwz     r10,32(r31)
>    0x0000200000080030 <+48>:	ld      r9,56(r31)
>    0x0000200000080034 <+52>:	stw     r10,0(r9)
>    0x0000200000080038 <+56>:	nop
>    0x000020000008003c <+60>:	addi    r1,r31,80
>    0x0000200000080040 <+64>:	ld      r31,-8(r1)
>    0x0000200000080044 <+68>:	blr
> 

Passing in different values to bfd_set_gp_value in place of
sym->value affects the offsets referenced at [1] and [2].

The value in r9 when we reach [3] is zero, so it SIGSEGVs on
that.    The familiar -32768 value at [2] suggests to me
that we are trying to reach farther than allowed.


(gdb) info reg r2
r2             0x200000000000      0x200000000000
(gdb) info reg r12
r12            0x200000080000      0x200000080000

(gdb) info address varint
Symbol "varint" is static storage at address 0x100020010.

(gdb) maint info section .data
Exec file: `/home/willschm/gdb_builds/gdb-patches/a.out', 
        file type elf64-powerpcle.
 [21]     0x100020000->0x100020038 at 0x00010000: .data ALLOC LOAD DATA HAS_CONTENTS

(gdb) find 0x100020000,0x100020038,0x12345678
0x100020010 <varint>
1 pattern found.

(gdb) find 0x200000000000,0x200000080000,0x12345678
Pattern not found.
(gdb) find 0x200000080000,0x200000180000,0x12345678
Pattern not found.




As another reference, this is what the disassembly looks like when we
issue a "compile print main", which does not have any .TOC. references.
(this works).

> (gdb) disas
> Dump of assembler code for function _gdb_expr:
>    0x0000200000080000 <+0>:	std     r31,-8(r1)
>    0x0000200000080004 <+4>:	stdu    r1,-80(r1)
>    0x0000200000080008 <+8>:	mr      r31,r1
>    0x000020000008000c <+12>:	std     r3,48(r31)
>    0x0000200000080010 <+16>:	std     r4,56(r31)
>    0x0000200000080014 <+20>:	lis     r9,1
>    0x0000200000080018 <+24>:	rldicr  r9,r9,16,47
>    0x000020000008001c <+28>:	ori     r9,r9,2044
>    0x0000200000080020 <+32>:	std     r9,32(r31)
>    0x0000200000080024 <+36>:	ld      r9,32(r31)
>    0x0000200000080028 <+40>:	lbz     r10,0(r9)
>    0x000020000008002c <+44>:	ld      r9,56(r31)
>    0x0000200000080030 <+48>:	stb     r10,0(r9)
>    0x0000200000080034 <+52>:	nop
>    0x0000200000080038 <+56>:	addi    r1,r31,80
>    0x000020000008003c <+60>:	ld      r31,-8(r1)
>    0x0000200000080040 <+64>:	blr
>    0x0000200000080044 <+68>:	.long 0x0
>    0x0000200000080048 <+72>:	.long 0x0
>    0x000020000008004c <+76>:	.long 0x1000180
> 


Help!  :-) 

Thanks
-Will


Patches for reference,   
1 - add target options.
2 - add/specify target triple.
3 - externalize bfd bfd_set_gp_value.
4 - call bfd_set_gp_value for .TOC.


[Add target options]

    Add a ppc64_linux_gcc_target_options

diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index a629450d746..5c2390f0e41 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -822,10 +822,18 @@ rs6000_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   return rs6000_in_function_epilogue_frame_p (get_current_frame (),
 					      gdbarch, pc);
 }
 
+/* Implement  the linux_gcc_target_options method.  */
+static std::string
+ppc64_linux_gcc_target_options (struct gdbarch *gdbarch)
+{
+        return "-mcmodel=medium" ;
+}
+
+
 /* Get the ith function argument for the current function.  */
 static CORE_ADDR
 rs6000_fetch_pointer_argument (struct frame_info *frame, int argi, 
 			       struct type *type)
 {
@@ -7127,10 +7135,13 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Trampoline.  */
   set_gdbarch_in_solib_return_trampoline
     (gdbarch, rs6000_in_solib_return_trampoline);
   set_gdbarch_skip_trampoline_code (gdbarch, rs6000_skip_trampoline_code);
 
+  /* */
+  set_gdbarch_gcc_target_options (gdbarch, ppc64_linux_gcc_target_options);
+
   /* Hook in the DWARF CFI frame unwinder.  */
   dwarf2_append_unwinders (gdbarch);
   dwarf2_frame_set_adjust_regnum (gdbarch, rs6000_adjust_frame_regnum);
 
   /* Frame handling.  */



[Add target triplet]

    add a target triplet.  (needs adjustment)

diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index 1e94922f25a..61a69a5de78 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -1971,10 +1971,17 @@ ppc_floatformat_for_type (struct gdbarch *gdbarch,
     }
 
   return default_floatformat_for_type (gdbarch, name, len);
 }
 
+/* Specify the target triplet as appropriate.. */
+static const char *
+ppc64le_gnu_triplet_regexp (struct gdbarch *gdbarch)
+{
+        return "powerpc64le?";
+}
+
 static void
 ppc_linux_init_abi (struct gdbarch_info info,
 		    struct gdbarch *gdbarch)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
@@ -2101,10 +2108,13 @@ ppc_linux_init_abi (struct gdbarch_info info,
       /* BFD target for core files.  */
       if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
 	set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpcle");
       else
 	set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpc");
+     /* Set compiler triplet.  */
+      if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
+          set_gdbarch_gnu_triplet_regexp (gdbarch, ppc64le_gnu_triplet_regexp);
     }
 
   set_gdbarch_core_read_description (gdbarch, ppc_linux_core_read_description);
   set_gdbarch_iterate_over_regset_sections (gdbarch,
 					    ppc_linux_iterate_over_regset_sections);



[ eternalize bfd bfd_set_gp_value ]

    tweak bfd to externalize the bfd_set_gp_value function.

diff --git a/bfd/bfd.c b/bfd/bfd.c
index 6e5d3397d15..a53ad80190e 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -1849,10 +1849,28 @@ _bfd_set_gp_value (bfd *abfd, bfd_vma v)
     ecoff_data (abfd)->gp = v;
   else if (abfd->xvec->flavour == bfd_target_elf_flavour)
     elf_gp (abfd) = v;
 }
 
+/*
+FUNCTION
+	bfd_set_gp_value
+
+SYNOPSIS
+	void bfd_set_gp_value (bfd * abfd, bfd_vma v);
+
+DESCRIPTION
+	Allow external gdb to call this function for
+	gdb-compile support.
+*/
+
+void
+bfd_set_gp_value (bfd *abfd, bfd_vma v)
+{
+        return _bfd_set_gp_value (abfd, v);
+}
+
 /*
 FUNCTION
 	bfd_scan_vma
 
 SYNOPSIS




[ call bfd_set_gp_value for .TOC. symbol ]

diff --git a/gdb/compile/compile-object-load.c b/gdb/compile/compile-object-load.c
index 1c512801bcd..56df153a89c 100644
--- a/gdb/compile/compile-object-load.c
+++ b/gdb/compile/compile-object-load.c
@@ -720,10 +720,27 @@ compile_object_load (const compile_file_names &file_names,
 	     need for _GLOBAL_OFFSET_TABLE_.  Together with -fPIE the data
 	     remain PC-relative even with _GLOBAL_OFFSET_TABLE_ as zero.  */
 	  sym->value = 0;
 	  continue;
 	}
+      if (strcmp (sym->name, ".TOC.") == 0)
+        {
+	  fprintf_unfiltered (gdb_stdlog,
+			      "ELF symbol \"%s\" found.  calling bfd_set_gp_value %s\n",
+			      sym->name, paddress (target_gdbarch (), sym->value));
+	  bfd_set_gp_value(abfd.get(), sym->value);
+	  continue;
+        }
+      /* debug ... */
+      if (strcmp (sym->name, "varint") == 0)
+        {
+	  fprintf_unfiltered (gdb_stdlog,
+			      "ELF symbol \"%s\" found. value  is %s\n",
+			      sym->name, paddress (target_gdbarch (), sym->value));
+	  continue;
+        }
+
       bmsym = lookup_minimal_symbol (sym->name, NULL, NULL);
       switch (bmsym.minsym == NULL
 	      ? mst_unknown : MSYMBOL_TYPE (bmsym.minsym))
 	{
 	case mst_text:




>                    but _bfd_set_gp_value is currently an internal BFD
> function.  That would need to change (give _bfd_set_gp_value a
> FUNCTION, SYNOPSIS, DESCRIPTION function comment, remove the
> declaration from libbfd-in.h, regenerate with
> --enable-maintainer-mode).
> 
> > If so, that might be the easiest fix; simply provide a reasonable
> > value (e.g. address of the .toc section + 0x8000) in the symbol
> > table, and everything else ought to work out ...
> > 
> > Bye,
> > Ulrich
> > 
> > -- 
> >   Dr. Ulrich Weigand
> >   GNU/Linux compilers and toolchain
> >   Ulrich.Weigand@de.ibm.com
> 






> 


  parent reply	other threads:[~2021-07-09 16:51 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-22 18:54 will schmidt
2021-06-23 15:36 ` Ulrich Weigand
2021-06-23 17:37   ` will schmidt
2021-06-24  3:11     ` Alan Modra
2021-06-24  4:39       ` Alan Modra
2021-06-24 15:32       ` Ulrich Weigand
2021-06-24 23:05         ` Alan Modra
2021-06-25 14:49           ` will schmidt
2021-07-09 16:51           ` will schmidt [this message]
2021-07-10  1:01             ` Alan Modra
2021-07-13  4:33               ` will schmidt
2021-07-13 11:11                 ` Alan Modra
2021-07-13 22:59                   ` will schmidt

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=7a410f448ecddd3e5c4175344be639f68ab3be47.camel@vnet.ibm.com \
    --to=will_schmidt@vnet.ibm.com \
    --cc=amodra@gmail.com \
    --cc=cel@us.ibm.com \
    --cc=gdb-patches@sourceware.org \
    --cc=rogealve@br.ibm.com \
    --cc=uweigand@de.ibm.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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).