This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH 3/4] Factor out common code for supporting 'ld --buildid'
- From: Jon TURNEY <jon dot turney at dronecode dot org dot uk>
- To: binutils at sourceware dot org
- Cc: Jon TURNEY <jon dot turney at dronecode dot org dot uk>
- Date: Thu, 23 Jan 2014 17:46:08 +0000
- Subject: [PATCH 3/4] Factor out common code for supporting 'ld --buildid'
- Authentication-results: sourceware.org; auth=none
- References: <1390499169-5908-1-git-send-email-jon dot turney at dronecode dot org dot uk>
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