public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Aaron Merey <amerey@redhat.com>
To: gdb-patches@sourceware.org, simon.marchi@polymtl.ca, tom@tromey.com
Subject: [PATCH 1/3] gdb/solib: Refactor scan_dyntag
Date: Thu, 12 Aug 2021 00:24:04 -0400	[thread overview]
Message-ID: <20210812042406.75637-2-amerey@redhat.com> (raw)
In-Reply-To: <20210812042406.75637-1-amerey@redhat.com>

scan_dyntag is unnecessarily duplicated in solib-svr4.c and solib-dsbt.c.

Move this function to solib.c and rename it to gdb_bfd_scan_elf_dyntag.
Also add it to solib.h so it is included in both solib-svr4 and solib-dsbt.
---
 gdb/solib-dsbt.c | 104 ++---------------------------------------
 gdb/solib-svr4.c | 118 ++++-------------------------------------------
 gdb/solib.c      | 104 +++++++++++++++++++++++++++++++++++++++++
 gdb/solib.h      |   6 +++
 4 files changed, 122 insertions(+), 210 deletions(-)

diff --git a/gdb/solib-dsbt.c b/gdb/solib-dsbt.c
index 803467dd489..d7f4b252eee 100644
--- a/gdb/solib-dsbt.c
+++ b/gdb/solib-dsbt.c
@@ -396,106 +396,6 @@ fetch_loadmap (CORE_ADDR ldmaddr)
 static void dsbt_relocate_main_executable (void);
 static int enable_break (void);
 
-/* Scan for DYNTAG in .dynamic section of ABFD. If DYNTAG is found 1 is
-   returned and the corresponding PTR is set.  */
-
-static int
-scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr)
-{
-  int arch_size, step, sect_size;
-  long dyn_tag;
-  CORE_ADDR dyn_ptr, dyn_addr;
-  gdb_byte *bufend, *bufstart, *buf;
-  Elf32_External_Dyn *x_dynp_32;
-  Elf64_External_Dyn *x_dynp_64;
-  struct bfd_section *sect;
-
-  if (abfd == NULL)
-    return 0;
-
-  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
-    return 0;
-
-  arch_size = bfd_get_arch_size (abfd);
-  if (arch_size == -1)
-    return 0;
-
-  /* Find the start address of the .dynamic section.  */
-  sect = bfd_get_section_by_name (abfd, ".dynamic");
-  if (sect == NULL)
-    return 0;
-
-  bool found = false;
-  for (const target_section &target_section
-	 : current_program_space->target_sections ())
-    if (sect == target_section.the_bfd_section)
-      {
-	dyn_addr = target_section.addr;
-	found = true;
-	break;
-      }
-  if (!found)
-    {
-      /* ABFD may come from OBJFILE acting only as a symbol file without being
-	 loaded into the target (see add_symbol_file_command).  This case is
-	 such fallback to the file VMA address without the possibility of
-	 having the section relocated to its actual in-memory address.  */
-
-      dyn_addr = bfd_section_vma (sect);
-    }
-
-  /* Read in .dynamic from the BFD.  We will get the actual value
-     from memory later.  */
-  sect_size = bfd_section_size (sect);
-  buf = bufstart = (gdb_byte *) alloca (sect_size);
-  if (!bfd_get_section_contents (abfd, sect,
-				 buf, 0, sect_size))
-    return 0;
-
-  /* Iterate over BUF and scan for DYNTAG.  If found, set PTR and return.  */
-  step = (arch_size == 32) ? sizeof (Elf32_External_Dyn)
-			   : sizeof (Elf64_External_Dyn);
-  for (bufend = buf + sect_size;
-       buf < bufend;
-       buf += step)
-  {
-    if (arch_size == 32)
-      {
-	x_dynp_32 = (Elf32_External_Dyn *) buf;
-	dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_tag);
-	dyn_ptr = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_un.d_ptr);
-      }
-    else
-      {
-	x_dynp_64 = (Elf64_External_Dyn *) buf;
-	dyn_tag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag);
-	dyn_ptr = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_un.d_ptr);
-      }
-     if (dyn_tag == DT_NULL)
-       return 0;
-     if (dyn_tag == dyntag)
-       {
-	 /* If requested, try to read the runtime value of this .dynamic
-	    entry.  */
-	 if (ptr)
-	   {
-	     struct type *ptr_type;
-	     gdb_byte ptr_buf[8];
-	     CORE_ADDR ptr_addr;
-
-	     ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
-	     ptr_addr = dyn_addr + (buf - bufstart) + arch_size / 8;
-	     if (target_read_memory (ptr_addr, ptr_buf, arch_size / 8) == 0)
-	       dyn_ptr = extract_typed_address (ptr_buf, ptr_type);
-	     *ptr = dyn_ptr;
-	   }
-	 return 1;
-       }
-  }
-
-  return 0;
-}
-
 /* See solist.h. */
 
 static int
@@ -565,7 +465,9 @@ lm_base (void)
 			    "lm_base: get addr %x by _GLOBAL_OFFSET_TABLE_.\n",
 			    (unsigned int) addr);
     }
-  else if (scan_dyntag (DT_PLTGOT, current_program_space->exec_bfd (), &addr))
+  else if (gdb_bfd_scan_elf_dyntag (DT_PLTGOT,
+				    current_program_space->exec_bfd (),
+				    &addr, NULL))
     {
       struct int_elf32_dsbt_loadmap *ldm;
 
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index a8a7d1171dc..3de1bb9c7f7 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -582,109 +582,6 @@ find_program_interpreter (void)
 }
 
 
-/* Scan for DESIRED_DYNTAG in .dynamic section of ABFD.  If DESIRED_DYNTAG is
-   found, 1 is returned and the corresponding PTR is set.  */
-
-static int
-scan_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr,
-	     CORE_ADDR *ptr_addr)
-{
-  int arch_size, step, sect_size;
-  long current_dyntag;
-  CORE_ADDR dyn_ptr, dyn_addr;
-  gdb_byte *bufend, *bufstart, *buf;
-  Elf32_External_Dyn *x_dynp_32;
-  Elf64_External_Dyn *x_dynp_64;
-  struct bfd_section *sect;
-
-  if (abfd == NULL)
-    return 0;
-
-  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
-    return 0;
-
-  arch_size = bfd_get_arch_size (abfd);
-  if (arch_size == -1)
-    return 0;
-
-  /* Find the start address of the .dynamic section.  */
-  sect = bfd_get_section_by_name (abfd, ".dynamic");
-  if (sect == NULL)
-    return 0;
-
-  bool found = false;
-  for (const target_section &target_section
-	 : current_program_space->target_sections ())
-    if (sect == target_section.the_bfd_section)
-      {
-	dyn_addr = target_section.addr;
-	found = true;
-	break;
-      }
-  if (!found)
-    {
-      /* ABFD may come from OBJFILE acting only as a symbol file without being
-	 loaded into the target (see add_symbol_file_command).  This case is
-	 such fallback to the file VMA address without the possibility of
-	 having the section relocated to its actual in-memory address.  */
-
-      dyn_addr = bfd_section_vma (sect);
-    }
-
-  /* Read in .dynamic from the BFD.  We will get the actual value
-     from memory later.  */
-  sect_size = bfd_section_size (sect);
-  buf = bufstart = (gdb_byte *) alloca (sect_size);
-  if (!bfd_get_section_contents (abfd, sect,
-				 buf, 0, sect_size))
-    return 0;
-
-  /* Iterate over BUF and scan for DYNTAG.  If found, set PTR and return.  */
-  step = (arch_size == 32) ? sizeof (Elf32_External_Dyn)
-			   : sizeof (Elf64_External_Dyn);
-  for (bufend = buf + sect_size;
-       buf < bufend;
-       buf += step)
-  {
-    if (arch_size == 32)
-      {
-	x_dynp_32 = (Elf32_External_Dyn *) buf;
-	current_dyntag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_tag);
-	dyn_ptr = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_un.d_ptr);
-      }
-    else
-      {
-	x_dynp_64 = (Elf64_External_Dyn *) buf;
-	current_dyntag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag);
-	dyn_ptr = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_un.d_ptr);
-      }
-     if (current_dyntag == DT_NULL)
-       return 0;
-     if (current_dyntag == desired_dyntag)
-       {
-	 /* If requested, try to read the runtime value of this .dynamic
-	    entry.  */
-	 if (ptr)
-	   {
-	     struct type *ptr_type;
-	     gdb_byte ptr_buf[8];
-	     CORE_ADDR ptr_addr_1;
-
-	     ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
-	     ptr_addr_1 = dyn_addr + (buf - bufstart) + arch_size / 8;
-	     if (target_read_memory (ptr_addr_1, ptr_buf, arch_size / 8) == 0)
-	       dyn_ptr = extract_typed_address (ptr_buf, ptr_type);
-	     *ptr = dyn_ptr;
-	     if (ptr_addr)
-	       *ptr_addr = dyn_addr + (buf - bufstart);
-	   }
-	 return 1;
-       }
-  }
-
-  return 0;
-}
-
 /* Scan for DESIRED_DYNTAG in .dynamic section of the target's main executable,
    found by consulting the OS auxillary vector.  If DESIRED_DYNTAG is found, 1
    is returned and the corresponding PTR is set.  */
@@ -768,8 +665,9 @@ elf_locate_base (void)
   /* Look for DT_MIPS_RLD_MAP first.  MIPS executables use this
      instead of DT_DEBUG, although they sometimes contain an unused
      DT_DEBUG.  */
-  if (scan_dyntag (DT_MIPS_RLD_MAP, current_program_space->exec_bfd (),
-		   &dyn_ptr, NULL)
+  if (gdb_bfd_scan_elf_dyntag (DT_MIPS_RLD_MAP,
+			       current_program_space->exec_bfd (),
+			       &dyn_ptr, NULL)
       || scan_dyntag_auxv (DT_MIPS_RLD_MAP, &dyn_ptr, NULL))
     {
       struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
@@ -787,8 +685,9 @@ elf_locate_base (void)
   /* Then check DT_MIPS_RLD_MAP_REL.  MIPS executables now use this form
      because of needing to support PIE.  DT_MIPS_RLD_MAP will also exist
      in non-PIE.  */
-  if (scan_dyntag (DT_MIPS_RLD_MAP_REL, current_program_space->exec_bfd (),
-		   &dyn_ptr, &dyn_ptr_addr)
+  if (gdb_bfd_scan_elf_dyntag (DT_MIPS_RLD_MAP_REL,
+			       current_program_space->exec_bfd (),
+			       &dyn_ptr, &dyn_ptr_addr)
       || scan_dyntag_auxv (DT_MIPS_RLD_MAP_REL, &dyn_ptr, &dyn_ptr_addr))
     {
       struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
@@ -804,7 +703,8 @@ elf_locate_base (void)
     }
 
   /* Find DT_DEBUG.  */
-  if (scan_dyntag (DT_DEBUG, current_program_space->exec_bfd (), &dyn_ptr, NULL)
+  if (gdb_bfd_scan_elf_dyntag (DT_DEBUG, current_program_space->exec_bfd (),
+			       &dyn_ptr, NULL)
       || scan_dyntag_auxv (DT_DEBUG, &dyn_ptr, NULL))
     return dyn_ptr;
 
@@ -3258,7 +3158,7 @@ svr4_iterate_over_objfiles_in_search_order
 	abfd = current_objfile->obfd;
 
       if (abfd != nullptr
-	  && scan_dyntag (DT_SYMBOLIC, abfd, nullptr, nullptr) == 1)
+	  && gdb_bfd_scan_elf_dyntag (DT_SYMBOLIC, abfd, nullptr, nullptr) == 1)
 	{
 	  checked_current_objfile = true;
 	  if (cb (current_objfile, cb_data) != 0)
diff --git a/gdb/solib.c b/gdb/solib.c
index 317f7eb485e..e30affbb7e7 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -35,6 +35,8 @@
 #include "language.h"
 #include "gdbcmd.h"
 #include "completer.h"
+#include "elf/external.h"
+#include "elf/common.h"
 #include "filenames.h"		/* for DOSish file names */
 #include "exec.h"
 #include "solist.h"
@@ -1481,6 +1483,108 @@ gdb_bfd_lookup_symbol_from_symtab (bfd *abfd,
   return symaddr;
 }
 
+/* See solib.h.  */
+
+int
+gdb_bfd_scan_elf_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr,
+			 CORE_ADDR *ptr_addr)
+{
+  int arch_size, step, sect_size;
+  long current_dyntag;
+  CORE_ADDR dyn_ptr, dyn_addr;
+  gdb_byte *bufend, *bufstart, *buf;
+  Elf32_External_Dyn *x_dynp_32;
+  Elf64_External_Dyn *x_dynp_64;
+  struct bfd_section *sect;
+
+  if (abfd == NULL)
+    return 0;
+
+  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
+    return 0;
+
+  arch_size = bfd_get_arch_size (abfd);
+  if (arch_size == -1)
+    return 0;
+
+  /* Find the start address of the .dynamic section.  */
+  sect = bfd_get_section_by_name (abfd, ".dynamic");
+  if (sect == NULL)
+    return 0;
+
+  bool found = false;
+  for (const target_section &target_section
+	 : current_program_space->target_sections ())
+    if (sect == target_section.the_bfd_section)
+      {
+	dyn_addr = target_section.addr;
+	found = true;
+	break;
+      }
+  if (!found)
+    {
+      /* ABFD may come from OBJFILE acting only as a symbol file without being
+	 loaded into the target (see add_symbol_file_command).  This case is
+	 such fallback to the file VMA address without the possibility of
+	 having the section relocated to its actual in-memory address.  */
+
+      dyn_addr = bfd_section_vma (sect);
+    }
+
+  /* Read in .dynamic from the BFD.  We will get the actual value
+     from memory later.  */
+  sect_size = bfd_section_size (sect);
+  buf = bufstart = (gdb_byte *) alloca (sect_size);
+  if (!bfd_get_section_contents (abfd, sect,
+				 buf, 0, sect_size))
+    return 0;
+
+  /* Iterate over BUF and scan for DYNTAG.  If found, set PTR and return.  */
+  step = (arch_size == 32) ? sizeof (Elf32_External_Dyn)
+			   : sizeof (Elf64_External_Dyn);
+  for (bufend = buf + sect_size;
+       buf < bufend;
+       buf += step)
+  {
+    if (arch_size == 32)
+      {
+	x_dynp_32 = (Elf32_External_Dyn *) buf;
+	current_dyntag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_tag);
+	dyn_ptr = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_un.d_ptr);
+      }
+    else
+      {
+	x_dynp_64 = (Elf64_External_Dyn *) buf;
+	current_dyntag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag);
+	dyn_ptr = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_un.d_ptr);
+      }
+    if (current_dyntag == DT_NULL)
+      return 0;
+    if (current_dyntag == desired_dyntag)
+      {
+	/* If requested, try to read the runtime value of this .dynamic
+	   entry.  */
+	if (ptr)
+	  {
+	    struct type *ptr_type;
+	    gdb_byte ptr_buf[8];
+	    CORE_ADDR ptr_addr_1;
+
+	    ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
+	    ptr_addr_1 = dyn_addr + (buf - bufstart) + arch_size / 8;
+	    if (target_read_memory (ptr_addr_1, ptr_buf, arch_size / 8) == 0)
+	      dyn_ptr = extract_typed_address (ptr_buf, ptr_type);
+	    *ptr = dyn_ptr;
+	    if (ptr_addr)
+	      *ptr_addr = dyn_addr + (buf - bufstart);
+	  }
+	return 1;
+      }
+  }
+
+  return 0;
+}
+
 /* Lookup the value for a specific symbol from symbol table.  Look up symbol
    from ABFD.  MATCH_SYM is a callback function to determine whether to pick
    up a symbol.  DATA is the input of this callback function.  Return NULL
diff --git a/gdb/solib.h b/gdb/solib.h
index a94e9d3cd9e..c50f74e06bf 100644
--- a/gdb/solib.h
+++ b/gdb/solib.h
@@ -112,6 +112,12 @@ extern CORE_ADDR gdb_bfd_lookup_symbol_from_symtab (bfd *abfd,
 						       const void *),
 						    const void *data);
 
+/* Scan for DESIRED_DYNTAG in .dynamic section of ABFD.  If DESIRED_DYNTAG is
+   found, 1 is returned and the corresponding PTR and PTR_ADDR are set.  */
+
+extern int gdb_bfd_scan_elf_dyntag (const int desired_dyntag, bfd *abfd,
+				    CORE_ADDR *ptr, CORE_ADDR *ptr_addr);
+
 /* Enable or disable optional solib event breakpoints as appropriate.  */
 
 extern void update_solib_breakpoints (void);
-- 
2.31.1


  reply	other threads:[~2021-08-12  4:24 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-12  4:24 [PATCH v3 0/3] Add debuginfod core file support Aaron Merey
2021-08-12  4:24 ` Aaron Merey [this message]
2021-08-17 13:28   ` [PATCH 1/3] gdb/solib: Refactor scan_dyntag Simon Marchi
2021-08-19  2:30     ` Aaron Merey
2021-08-12  4:24 ` [PATCH 2/3] gdb: Add soname to build-id mapping for corefiles Aaron Merey
2021-08-15 14:51   ` Lancelot SIX
2021-08-17 13:58     ` Simon Marchi
2021-08-19  2:22       ` Aaron Merey
2021-09-29  1:12         ` Aaron Merey
2021-10-18 23:06           ` [PING**2][PATCH " Aaron Merey
2021-11-03 18:12             ` [PING**3][PATCH " Aaron Merey
2021-11-04  1:32         ` [PATCH " Simon Marchi
2021-08-12  4:24 ` [PATCH 3/3] PR gdb/27570: missing support for debuginfod in core_target::build_file_mappings Aaron Merey
2021-09-29  1:13   ` Aaron Merey
2021-10-18 23:05     ` [PING**2][PATCH " Aaron Merey
2021-11-03 18:11       ` [PING**3][PATCH " Aaron Merey
2021-11-04  1:37   ` [PATCH " Simon Marchi

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=20210812042406.75637-2-amerey@redhat.com \
    --to=amerey@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=simon.marchi@polymtl.ca \
    --cc=tom@tromey.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).