This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 3/4] Factor out common code for supporting 'ld --buildid'


Factor out the code for parsing the 'ld --buildid' option and calculating the
build-id, which will be common between ELF and PE/COFF implementations, as
ldbuildid.c.  Place prototypes in ldbuildid.h.

uuid-style buildid can't be supported on MinGW due to lack of /dev/urandom.

XXX: This doesn't include the regeneration of ld/Makefile.in, as I don't have
the correct automake version available.

Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>

ld/ChangeLog:

2014-01-20  Jon TURNEY  <jon.turney@dronecode.org.uk>

	* emultempl/elf32.em (id_note_section_size, read_hex, write_build_id):
	Move code for parsing build-id option and calculating the build-id to...
	* ldbuildid.c: New file.
	* ldbuildid.h: New file.
	* Makefile.am (CFILES, HFILES, OFILES, ld_new_SOURCES): Add new files.

Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
---
 ld/Makefile.am        |   9 ++--
 ld/emultempl/elf32.em |  96 +++------------------------------
 ld/ldbuildid.c        | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++
 ld/ldbuildid.h        |  39 ++++++++++++++
 4 files changed, 195 insertions(+), 94 deletions(-)
 create mode 100644 ld/ldbuildid.c
 create mode 100644 ld/ldbuildid.h

diff --git a/ld/Makefile.am b/ld/Makefile.am
index 1abb340..5eaa469 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -550,12 +550,12 @@ ALL_EMUL_EXTRA_OFILES = \
 CFILES = ldctor.c ldemul.c ldexp.c ldfile.c ldlang.c \
 	ldmain.c ldmisc.c ldver.c ldwrite.c lexsup.c \
 	mri.c ldcref.c pe-dll.c pep-dll.c ldlex-wrapper.c \
-	$(PLUGIN_C)
+	$(PLUGIN_C) ldbuildid.c
 
 HFILES = ld.h ldctor.h ldemul.h ldexp.h ldfile.h \
 	ldlang.h ldlex.h ldmain.h ldmisc.h ldver.h \
 	ldwrite.h mri.h deffile.h pe-dll.h pep-dll.h \
-	elf-hints-local.h $(PLUGIN_H)
+	elf-hints-local.h $(PLUGIN_H) ldbuildid.h
 
 GENERATED_CFILES = ldgram.c ldlex.c deffilep.c
 GENERATED_HFILES = ldgram.h ldemul-list.h deffilep.h
@@ -567,7 +567,8 @@ BUILT_SOURCES = $(GENERATED_HFILES)
 OFILES = ldgram.@OBJEXT@ ldlex-wrapper.@OBJEXT@ lexsup.@OBJEXT@ ldlang.@OBJEXT@ \
 	mri.@OBJEXT@ ldctor.@OBJEXT@ ldmain.@OBJEXT@ $(PLUGIN_OBJECT) \
 	ldwrite.@OBJEXT@ ldexp.@OBJEXT@  ldemul.@OBJEXT@ ldver.@OBJEXT@ ldmisc.@OBJEXT@ \
-	ldfile.@OBJEXT@ ldcref.@OBJEXT@ ${EMULATION_OFILES} ${EMUL_EXTRA_OFILES}
+	ldfile.@OBJEXT@ ldcref.@OBJEXT@ ${EMULATION_OFILES} ${EMUL_EXTRA_OFILES} \
+	ldbuildid.@OBJEXT@
 
 STAGESTUFF = *.@OBJEXT@ ldscripts/* e*.c
 
@@ -2215,7 +2216,7 @@ EXTRA_ld_new_SOURCES = deffilep.y ldlex.l
 EXTRA_ld_new_SOURCES += pep-dll.c pe-dll.c
 
 ld_new_SOURCES = ldgram.y ldlex-wrapper.c lexsup.c ldlang.c mri.c ldctor.c ldmain.c \
-	ldwrite.c ldexp.c ldemul.c ldver.c ldmisc.c ldfile.c ldcref.c $(PLUGIN_C)
+	ldwrite.c ldexp.c ldemul.c ldver.c ldmisc.c ldfile.c ldcref.c $(PLUGIN_C) ldbuildid.c
 ld_new_DEPENDENCIES = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBIBERTY) $(LIBINTL_DEP)
 ld_new_LDADD = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBIBERTY) $(LIBINTL)
 
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index a4f04f1..4674bba 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -41,10 +41,7 @@ fragment <<EOF
 #include "bfd.h"
 #include "libiberty.h"
 #include "filenames.h"
-#include "safe-ctype.h"
 #include "getopt.h"
-#include "md5.h"
-#include "sha1.h"
 #include <fcntl.h>
 
 #include "bfdlink.h"
@@ -56,6 +53,7 @@ fragment <<EOF
 #include "ldlang.h"
 #include "ldfile.h"
 #include "ldemul.h"
+#include "ldbuildid.h"
 #include <ldgram.h>
 #include "elf/common.h"
 #include "elf-bfd.h"
@@ -897,53 +895,20 @@ id_note_section_size (bfd *abfd ATTRIBUTE_UNUSED)
 {
   const char *style = emit_note_gnu_build_id;
   bfd_size_type size;
+  bfd_size_type build_id_size;
 
   size = offsetof (Elf_External_Note, name[sizeof "GNU"]);
   size = (size + 3) & -(bfd_size_type) 4;
 
-  if (!strcmp (style, "md5") || !strcmp (style, "uuid"))
-    size += 128 / 8;
-  else if (!strcmp (style, "sha1"))
-    size += 160 / 8;
-  else if (!strncmp (style, "0x", 2))
-    {
-      /* ID is in string form (hex).  Convert to bits.  */
-      const char *id = style + 2;
-      do
-	{
-	  if (ISXDIGIT (id[0]) && ISXDIGIT (id[1]))
-	    {
-	      ++size;
-	      id += 2;
-	    }
-	  else if (*id == '-' || *id == ':')
-	    ++id;
-	  else
-	    {
-	      size = 0;
-	      break;
-	    }
-	} while (*id != '\0');
-    }
+  build_id_size = compute_build_id_size(style);
+  if (build_id_size)
+    size += build_id_size;
   else
     size = 0;
 
   return size;
 }
 
-static unsigned char
-read_hex (const char xdigit)
-{
-  if (ISDIGIT (xdigit))
-    return xdigit - '0';
-  if (ISUPPER (xdigit))
-    return xdigit - 'A' + 0xa;
-  if (ISLOWER (xdigit))
-    return xdigit - 'a' + 0xa;
-  abort ();
-  return 0;
-}
-
 static bfd_boolean
 write_build_id (bfd *abfd)
 {
@@ -956,7 +921,6 @@ write_build_id (bfd *abfd)
   bfd_size_type size;
   file_ptr position;
   Elf_External_Note *e_note;
-  typedef void (*sum_fn) (const void *, size_t, void *);
 
   style = t->o->build_id.style;
   asec = t->o->build_id.sec;
@@ -988,55 +952,7 @@ write_build_id (bfd *abfd)
   bfd_h_put_32 (abfd, NT_GNU_BUILD_ID, &e_note->type);
   memcpy (e_note->name, "GNU", sizeof "GNU");
 
-  if (strcmp (style, "md5") == 0)
-    {
-      struct md5_ctx ctx;
-
-      md5_init_ctx (&ctx);
-      if (!bed->s->checksum_contents (abfd, (sum_fn) &md5_process_bytes, &ctx))
-	return FALSE;
-      md5_finish_ctx (&ctx, id_bits);
-    }
-  else if (strcmp (style, "sha1") == 0)
-    {
-      struct sha1_ctx ctx;
-
-      sha1_init_ctx (&ctx);
-      if (!bed->s->checksum_contents (abfd, (sum_fn) &sha1_process_bytes, &ctx))
-	return FALSE;
-      sha1_finish_ctx (&ctx, id_bits);
-    }
-  else if (strcmp (style, "uuid") == 0)
-    {
-      int n;
-      int fd = open ("/dev/urandom", O_RDONLY);
-      if (fd < 0)
-	return FALSE;
-      n = read (fd, id_bits, size);
-      close (fd);
-      if (n < (int) size)
-	return FALSE;
-    }
-  else if (strncmp (style, "0x", 2) == 0)
-    {
-      /* ID is in string form (hex).  Convert to bits.  */
-      const char *id = style + 2;
-      size_t n = 0;
-      do
-	{
-	  if (ISXDIGIT (id[0]) && ISXDIGIT (id[1]))
-	    {
-	      id_bits[n] = read_hex (*id++) << 4;
-	      id_bits[n++] |= read_hex (*id++);
-	    }
-	  else if (*id == '-' || *id == ':')
-	    ++id;
-	  else
-	    abort ();		/* Should have been validated earlier.  */
-	} while (*id != '\0');
-    }
-  else
-    abort ();			/* Should have been validated earlier.  */
+  generate_build_id(abfd, style, bed->s->checksum_contents, id_bits);
 
   position = i_shdr->sh_offset + asec->output_offset;
   size = asec->size;
diff --git a/ld/ldbuildid.c b/ld/ldbuildid.c
new file mode 100644
index 0000000..bdd2df4
--- /dev/null
+++ b/ld/ldbuildid.c
@@ -0,0 +1,145 @@
+/* ldbuildid.c - Build Id support routines
+   Copyright 2013 Free Software Foundation, Inc.
+
+   This file is part of the GNU Binutils.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "sysdep.h"
+#include "bfd.h"
+#include "safe-ctype.h"
+#include "md5.h"
+#include "sha1.h"
+
+#include "ldbuildid.h"
+
+bfd_boolean
+validate_build_id_style(const char *style)
+{
+ if ((strcmp (style, "md5") == 0) ||
+     (strcmp (style, "sha1") == 0) ||
+#ifndef __MINGW32__
+     (strcmp (style, "uuid") == 0) ||
+#endif
+     (strncmp (style, "0x", 2) == 0))
+   return TRUE;
+
+ return FALSE;
+}
+
+bfd_size_type
+compute_build_id_size(const char *style)
+{
+  if (!strcmp (style, "md5") || !strcmp (style, "uuid"))
+    return  128 / 8;
+  else if (!strcmp (style, "sha1"))
+    return  160 / 8;
+  else if (!strncmp (style, "0x", 2))
+    {
+      bfd_size_type size = 0;
+      /* ID is in string form (hex).  Count the bytes */
+      const char *id = style + 2;
+      do
+	{
+	  if (ISXDIGIT (id[0]) && ISXDIGIT (id[1]))
+	    {
+	      ++size;
+	      id += 2;
+	    }
+	  else if (*id == '-' || *id == ':')
+	    ++id;
+	  else
+	    {
+	      size = 0;
+	      break;
+	    }
+	} while (*id != '\0');
+      return size;
+    }
+  return 0;
+}
+
+static unsigned char
+read_hex (const char xdigit)
+{
+  if (ISDIGIT (xdigit))
+    return xdigit - '0';
+  if (ISUPPER (xdigit))
+    return xdigit - 'A' + 0xa;
+  if (ISLOWER (xdigit))
+    return xdigit - 'a' + 0xa;
+  abort ();
+  return 0;
+}
+
+bfd_boolean
+generate_build_id(bfd *abfd, const char *style, checksum_fn checksum_contents, unsigned char *id_bits)
+{
+  if (strcmp (style, "md5") == 0)
+    {
+      struct md5_ctx ctx;
+      md5_init_ctx (&ctx);
+      if (!(*checksum_contents) (abfd, (sum_fn) &md5_process_bytes, &ctx))
+	return FALSE;
+      md5_finish_ctx (&ctx, id_bits);
+    }
+  else if (strcmp (style, "sha1") == 0)
+    {
+      struct sha1_ctx ctx;
+      sha1_init_ctx (&ctx);
+      if (!(*checksum_contents) (abfd, (sum_fn) &sha1_process_bytes, &ctx))
+	return FALSE;
+      sha1_finish_ctx (&ctx, id_bits);
+    }
+#ifndef __MINGW32__
+  else if (strcmp (style, "uuid") == 0)
+    {
+      int n;
+      int fd = open ("/dev/urandom", O_RDONLY);
+      int size = 128 / 8;
+      if (fd < 0)
+	return FALSE;
+      n = read (fd, id_bits, size);
+      close (fd);
+      if (n < size)
+        {
+          return FALSE;
+        }
+    }
+#endif
+  else if (strncmp (style, "0x", 2) == 0)
+    {
+      /* ID is in string form (hex).  Convert to bits.  */
+      const char *id = style + 2;
+      size_t n = 0;
+      do
+	{
+	  if (ISXDIGIT (id[0]) && ISXDIGIT (id[1]))
+	    {
+	      id_bits[n] = read_hex (*id++) << 4;
+	      id_bits[n++] |= read_hex (*id++);
+	    }
+	  else if (*id == '-' || *id == ':')
+	    ++id;
+	  else
+	    abort ();		/* Should have been validated earlier.  */
+	} while (*id != '\0');
+    }
+  else
+    abort ();			/* Should have been validated earlier.  */
+
+  return TRUE;
+}
diff --git a/ld/ldbuildid.h b/ld/ldbuildid.h
new file mode 100644
index 0000000..365bb31
--- /dev/null
+++ b/ld/ldbuildid.h
@@ -0,0 +1,39 @@
+/* ldbuildid.h -
+   Copyright 2013 Free Software Foundation, Inc.
+
+   This file is part of the GNU Binutils.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#ifndef LDBUILDID_H
+#define LDBUILDID_H
+
+bfd_boolean
+validate_build_id_style(const char *style);
+
+bfd_size_type
+compute_build_id_size(const char *style);
+
+typedef void (*sum_fn) (const void *, size_t, void *);
+
+typedef bfd_boolean (*checksum_fn) (bfd *abfd,
+              void (*process) (const void *, size_t, void *),
+              void *arg);
+
+bfd_boolean
+generate_build_id(bfd *abfd, const char *style, checksum_fn checksum_contents, unsigned char *id_bits);
+
+#endif
-- 
1.8.3.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]