Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Jan Kratochvil <jan.kratochvil@redhat.com>
To: Aleksandar Ristovski <aristovski@qnx.com>
Cc: "gdb-patches@sourceware.org" <gdb-patches@sourceware.org>
Subject: [draft patch 6/6] gdbserver build-id attribute generator (unfixed)
Date: Sun, 10 Mar 2013 21:09:00 -0000	[thread overview]
Message-ID: <20130310210843.GG21130@host2.jankratochvil.net> (raw)
In-Reply-To: <51278984.3070208@qnx.com>

--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -40179,6 +40179,9 @@ memory address.  It is a displacement of absolute memory address against
 address the file was prelinked to during the library load.
 @item
 @code{l_ld}, which is memory address of the @code{PT_DYNAMIC} segment
+@item
+@code{build-id}, hex encoded @code{.note.gnu.build-id} section, if such
+section exists.
 @end itemize
 
 Additionally the single @code{main-lm} attribute specifies address of
@@ -40196,7 +40199,7 @@ looks like this:
   <library name="/lib/ld-linux.so.2" lm="0xe4f51c" l_addr="0xe2d000"
            l_ld="0xe4eefc"/>
   <library name="/lib/libc.so.6" lm="0xe4fbe8" l_addr="0x154000"
-           l_ld="0x152350"/>
+           l_ld="0x152350" build-id="9afccf7cc41e6293476223fe72480854"/>
 </library-list-svr>
 @end smallexample
 
@@ -40212,6 +40215,7 @@ The format of an SVR4 library list is described by this DTD:
 <!ATTLIST library            lm      CDATA   #REQUIRED>
 <!ATTLIST library            l_addr  CDATA   #REQUIRED>
 <!ATTLIST library            l_ld    CDATA   #REQUIRED>
+<!ATTLIST library            build-id CDATA  #IMPLIED>
 @end smallexample
 
 @node Memory Map Format
--- a/gdb/features/library-list-svr4.dtd
+++ b/gdb/features/library-list-svr4.dtd
@@ -14,3 +14,4 @@
 <!ATTLIST library            lm      CDATA   #REQUIRED>
 <!ATTLIST library            l_addr  CDATA   #REQUIRED>
 <!ATTLIST library            l_ld    CDATA   #REQUIRED>
+<!ATTLIST library            build-id CDATA  #IMPLIED>
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -20,6 +20,7 @@
 #include "linux-low.h"
 #include "linux-osdata.h"
 #include "agent.h"
+#include "linux-maps.h"
 
 #include "gdb_wait.h"
 #include <stdio.h>
@@ -5639,6 +5640,149 @@ struct link_map_offsets
     int l_prev_offset;
   };
 
+struct find_memory_region_callback_data
+{
+  unsigned is_elf64 : 1;
+  const char *soname;
+  CORE_ADDR l_addr;
+
+  /* Return.  Meaningful iff *build_id != NULL.  */
+  size_t build_idsz;
+
+  /* Return.  malloc allocated memory.  */
+  void *build_id;
+};
+
+static linux_find_memory_region_ftype find_memory_region_callback;
+
+static int
+find_memory_region_callback (ULONGEST vaddr, ULONGEST size, ULONGEST offset,
+			     ULONGEST inode, int read, int write, int exec,
+			     int modified, const char *filename, void *data)
+{
+  struct find_memory_region_callback_data *p = data;
+
+  if (filename != NULL && strcmp (filename, p->soname) == 0)
+    {
+      union ElfXX_Ehdr
+	{
+	  Elf32_Ehdr _32;
+	  Elf64_Ehdr _64;
+	} ehdr;
+      union ElfXX_Phdr
+	{
+	  Elf32_Phdr _32;
+	  Elf64_Phdr _64;
+	} phdr;
+      union ElfXX_Nhdr
+	{
+	  Elf32_Nhdr _32;
+	  Elf64_Nhdr _64;
+	} *nhdr;
+#define HDR(p, hdr, fld) (((p)->is_elf64)? (hdr)._64.fld : (hdr)._32.fld)
+      if (linux_read_memory (vaddr, (unsigned char *) &ehdr, sizeof (ehdr))
+	  == 0
+	  && HDR (p, ehdr, e_ident[EI_MAG0]) == ELFMAG0
+	  && HDR (p, ehdr, e_ident[EI_MAG1]) == ELFMAG1
+	  && HDR (p, ehdr, e_ident[EI_MAG2]) == ELFMAG2
+	  && HDR (p, ehdr, e_ident[EI_MAG3]) == ELFMAG3)
+	{
+	  unsigned i;
+
+	  for (i = 0; i < HDR (p, ehdr, e_phnum); ++i)
+	    {
+	      if (linux_read_memory (vaddr + HDR (p, ehdr, e_phoff)
+				     + HDR (p, ehdr, e_phentsize) * i,
+				     (unsigned char *) &phdr,
+				     HDR (p, ehdr, e_phentsize)) != 0)
+		{
+		  warning ("Could not read program header.");
+		  break;
+		}
+	      if (HDR (p, phdr, p_type) == PT_NOTE)
+		{
+	          nhdr = xmalloc (HDR (p, phdr, p_memsz));
+
+		  if (linux_read_memory (p->l_addr + HDR (p, phdr, p_vaddr),
+					 (unsigned char *) nhdr,
+					 HDR (p, phdr, p_memsz)) != 0)
+		    {
+		      warning ("Could not read note.");
+		      break;
+		    }
+		  if (HDR (p, *nhdr, n_type) == NT_GNU_BUILD_ID)
+		    {
+		      p->build_idsz = (HDR (p, *nhdr, n_namesz)
+				       + HDR (p, *nhdr, n_descsz)
+				       + (p->is_elf64
+					  ? sizeof (nhdr->_64)
+					  : sizeof (nhdr->_32)));
+		      if (p->build_idsz > HDR (p, phdr, p_memsz))
+			{
+			  warning ("NT_GNU_BUILD_ID has invalid size..");
+			  break;
+			}
+		      p->build_id = nhdr;
+		      break;
+		    }
+		  free (nhdr);
+		}
+	    }
+	}
+      else
+	warning ("Reading build-id failed.");
+
+      return 1;
+    }
+#undef HDR
+  return 0;
+}
+
+/* Return malloc allocated buffer.  User must free it.
+
+   NULL may be returned if build-id could not be fetched.  */
+
+static char *
+get_hex_build_id (const char *const soname, const int is_elf64,
+		  const CORE_ADDR l_addr)
+{
+  struct find_memory_region_callback_data data;
+  char *hex_build_id;
+  char *real_soname = realpath (soname, NULL);
+
+  if (real_soname == NULL)
+    {
+      fprintf (stderr, "Failed to get realpath of %s (%s).\n", soname,
+	       strerror (errno));
+      return NULL;
+    }
+
+  data.is_elf64 = is_elf64 != 0;
+  data.soname = real_soname;
+  data.l_addr = l_addr;
+  data.build_idsz = 0;
+  data.build_id = NULL;
+
+  linux_find_memory_regions_full (lwpid_of (get_thread_lwp (current_inferior)),
+				  find_memory_region_callback, &data, NULL);
+  free (real_soname);
+  if (data.build_id != NULL)
+    {
+      hex_build_id = xmalloc (data->build_idsz * 2 + 1);
+      if (bin2hex (data.build_id, hex_build_id, data->build_idsz)
+	  != data->build_idsz)
+	{
+	  fprintf (stderr, "Hex encoding of build-id failed\n");
+	  xfree (hex_build_id);
+	  hex_build_id = NULL;
+	}
+    }
+  else
+    hex_build_id = NULL;
+  free (data.build_id);
+  return hex_build_id;
+}
+
 /* Construct qXfer:libraries-svr4:read reply.  */
 
 static int
@@ -5760,6 +5904,7 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
 	      /* 6x the size for xml_escape_text below.  */
 	      size_t len = 6 * strlen ((char *) libname);
 	      char *name;
+	      char *hex_enc_build_id;
 
 	      if (!header_done)
 		{
@@ -5768,7 +5913,12 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
 		  header_done = 1;
 		}
 
-	      while (allocated < p - document + len + 200)
+	      name = xml_escape_text ((char *) libname);
+	      hex_enc_build_id = get_hex_build_id (name, is_elf64, l_addr);
+
+	      while (allocated < (p - document + len + 200
+				  + (hex_enc_build_id != NULL
+				     ? strlen (hex_enc_build_id) : 0)))
 		{
 		  /* Expand to guarantee sufficient storage.  */
 		  uintptr_t document_len = p - document;
@@ -5778,12 +5928,15 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
 		  p = document + document_len;
 		}
 
-	      name = xml_escape_text ((char *) libname);
 	      p += sprintf (p, "<library name=\"%s\" lm=\"0x%lx\" "
-			       "l_addr=\"0x%lx\" l_ld=\"0x%lx\"/>",
+			       "l_addr=\"0x%lx\" l_ld=\"0x%lx\"",
 			    name, (unsigned long) lm_addr,
 			    (unsigned long) l_addr, (unsigned long) l_ld);
+	      if (hex_enc_build_id != NULL)
+		p += sprintf (p, " build-id=\"%s\"", hex_enc_build_id);
+	      p += sprintf(p, "/>");
 	      free (name);
+	      xfree (hex_enc_build_id);
 	    }
 	  else if (lm_prev == 0)
 	    {


  parent reply	other threads:[~2013-03-10 21:09 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-02-22 15:07 [patch] gdbserver build-id in qxfer_libraries reply Aleksandar Ristovski
2013-02-22 18:39 ` Aleksandar Ristovski
2013-02-26 12:01   ` Pedro Alves
2013-02-27 17:25     ` Aleksandar Ristovski
2013-02-27 17:31       ` Aleksandar Ristovski
2013-02-27 18:44       ` Eli Zaretskii
2013-03-10 21:07 ` [draft patch 0/6] Split FYI and some review notes Jan Kratochvil
2013-03-11 14:25   ` Aleksandar Ristovski
2013-03-11 15:07     ` Jan Kratochvil
2013-03-14 18:43       ` Gary Benson
2013-03-14 19:55         ` Tom Tromey
2013-03-15 15:35         ` Aleksandar Ristovski
2013-03-15 15:44   ` Aleksandar Ristovski
2013-03-15 15:38     ` Aleksandar Ristovski
2013-03-15 16:28     ` Jan Kratochvil
2013-03-15 16:43       ` Aleksandar Ristovski
2013-03-10 21:08 ` [draft patch 2/6] Merge multiple hex conversions Jan Kratochvil
2013-03-22 13:05   ` [patch " Aleksandar Ristovski
2013-04-05 16:07     ` Aleksandar Ristovski
2013-03-10 21:08 ` [draft patch 1/6] Move utility functions to common/ Jan Kratochvil
2013-03-22 13:13   ` [patch " Aleksandar Ristovski
2013-03-22 13:05     ` Aleksandar Ristovski
2013-04-07 18:54     ` Aleksandar Ristovski
2013-04-05 13:06       ` Aleksandar Ristovski
2013-03-10 21:08 ` [draft patch 3/6] Create empty common/linux-maps.[ch] Jan Kratochvil
2013-03-22 14:54   ` [patch " Aleksandar Ristovski
2013-03-22 13:06     ` Aleksandar Ristovski
2013-04-05 13:25     ` Aleksandar Ristovski
2013-03-10 21:08 ` [draft patch 4/6] Prepare linux_find_memory_regions_full & co. for move Jan Kratochvil
2013-03-22 13:34   ` [patch " Aleksandar Ristovski
2013-03-22 13:54     ` Aleksandar Ristovski
2013-03-26 18:11     ` Jan Kratochvil
2013-03-27 20:44       ` Aleksandar Ristovski
2013-03-27 21:54         ` Aleksandar Ristovski
2013-03-28 23:02         ` Jan Kratochvil
2013-03-29  0:26           ` Aleksandar Ristovski
2013-03-29  0:29             ` Pedro Alves
2013-04-01 22:39           ` Aleksandar Ristovski
2013-04-01 21:13             ` Aleksandar Ristovski
2013-04-02 13:41             ` Jan Kratochvil
2013-04-02 13:41               ` Aleksandar Ristovski
2013-04-02 13:41                 ` Jan Kratochvil
2013-04-05 15:37                   ` Aleksandar Ristovski
2013-04-07 14:28                     ` Aleksandar Ristovski
2013-03-10 21:09 ` [draft patch 5/6] Move linux_find_memory_regions_full & co Jan Kratochvil
2013-03-22 13:05   ` [patch " Aleksandar Ristovski
2013-03-22 13:34     ` Aleksandar Ristovski
2013-03-26 18:27     ` Jan Kratochvil
2013-03-27 21:25       ` Aleksandar Ristovski
2013-03-28 22:38         ` Jan Kratochvil
2013-04-01 23:19           ` Aleksandar Ristovski
2013-04-02  2:33             ` Aleksandar Ristovski
2013-04-02  2:33             ` Jan Kratochvil
2013-04-07 18:54               ` Aleksandar Ristovski
2013-04-05 15:37                 ` Aleksandar Ristovski
2013-03-10 21:09 ` Jan Kratochvil [this message]
2013-03-10 22:04   ` [draft patch 6/6] gdbserver build-id attribute generator (unfixed) Eli Zaretskii
2013-03-22 13:05   ` [patch 6/6] gdbserver build-id attribute generator Aleksandar Ristovski
2013-03-22 15:19     ` Aleksandar Ristovski
2013-03-22 17:24     ` Eli Zaretskii
2013-03-26 23:45     ` Jan Kratochvil
2013-03-27 17:54       ` Aleksandar Ristovski
2013-03-27 18:08         ` Jan Kratochvil
2013-03-27 18:12           ` Eli Zaretskii
2013-03-27 20:46           ` Aleksandar Ristovski
2013-03-29  0:13             ` Aleksandar Ristovski
2013-03-29  0:20               ` Aleksandar Ristovski
2013-03-29 16:19               ` Jan Kratochvil
     [not found]               ` <20130331174322.GB21374@host2.jankratochvil.net>
2013-04-02 17:18                 ` Aleksandar Ristovski
2013-04-04  2:22                   ` Jan Kratochvil
2013-04-05 15:05                     ` Aleksandar Ristovski
2013-04-09 15:28                       ` Gary Benson
2013-04-09 15:28                         ` Aleksandar Ristovski
2013-04-09 19:26                           ` Gary Benson
2013-04-12 15:28                             ` Jan Kratochvil
2013-04-09 15:28                         ` Jan Kratochvil
2013-04-09 15:29                           ` Gary Benson
2013-04-09 15:29                           ` Aleksandar Ristovski
2013-04-04 16:08 ` [patch] gdbserver build-id in qxfer_libraries reply Jan Kratochvil

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=20130310210843.GG21130@host2.jankratochvil.net \
    --to=jan.kratochvil@redhat.com \
    --cc=aristovski@qnx.com \
    --cc=gdb-patches@sourceware.org \
    /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