RPM Package Manager, CVS Repository
http://rpm5.org/cvs/
____________________________________________________________________________
Server: rpm5.org Name: Jeff Johnson
Root: /v/rpm/cvs Email: jbj@rpm5.org
Module: rpm Date: 28-Aug-2007 18:10:19
Branch: rpm-4_5 Handle: 2007082817101801
Modified files: (Branch: rpm-4_5)
rpm CHANGES
rpm/tools Makefile.am debugedit.c
Log:
- update debugedit to include buildid changes.
Summary:
Revision Changes Path
1.1360.2.35 +1 -0 rpm/CHANGES
2.85.2.2 +4 -1 rpm/tools/Makefile.am
2.9.2.1 +171 -5 rpm/tools/debugedit.c
____________________________________________________________________________
patch -p0 <<'@@ .'
Index: rpm/CHANGES
============================================================================
$ cvs diff -u -r1.1360.2.34 -r1.1360.2.35 CHANGES
--- rpm/CHANGES 28 Aug 2007 00:44:41 -0000 1.1360.2.34
+++ rpm/CHANGES 28 Aug 2007 16:10:18 -0000 1.1360.2.35
@@ -1,4 +1,5 @@
4.4.9 -> 4.5:
+ - jbj: update debugedit to include buildid changes.
- jbj: update id.po (Translation Project).
- jbj: prepare for open as a macro in bleeding edge glibc-2.6.90+.
- jbj: python: backport signalsCaught, remove archscore.
@@ .
patch -p0 <<'@@ .'
Index: rpm/tools/Makefile.am
============================================================================
$ cvs diff -u -r2.85.2.1 -r2.85.2.2 Makefile.am
--- rpm/tools/Makefile.am 17 Jun 2007 01:11:49 -0000 2.85.2.1
+++ rpm/tools/Makefile.am 28 Aug 2007 16:10:19 -0000 2.85.2.2
@@ -28,7 +28,10 @@
convertdb1_SOURCES = convertdb1.c
debugedit_SOURCES = debugedit.c hashtab.c
-debugedit_LDADD = @WITH_LIBELF_LIB@ @WITH_POPT_LIB@
+debugedit_LDADD = \
+ @WITH_LIBELF_LIB@\
+ @WITH_BEECRYPT_LIB@\
+ @WITH_POPT_LIB@
rpmdeps_SOURCES = rpmdeps.c
@@ .
patch -p0 <<'@@ .'
Index: rpm/tools/debugedit.c
============================================================================
$ cvs diff -u -r2.9 -r2.9.2.1 debugedit.c
--- rpm/tools/debugedit.c 25 May 2007 17:36:41 -0000 2.9
+++ rpm/tools/debugedit.c 28 Aug 2007 16:10:19 -0000 2.9.2.1
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002, 2003, 2005 Red Hat, Inc.
+/* Copyright (C) 2001, 2002, 2003, 2005, 2007 Red Hat, Inc.
Written by Alexander Larsson <alexl@redhat.com>, 2002
Based on code by Jakub Jelinek <jakub@redhat.com>, 2001.
@@ -35,7 +35,7 @@
#include <gelf.h>
-#if 0 /* XXX compile without dwarf.h */
+#if 1 /* XXX compile without dwarf.h */
#include <dwarf.h>
#else
/* some defines taken from the dwarf standard */
@@ -69,6 +69,7 @@
#define DW_FORM_indirect 0x16
#endif
+#include "beecrypt.h"
#include "hashtab.h"
#define DW_TAG_partial_unit 0x3c
@@ -76,7 +77,8 @@
char *base_dir = NULL;
char *dest_dir = NULL;
char *list_file = NULL;
-int list_file_fd = -1;
+int list_file_fd = -1;
+int do_build_id = 0;
typedef unsigned int uint_32;
typedef unsigned short uint_16;
@@ -646,6 +648,7 @@
}
else
ptr = srcptr = dir;
+ unsigned char *srcstart=srcptr;
while (*srcptr != 0)
{
size_t len = strlen (srcptr) + 1;
@@ -1249,6 +1252,8 @@
"directory to rewrite base-dir into", NULL },
{ "list-file", 'l', POPT_ARG_STRING, &list_file, 0,
"file where to put list of source and header file names", NULL },
+ { "build-id", 'i', POPT_ARG_NONE, &do_build_id, 0,
+ "recompute build ID note and print ID on stdout", NULL },
POPT_AUTOHELP
{ NULL, 0, 0, NULL, 0, NULL, NULL }
};
@@ -1327,6 +1332,126 @@
return NULL;
}
+/* Compute a fresh build ID bit-string from the editted file contents. */
+static void
+handle_build_id (DSO *dso, Elf_Data *build_id,
+ size_t build_id_offset, size_t build_id_size)
+{
+ hashFunctionContext ctx;
+ const hashFunction *hf = NULL;
+ int i = hashFunctionCount ();
+
+ while (i-- > 0)
+ {
+ hf = hashFunctionGet (i);
+ if (hf != NULL && hf->digestsize == build_id_size)
+ break;
+ }
+ if (hf == NULL)
+ {
+ fprintf (stderr, "Cannot handle %Zu-byte build ID\n", build_id_size);
+ exit (1);
+ }
+
+ if (elf_update (dso->elf, ELF_C_NULL) < 0)
+ {
+ fprintf (stderr, "Failed to update file: %s\n",
+ elf_errmsg (elf_errno ()));
+ exit (1);
+ }
+
+ /* Clear the old bits so they do not affect the new hash. */
+ memset ((char *) build_id->d_buf + build_id_offset, 0, build_id_size);
+
+ hashFunctionContextInit (&ctx, hf);
+
+ /* Slurp the relevant header bits and section contents and feed them
+ into the hash function. The only bits we ignore are the offset
+ fields in ehdr and shdrs, since the semantically identical ELF file
+ could be written differently if it doesn't change the phdr layout.
+ We always use the GElf (i.e. Elf64) formats for the bits to hash
+ since it is convenient. It doesn't matter whether this is an Elf32
+ or Elf64 object, only that we are consistent in what bits feed the
+ hash so it comes out the same for the same file contents. */
+ {
+ inline void process (const void *data, size_t size);
+ inline void process (const void *data, size_t size)
+ {
+ memchunk chunk = { .data = (void *) data, .size = size };
+ hashFunctionContextUpdateMC (&ctx, &chunk);
+ }
+
+ union
+ {
+ GElf_Ehdr ehdr;
+ GElf_Phdr phdr;
+ GElf_Shdr shdr;
+ } u;
+ Elf_Data x = { .d_version = EV_CURRENT, .d_buf = &u };
+
+ x.d_type = ELF_T_EHDR;
+ x.d_size = sizeof u.ehdr;
+ u.ehdr = dso->ehdr;
+ u.ehdr.e_phoff = u.ehdr.e_shoff = 0;
+ if (elf64_xlatetom (&x, &x, dso->ehdr.e_ident[EI_DATA]) == NULL)
+ {
+ bad:
+ fprintf (stderr, "Failed to compute header checksum: %s\n",
+ elf_errmsg (elf_errno ()));
+ exit (1);
+ }
+
+ x.d_type = ELF_T_PHDR;
+ x.d_size = sizeof u.phdr;
+ for (i = 0; i < dso->ehdr.e_phnum; ++i)
+ {
+ if (gelf_getphdr (dso->elf, i, &u.phdr) == NULL)
+ goto bad;
+ if (elf64_xlatetom (&x, &x, dso->ehdr.e_ident[EI_DATA]) == NULL)
+ goto bad;
+ process (x.d_buf, x.d_size);
+ }
+
+ x.d_type = ELF_T_SHDR;
+ x.d_size = sizeof u.shdr;
+ for (i = 0; i < dso->ehdr.e_shnum; ++i)
+ if (dso->scn[i] != NULL)
+ {
+ u.shdr = dso->shdr[i];
+ u.shdr.sh_offset = 0;
+ if (elf64_xlatetom (&x, &x, dso->ehdr.e_ident[EI_DATA]) == NULL)
+ goto bad;
+ process (x.d_buf, x.d_size);
+
+ if (u.shdr.sh_type != SHT_NOBITS)
+ {
+ Elf_Data *d = elf_rawdata (dso->scn[i], NULL);
+ if (d == NULL)
+ goto bad;
+ process (d->d_buf, d->d_size);
+ }
+ }
+ }
+
+ hashFunctionContextDigest (&ctx, (byte *) build_id->d_buf + build_id_offset);
+ hashFunctionContextFree (&ctx);
+
+ elf_flagdata (build_id, ELF_C_SET, ELF_F_DIRTY);
+
+ /* Now format the build ID bits in hex to print out. */
+ {
+ const unsigned char * id = build_id->d_buf + build_id_offset;
+ char hex[build_id_size * 2 + 1];
+ int n = snprintf (hex, 3, "%02" PRIx8, id[0]);
+ assert (n == 2);
+ for (i = 1; i < build_id_size; ++i)
+ {
+ n = snprintf (&hex[i * 2], 3, "%02" PRIx8, id[i]);
+ assert (n == 2);
+ }
+ puts (hex);
+ }
+}
int
main (int argc, char *argv[])
@@ -1339,7 +1464,9 @@
const char **args;
struct stat stat_buf;
char *p;
-
+ Elf_Data *build_id = NULL;
+ size_t build_id_offset = 0, build_id_size = 0;
+
optCon = poptGetContext("debugedit", argc, (const char **)argv,
optionsTable, 0);
@@ -1442,13 +1569,52 @@
#endif
if (strcmp (name, ".debug_info") == 0)
edit_dwarf2 (dso);
-
+
+ break;
+ case SHT_NOTE:
+ if (do_build_id
+ && build_id == NULL && (dso->shdr[i].sh_flags & SHF_ALLOC))
+ {
+ /* Look for a build-ID note here. */
+ Elf_Data *data = elf_rawdata (elf_getscn (dso->elf, i), NULL);
+ Elf32_Nhdr nh;
+ Elf_Data dst =
+ {
+ .d_version = EV_CURRENT, .d_type = ELF_T_NHDR,
+ .d_buf = &nh, .d_size = sizeof nh
+ };
+ Elf_Data src = dst;
+ src.d_buf = data->d_buf;
+ assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr));
+ while (data->d_buf + data->d_size - src.d_buf > (int) sizeof nh
+ && elf32_xlatetom (&dst, &src, dso->ehdr.e_ident[EI_DATA]))
+ {
+ Elf32_Word len = sizeof nh + nh.n_namesz;
+ len = (len + 3) & ~3;
+
+ if (nh.n_namesz == sizeof "GNU" && nh.n_type == 3
+ && !memcmp (src.d_buf + sizeof nh, "GNU", sizeof "GNU"))
+ {
+ build_id = data;
+ build_id_offset = src.d_buf + len - data->d_buf;
+ build_id_size = nh.n_descsz;
+ break;
+ }
+
+ len += nh.n_descsz;
+ len = (len + 3) & ~3;
+ src.d_buf += len;
+ }
+ }
break;
default:
break;
}
}
+ if (do_build_id && build_id != NULL)
+ handle_build_id (dso, build_id, build_id_offset, build_id_size);
+
if (elf_update (dso->elf, ELF_C_WRITE) < 0)
{
fprintf (stderr, "Failed to write file: %s\n", elf_errmsg (elf_errno()));
@@ .
Received on Tue Aug 28 18:10:19 2007