Igor Gnatenko 082d5d
From 46b763e54de34d0dd28d82e3a87b59c6a94a4c07 Mon Sep 17 00:00:00 2001
Panu Matilainen 5b4d98
From: Mark Wielaard <mjw@redhat.com>
Panu Matilainen 5b4d98
Date: Tue, 14 Jun 2016 17:07:12 +0200
Igor Gnatenko 3992a6
Subject: [PATCH 04/54] Add build-id links to rpm for all ELF files.
Panu Matilainen 5b4d98
Panu Matilainen 5b4d98
This patch moves the main ELF file build-id symlinks from the
Panu Matilainen 5b4d98
debuginfo package into the main package. And uses different
Panu Matilainen 5b4d98
base directories for the main ELF file build-id symlink.
Panu Matilainen 5b4d98
For the main build-id use /usr/lib/.build-id and for the debug
Panu Matilainen 5b4d98
build-id use /usr/lib/debug/.build-id.
Panu Matilainen 5b4d98
Panu Matilainen 5b4d98
There are two reasons for doing this. The main package and the
Panu Matilainen 5b4d98
debuginfo package might get out of sync, or the debuginfo package
Panu Matilainen 5b4d98
might not be installed at all. In which case finding the main ELF
Panu Matilainen 5b4d98
file through the build-id symlink becomes impossible. Secondly by
Panu Matilainen 5b4d98
moving the main ELF build-id symlink in its own directory the
Panu Matilainen 5b4d98
/usr/lib/debug directory gets populated with only debuginfo files
Panu Matilainen 5b4d98
which is convenient if the user might want to have that directory
Panu Matilainen 5b4d98
populated through a network mountpoint.
Panu Matilainen 5b4d98
Panu Matilainen 5b4d98
To support the new logic the symlink code has been moved from
Panu Matilainen 5b4d98
find-debuginfo.sh to build/files.c.
Panu Matilainen 5b4d98
Panu Matilainen 5b4d98
This also includes support for a new config %_build_id_links that
Panu Matilainen 5b4d98
defaults to compat. The other settings are none, alldebug (the old
Panu Matilainen 5b4d98
style) and separate. compat is like separate, but adds a compatibility
Panu Matilainen 5b4d98
link under /usr/lib/debug/.build-id for the main build-id symlink.
Panu Matilainen 5b4d98
Panu Matilainen 5b4d98
There are several new testcases added to test the various settings
Panu Matilainen 5b4d98
using the new keyword "buildid".
Panu Matilainen 5b4d98
Panu Matilainen 5b4d98
Signed-off-by: Mark Wielaard <mjw@redhat.com>
Igor Gnatenko 082d5d
(cherry picked from commit bbfe1f86b2e4b5c0bd499d9f3dd9de9c9c20fff2)
Panu Matilainen 5b4d98
---
Panu Matilainen 5b4d98
 build/Makefile.am              |   4 +
Panu Matilainen 5b4d98
 build/files.c                  | 375 ++++++++++++++++++++
Panu Matilainen 5b4d98
 configure.ac                   |  15 +
Panu Matilainen 5b4d98
 macros.in                      |  28 ++
Panu Matilainen 5b4d98
 scripts/find-debuginfo.sh      |  60 ----
Panu Matilainen 5b4d98
 tests/Makefile.am              |   1 +
Panu Matilainen 5b4d98
 tests/data/SPECS/hello2cp.spec |  64 ++++
Panu Matilainen 5b4d98
 tests/data/SPECS/hello2ln.spec |  63 ++++
Panu Matilainen 5b4d98
 tests/rpmbuildid.at            | 761 +++++++++++++++++++++++++++++++++++++++++
Panu Matilainen 5b4d98
 tests/rpmtests.at              |   1 +
Panu Matilainen 5b4d98
 10 files changed, 1312 insertions(+), 60 deletions(-)
Panu Matilainen 5b4d98
 create mode 100644 tests/data/SPECS/hello2cp.spec
Panu Matilainen 5b4d98
 create mode 100644 tests/data/SPECS/hello2ln.spec
Panu Matilainen 5b4d98
 create mode 100644 tests/rpmbuildid.at
Panu Matilainen 5b4d98
Panu Matilainen 5b4d98
diff --git a/build/Makefile.am b/build/Makefile.am
Igor Gnatenko 082d5d
index dbda716ac..71edbd1c4 100644
Panu Matilainen 5b4d98
--- a/build/Makefile.am
Panu Matilainen 5b4d98
+++ b/build/Makefile.am
Panu Matilainen 5b4d98
@@ -26,3 +26,7 @@ librpmbuild_la_LIBADD = \
Panu Matilainen 5b4d98
 	@LTLIBICONV@ \
Panu Matilainen 5b4d98
 	@WITH_POPT_LIB@ \
Panu Matilainen 5b4d98
 	@WITH_MAGIC_LIB@
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+if LIBDW
Panu Matilainen 5b4d98
+librpmbuild_la_LIBADD += @WITH_LIBELF_LIB@ @WITH_LIBDW_LIB@
Panu Matilainen 5b4d98
+endif
Panu Matilainen 5b4d98
diff --git a/build/files.c b/build/files.c
Igor Gnatenko 082d5d
index b76ce048f..b010483e4 100644
Panu Matilainen 5b4d98
--- a/build/files.c
Panu Matilainen 5b4d98
+++ b/build/files.c
Panu Matilainen 5b4d98
@@ -14,6 +14,11 @@
Panu Matilainen 5b4d98
 #include <sys/capability.h>
Panu Matilainen 5b4d98
 #endif
Panu Matilainen 5b4d98
 
Panu Matilainen 5b4d98
+#if HAVE_LIBDW
Panu Matilainen 5b4d98
+#include <libelf.h>
Panu Matilainen 5b4d98
+#include <elfutils/libdwelf.h>
Panu Matilainen 5b4d98
+#endif
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
 #include <rpm/rpmpgp.h>
Panu Matilainen 5b4d98
 #include <rpm/argv.h>
Panu Matilainen 5b4d98
 #include <rpm/rpmfc.h>
Panu Matilainen 5b4d98
@@ -1551,6 +1556,368 @@ exit:
Panu Matilainen 5b4d98
     return rc;
Panu Matilainen 5b4d98
 }
Panu Matilainen 5b4d98
 
Panu Matilainen 5b4d98
+#if HAVE_LIBDW
Panu Matilainen 5b4d98
+/* How build id links are generated.  See macros.in for description.  */
Panu Matilainen 5b4d98
+#define BUILD_IDS_NONE     0
Panu Matilainen 5b4d98
+#define BUILD_IDS_ALLDEBUG 1
Panu Matilainen 5b4d98
+#define BUILD_IDS_SEPARATE 2
Panu Matilainen 5b4d98
+#define BUILD_IDS_COMPAT   3
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+static int addNewIDSymlink(FileList fl,
Panu Matilainen 5b4d98
+			   char *targetpath, char *idlinkpath,
Panu Matilainen 5b4d98
+			   int isDbg, int isCompat)
Panu Matilainen 5b4d98
+{
Panu Matilainen 5b4d98
+    const char *linkerr = _("failed symlink");
Panu Matilainen 5b4d98
+    int rc = 0;
Panu Matilainen 5b4d98
+    int nr = 0;
Panu Matilainen 5b4d98
+    char *origpath, *linkpath;
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+    if (isDbg)
Panu Matilainen 5b4d98
+	rasprintf(&linkpath, "%s.debug", idlinkpath);
Panu Matilainen 5b4d98
+    else
Panu Matilainen 5b4d98
+	linkpath = idlinkpath;
Panu Matilainen 5b4d98
+    origpath = linkpath;
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+    while (faccessat(AT_FDCWD, linkpath, F_OK, AT_SYMLINK_NOFOLLOW) == 0) {
Panu Matilainen 5b4d98
+	if (nr > 0)
Panu Matilainen 5b4d98
+	    free(linkpath);
Panu Matilainen 5b4d98
+	nr++;
Panu Matilainen 5b4d98
+	rasprintf(&linkpath, "%s.%d%s", idlinkpath, nr,
Panu Matilainen 5b4d98
+		  isDbg ? ".debug" : "");
Panu Matilainen 5b4d98
+    }
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+    char *symtarget = targetpath;
Panu Matilainen 5b4d98
+    if (nr > 0 && isCompat)
Panu Matilainen 5b4d98
+	rasprintf (&symtarget, "%s.%d", targetpath, nr);
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+    if (symlink(symtarget, linkpath) < 0) {
Panu Matilainen 5b4d98
+	rc = 1;
Panu Matilainen 5b4d98
+	rpmlog(RPMLOG_ERR, "%s: %s -> %s: %m\n",
Panu Matilainen 5b4d98
+	       linkerr, linkpath, symtarget);
Panu Matilainen 5b4d98
+    } else {
Panu Matilainen 5b4d98
+	fl->cur.isDir = 0;
Panu Matilainen 5b4d98
+	rc = addFile(fl, linkpath, NULL);
Panu Matilainen 5b4d98
+    }
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+    /* Don't warn (again) if this is a compat id-link, we retarget it. */
Panu Matilainen 5b4d98
+    if (nr > 0 && !isCompat) {
Panu Matilainen 5b4d98
+	/* Lets see why there are multiple build-ids. If the original
Panu Matilainen 5b4d98
+	   targets are hard linked, then it is OK, otherwise warn
Panu Matilainen 5b4d98
+	   something fishy is going on. Would be nice to call
Panu Matilainen 5b4d98
+	   something like eu-elfcmp to see if they are really the same
Panu Matilainen 5b4d98
+	   ELF file or not. */
Panu Matilainen 5b4d98
+	struct stat st1, st2;
Panu Matilainen 5b4d98
+	if (stat (origpath, &st1) != 0) {
Panu Matilainen 5b4d98
+	    rpmlog(RPMLOG_WARNING, _("Duplicate build-id, stat %s: %m\n"),
Panu Matilainen 5b4d98
+		   origpath);
Panu Matilainen 5b4d98
+	} else if (stat (linkpath, &st2) != 0) {
Panu Matilainen 5b4d98
+	    rpmlog(RPMLOG_WARNING, _("Duplicate build-id, stat %s: %m\n"),
Panu Matilainen 5b4d98
+		   linkpath);
Panu Matilainen 5b4d98
+	} else if (!(S_ISREG(st1.st_mode) && S_ISREG(st2.st_mode)
Panu Matilainen 5b4d98
+		  && st1.st_nlink > 1 && st2.st_nlink == st1.st_nlink
Panu Matilainen 5b4d98
+		  && st1.st_ino == st2.st_ino && st1.st_dev == st2.st_dev)) {
Panu Matilainen 5b4d98
+	    char *rpath1 = realpath(origpath, NULL);
Panu Matilainen 5b4d98
+	    char *rpath2 = realpath(linkpath, NULL);
Panu Matilainen 5b4d98
+	    rpmlog(RPMLOG_WARNING, _("Duplicate build-ids %s and %s\n"),
Panu Matilainen 5b4d98
+		   rpath1, rpath2);
Panu Matilainen 5b4d98
+	    free(rpath1);
Panu Matilainen 5b4d98
+	    free(rpath2);
Panu Matilainen 5b4d98
+	}
Panu Matilainen 5b4d98
+    }
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+    if (isDbg)
Panu Matilainen 5b4d98
+	free(origpath);
Panu Matilainen 5b4d98
+    if (nr > 0)
Panu Matilainen 5b4d98
+	free(linkpath);
Panu Matilainen 5b4d98
+    if (nr > 0 && isCompat)
Panu Matilainen 5b4d98
+	free(symtarget);
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+    return rc;
Panu Matilainen 5b4d98
+}
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+static int generateBuildIDs(FileList fl)
Panu Matilainen 5b4d98
+{
Panu Matilainen 5b4d98
+    int rc = 0;
Panu Matilainen 5b4d98
+    int i;
Panu Matilainen 5b4d98
+    FileListRec flp;
Panu Matilainen 5b4d98
+    char **ids = NULL;
Panu Matilainen 5b4d98
+    char **paths = NULL;
Panu Matilainen 5b4d98
+    size_t nr_ids, allocated;
Panu Matilainen 5b4d98
+    nr_ids = allocated = 0;
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+    /* How are we supposed to create the build-id links?  */
Panu Matilainen 5b4d98
+    char *build_id_links_macro = rpmExpand("%{?_build_id_links}", NULL);
Panu Matilainen 5b4d98
+    int build_id_links;
Panu Matilainen 5b4d98
+    if (build_id_links_macro == NULL) {
Panu Matilainen 5b4d98
+	rpmlog(RPMLOG_WARNING,
Panu Matilainen 5b4d98
+	       _("_build_id_links macro not set, assuming 'compat'\n"));
Panu Matilainen 5b4d98
+	build_id_links = BUILD_IDS_COMPAT;
Panu Matilainen 5b4d98
+    } else if (strcmp(build_id_links_macro, "none") == 0) {
Panu Matilainen 5b4d98
+	build_id_links = BUILD_IDS_NONE;
Panu Matilainen 5b4d98
+    } else if (strcmp(build_id_links_macro, "alldebug") == 0) {
Panu Matilainen 5b4d98
+	build_id_links = BUILD_IDS_ALLDEBUG;
Panu Matilainen 5b4d98
+    } else if (strcmp(build_id_links_macro, "separate") == 0) {
Panu Matilainen 5b4d98
+	build_id_links = BUILD_IDS_SEPARATE;
Panu Matilainen 5b4d98
+    } else if (strcmp(build_id_links_macro, "compat") == 0) {
Panu Matilainen 5b4d98
+	build_id_links = BUILD_IDS_COMPAT;
Panu Matilainen 5b4d98
+    } else {
Panu Matilainen 5b4d98
+	rc = 1;
Panu Matilainen 5b4d98
+	rpmlog(RPMLOG_ERR,
Panu Matilainen 5b4d98
+	       _("_build_id_links macro set to unknown value '%s'\n"),
Panu Matilainen 5b4d98
+	       build_id_links_macro);
Panu Matilainen 5b4d98
+	build_id_links = BUILD_IDS_NONE;
Panu Matilainen 5b4d98
+    }
Panu Matilainen 5b4d98
+    free(build_id_links_macro);
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+    if (build_id_links == BUILD_IDS_NONE || rc != 0)
Panu Matilainen 5b4d98
+	return rc;
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+    int terminate = rpmExpandNumeric("%{?_missing_build_ids_terminate_build}");
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+    /* Collect and check all build-ids for ELF files in this package.  */
Panu Matilainen 5b4d98
+    int needMain = 0;
Panu Matilainen 5b4d98
+    int needDbg = 0;
Panu Matilainen 5b4d98
+    for (i = 0, flp = fl->files.recs; i < fl->files.used; i++, flp++) {
Panu Matilainen 5b4d98
+	int fd;
Panu Matilainen 5b4d98
+	fd = open (flp->diskPath, O_RDONLY);
Panu Matilainen 5b4d98
+	if (fd >= 0) {
Panu Matilainen 5b4d98
+	    struct stat sbuf;
Panu Matilainen 5b4d98
+	    if (fstat (fd, &sbuf) == 0 && S_ISREG (sbuf.st_mode)) {
Panu Matilainen 5b4d98
+		Elf *elf = elf_begin (fd, ELF_C_READ, NULL);
Panu Matilainen 5b4d98
+		if (elf != NULL && elf_kind(elf) == ELF_K_ELF) {
Panu Matilainen 5b4d98
+		    const void *build_id;
Panu Matilainen 5b4d98
+		    ssize_t len = dwelf_elf_gnu_build_id (elf, &build_id);
Panu Matilainen 5b4d98
+		    /* len == -1 means error. Zero means no
Panu Matilainen 5b4d98
+		       build-id. We want at least a length of 2 so we
Panu Matilainen 5b4d98
+		       have at least a xx/yy (hex) dir/file. But
Panu Matilainen 5b4d98
+		       reasonable build-ids are between 16 bytes (md5
Panu Matilainen 5b4d98
+		       is 128 bits) and 64 bytes (largest sha3 is 512
Panu Matilainen 5b4d98
+		       bits), common is 20 bytes (sha1 is 160 bits). */
Panu Matilainen 5b4d98
+		    if (len >= 16 && len <= 64) {
Panu Matilainen 5b4d98
+			/* We determine whether this is a main or
Panu Matilainen 5b4d98
+			   debug ELF based on path.  */
Panu Matilainen 5b4d98
+			#define DEBUGPATH "/usr/lib/debug/"
Panu Matilainen 5b4d98
+			int addid = 0;
Panu Matilainen 5b4d98
+			if (strncmp (flp->cpioPath,
Panu Matilainen 5b4d98
+				     DEBUGPATH, strlen (DEBUGPATH)) == 0) {
Panu Matilainen 5b4d98
+			    needDbg = 1;
Panu Matilainen 5b4d98
+			    addid = 1;
Panu Matilainen 5b4d98
+			}
Panu Matilainen 5b4d98
+			else if (build_id_links != BUILD_IDS_ALLDEBUG) {
Panu Matilainen 5b4d98
+			    needMain = 1;
Panu Matilainen 5b4d98
+			    addid = 1;
Panu Matilainen 5b4d98
+			}
Panu Matilainen 5b4d98
+			if (addid) {
Panu Matilainen 5b4d98
+			    const unsigned char *p = build_id;
Panu Matilainen 5b4d98
+			    const unsigned char *end = p + len;
Panu Matilainen 5b4d98
+			    char *id_str;
Panu Matilainen 5b4d98
+			    if (allocated <= nr_ids) {
Panu Matilainen 5b4d98
+				allocated += 16;
Panu Matilainen 5b4d98
+				paths = xrealloc (paths,
Panu Matilainen 5b4d98
+						  allocated * sizeof(char *));
Panu Matilainen 5b4d98
+				ids = xrealloc (ids,
Panu Matilainen 5b4d98
+						allocated * sizeof(char *));
Panu Matilainen 5b4d98
+			    }
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+			    paths[nr_ids] = xstrdup(flp->cpioPath);
Panu Matilainen 5b4d98
+			    id_str = ids[nr_ids] = xmalloc(2 * len + 1);
Panu Matilainen 5b4d98
+			    while (p < end)
Panu Matilainen 5b4d98
+				id_str += sprintf(id_str, "%02x",
Panu Matilainen 5b4d98
+						  (unsigned)*p++);
Panu Matilainen 5b4d98
+			    *id_str = '\0';
Panu Matilainen 5b4d98
+			    nr_ids++;
Panu Matilainen 5b4d98
+			}
Panu Matilainen 5b4d98
+		    } else {
Panu Matilainen 5b4d98
+			if (len < 0) {
Panu Matilainen 5b4d98
+			    rpmlog(terminate ? RPMLOG_ERR : RPMLOG_WARNING,
Panu Matilainen 5b4d98
+				   _("error reading build-id in %s: %s\n"),
Panu Matilainen 5b4d98
+				   flp->diskPath, elf_errmsg (-1));
Panu Matilainen 5b4d98
+			} else if (len == 0) {
Panu Matilainen 5b4d98
+			    rpmlog(terminate ? RPMLOG_ERR : RPMLOG_WARNING,
Panu Matilainen 5b4d98
+				   _("Missing build-id in %s\n"),
Panu Matilainen 5b4d98
+				   flp->diskPath);
Panu Matilainen 5b4d98
+			} else {
Panu Matilainen 5b4d98
+			    rpmlog(terminate ? RPMLOG_ERR : RPMLOG_WARNING,
Panu Matilainen 5b4d98
+				   (len < 16
Panu Matilainen 5b4d98
+				    ? _("build-id found in %s too small\n")
Panu Matilainen 5b4d98
+				    : _("build-id found in %s too large\n")),
Panu Matilainen 5b4d98
+				   flp->diskPath);
Panu Matilainen 5b4d98
+			}
Panu Matilainen 5b4d98
+			if (terminate)
Panu Matilainen 5b4d98
+			    rc = 1;
Panu Matilainen 5b4d98
+		    }
Panu Matilainen 5b4d98
+		    elf_end (elf);
Panu Matilainen 5b4d98
+		}
Panu Matilainen 5b4d98
+	    }
Panu Matilainen 5b4d98
+	    close (fd);
Panu Matilainen 5b4d98
+	}
Panu Matilainen 5b4d98
+    }
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+    /* Process and clean up all build-ids.  */
Panu Matilainen 5b4d98
+    if (nr_ids > 0) {
Panu Matilainen 5b4d98
+	const char *errdir = _("failed to create directory");
Panu Matilainen 5b4d98
+	char *mainiddir = NULL;
Panu Matilainen 5b4d98
+	char *debugiddir = NULL;
Panu Matilainen 5b4d98
+	if (rc == 0) {
Panu Matilainen 5b4d98
+	    /* Add .build-id directories to hold the subdirs/symlinks.  */
Panu Matilainen 5b4d98
+            #define BUILD_ID_DIR "/usr/lib/.build-id"
Panu Matilainen 5b4d98
+            #define DEBUG_ID_DIR "/usr/lib/debug/.build-id"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+	    mainiddir = rpmGetPath(fl->buildRoot, BUILD_ID_DIR, NULL);
Panu Matilainen 5b4d98
+	    debugiddir = rpmGetPath(fl->buildRoot, DEBUG_ID_DIR, NULL);
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+	    /* Supported, but questionable.  */
Panu Matilainen 5b4d98
+	    if (needMain && needDbg)
Panu Matilainen 5b4d98
+		rpmlog(RPMLOG_WARNING,
Panu Matilainen 5b4d98
+		       _("Mixing main ELF and debug files in package"));
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+	    if (needMain) {
Panu Matilainen 5b4d98
+		if ((rc = rpmioMkpath(mainiddir, 0755, -1, -1)) != 0) {
Panu Matilainen 5b4d98
+		    rpmlog(RPMLOG_ERR, "%s %s: %m\n", errdir, mainiddir);
Panu Matilainen 5b4d98
+		} else {
Panu Matilainen 5b4d98
+		    fl->cur.isDir = 1;
Panu Matilainen 5b4d98
+		    rc = addFile(fl, mainiddir, NULL);
Panu Matilainen 5b4d98
+		}
Panu Matilainen 5b4d98
+	    }
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+	    if (rc == 0 && needDbg) {
Panu Matilainen 5b4d98
+		if ((rc = rpmioMkpath(debugiddir, 0755, -1, -1)) != 0) {
Panu Matilainen 5b4d98
+		    rpmlog(RPMLOG_ERR, "%s %s: %m\n", errdir, debugiddir);
Panu Matilainen 5b4d98
+		} else {
Panu Matilainen 5b4d98
+		    fl->cur.isDir = 1;
Panu Matilainen 5b4d98
+		    rc = addFile(fl, debugiddir, NULL);
Panu Matilainen 5b4d98
+		}
Panu Matilainen 5b4d98
+	    }
Panu Matilainen 5b4d98
+	}
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+	/* Now add a subdir and symlink for each buildid found.  */
Panu Matilainen 5b4d98
+	for (i = 0; i < nr_ids; i++) {
Panu Matilainen 5b4d98
+	    /* Don't add anything more when an error occured. But do
Panu Matilainen 5b4d98
+	       cleanup.  */
Panu Matilainen 5b4d98
+	    if (rc == 0) {
Panu Matilainen 5b4d98
+		int isDbg = strncmp (paths[i], DEBUGPATH,
Panu Matilainen 5b4d98
+				     strlen (DEBUGPATH)) == 0;
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+		char *buildidsubdir;
Panu Matilainen 5b4d98
+		char subdir[4];
Panu Matilainen 5b4d98
+		subdir[0] = '/';
Panu Matilainen 5b4d98
+		subdir[1] = ids[i][0];
Panu Matilainen 5b4d98
+		subdir[2] = ids[i][1];
Panu Matilainen 5b4d98
+		subdir[3] = '\0';
Panu Matilainen 5b4d98
+		if (isDbg)
Panu Matilainen 5b4d98
+		    buildidsubdir = rpmGetPath(debugiddir, subdir, NULL);
Panu Matilainen 5b4d98
+		else
Panu Matilainen 5b4d98
+		    buildidsubdir = rpmGetPath(mainiddir, subdir, NULL);
Panu Matilainen 5b4d98
+		/* We only need to create and add the subdir once. */
Panu Matilainen 5b4d98
+		int addsubdir = access (buildidsubdir, F_OK) == -1;
Panu Matilainen 5b4d98
+		if (addsubdir
Panu Matilainen 5b4d98
+		    && (rc = rpmioMkpath(buildidsubdir, 0755, -1, -1)) != 0) {
Panu Matilainen 5b4d98
+		    rpmlog(RPMLOG_ERR, "%s %s: %m\n", errdir, buildidsubdir);
Panu Matilainen 5b4d98
+		} else {
Panu Matilainen 5b4d98
+		    fl->cur.isDir = 1;
Panu Matilainen 5b4d98
+		    if (!addsubdir
Panu Matilainen 5b4d98
+			|| (rc = addFile(fl, buildidsubdir, NULL)) == 0) {
Panu Matilainen 5b4d98
+			char *linkpattern, *targetpattern;
Panu Matilainen 5b4d98
+			char *linkpath, *targetpath;
Panu Matilainen 5b4d98
+			if (isDbg) {
Panu Matilainen 5b4d98
+			    linkpattern = "%s/%s";
Panu Matilainen 5b4d98
+			    targetpattern = "../../../../..%s";
Panu Matilainen 5b4d98
+			} else {
Panu Matilainen 5b4d98
+			    linkpattern = "%s/%s";
Panu Matilainen 5b4d98
+			    targetpattern = "../../../..%s";
Panu Matilainen 5b4d98
+			}
Panu Matilainen 5b4d98
+			rasprintf(&linkpath, linkpattern,
Panu Matilainen 5b4d98
+				  buildidsubdir, &ids[i][2]);
Panu Matilainen 5b4d98
+			rasprintf(&targetpath, targetpattern, paths[i]);
Panu Matilainen 5b4d98
+			rc = addNewIDSymlink(fl, targetpath, linkpath,
Panu Matilainen 5b4d98
+					     isDbg, 0);
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+			/* We might want to have a link from the debug
Panu Matilainen 5b4d98
+			   build_ids dir to the main one. We create it
Panu Matilainen 5b4d98
+			   when we are creating compat links or doing
Panu Matilainen 5b4d98
+			   an old style alldebug build-ids package. In
Panu Matilainen 5b4d98
+			   the first case things are simple since we
Panu Matilainen 5b4d98
+			   just link to the main build-id symlink. The
Panu Matilainen 5b4d98
+			   second case is a bit tricky, since we
Panu Matilainen 5b4d98
+			   cannot be 100% sure the file names in the
Panu Matilainen 5b4d98
+			   main and debug package match. Currently
Panu Matilainen 5b4d98
+			   they do, but when creating parallel
Panu Matilainen 5b4d98
+			   installable debuginfo packages they might
Panu Matilainen 5b4d98
+			   not (in that case we might have to also
Panu Matilainen 5b4d98
+			   strip the nvr from the debug name).
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+			   In general either method is discouraged
Panu Matilainen 5b4d98
+                           since it might create dangling symlinks if
Panu Matilainen 5b4d98
+                           the package versions get out of sync.  */
Panu Matilainen 5b4d98
+			if (rc == 0 && isDbg
Panu Matilainen 5b4d98
+			    && build_id_links == BUILD_IDS_COMPAT) {
Panu Matilainen 5b4d98
+			    /* buildidsubdir already points to the
Panu Matilainen 5b4d98
+			       debug buildid. We just need to setup
Panu Matilainen 5b4d98
+			       the symlink to the main one.  */
Panu Matilainen 5b4d98
+			    free(linkpath);
Panu Matilainen 5b4d98
+			    free(targetpath);
Panu Matilainen 5b4d98
+			    rasprintf(&linkpath, "%s/%s",
Panu Matilainen 5b4d98
+				      buildidsubdir, &ids[i][2]);
Panu Matilainen 5b4d98
+			    rasprintf(&targetpath,
Panu Matilainen 5b4d98
+				      "../../../.build-id%s/%s",
Panu Matilainen 5b4d98
+				      subdir, &ids[i][2]);
Panu Matilainen 5b4d98
+			    rc = addNewIDSymlink(fl, targetpath, linkpath,
Panu Matilainen 5b4d98
+						 0, 1);
Panu Matilainen 5b4d98
+			}
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+			if (rc == 0 && isDbg
Panu Matilainen 5b4d98
+			    && build_id_links == BUILD_IDS_ALLDEBUG) {
Panu Matilainen 5b4d98
+			    /* buildidsubdir already points to the
Panu Matilainen 5b4d98
+			       debug buildid. We do have to figure out
Panu Matilainen 5b4d98
+			       the main ELF file though (which is most
Panu Matilainen 5b4d98
+			       likely not in this package). Guess we
Panu Matilainen 5b4d98
+			       can find it by stripping the
Panu Matilainen 5b4d98
+			       /usr/lib/debug path and .debug
Panu Matilainen 5b4d98
+			       prefix. Which might not really be
Panu Matilainen 5b4d98
+			       correct if there was a more involved
Panu Matilainen 5b4d98
+			       transformation (for example for
Panu Matilainen 5b4d98
+			       parallel installable debuginfo
Panu Matilainen 5b4d98
+			       packages), but then we shouldn't be
Panu Matilainen 5b4d98
+			       using ALLDEBUG in the first place.
Panu Matilainen 5b4d98
+			       Also ignore things like .dwz multifiles
Panu Matilainen 5b4d98
+			       which don't end in ".debug". */
Panu Matilainen 5b4d98
+			    int pathlen = strlen(paths[i]);
Panu Matilainen 5b4d98
+			    int debuglen = strlen(".debug");
Panu Matilainen 5b4d98
+			    int prefixlen = strlen("/usr/lib/debug");
Panu Matilainen 5b4d98
+			    if (pathlen > prefixlen
Panu Matilainen 5b4d98
+				&& strcmp (paths[i] + pathlen - debuglen,
Panu Matilainen 5b4d98
+					   ".debug") == 0) {
Panu Matilainen 5b4d98
+				free(linkpath);
Panu Matilainen 5b4d98
+				free(targetpath);
Panu Matilainen 5b4d98
+				char *targetstr = xstrdup (paths[i]
Panu Matilainen 5b4d98
+							   + prefixlen);
Panu Matilainen 5b4d98
+				int targetlen = pathlen - prefixlen;
Panu Matilainen 5b4d98
+				targetstr[targetlen - debuglen] = '\0';
Panu Matilainen 5b4d98
+				rasprintf(&linkpath, "%s/%s",
Panu Matilainen 5b4d98
+					  buildidsubdir, &ids[i][2]);
Panu Matilainen 5b4d98
+				rasprintf(&targetpath, "../../../../..%s",
Panu Matilainen 5b4d98
+					  targetstr);
Panu Matilainen 5b4d98
+				rc = addNewIDSymlink(fl, targetpath,
Panu Matilainen 5b4d98
+						     linkpath, 0, 0);
Panu Matilainen 5b4d98
+				free(targetstr);
Panu Matilainen 5b4d98
+			    }
Panu Matilainen 5b4d98
+			}
Panu Matilainen 5b4d98
+			free(linkpath);
Panu Matilainen 5b4d98
+			free(targetpath);
Panu Matilainen 5b4d98
+		    }
Panu Matilainen 5b4d98
+		}
Panu Matilainen 5b4d98
+		free(buildidsubdir);
Panu Matilainen 5b4d98
+	    }
Panu Matilainen 5b4d98
+	    free(paths[i]);
Panu Matilainen 5b4d98
+	    free(ids[i]);
Panu Matilainen 5b4d98
+	}
Panu Matilainen 5b4d98
+	free(paths);
Panu Matilainen 5b4d98
+	free(ids);
Panu Matilainen 5b4d98
+    }
Panu Matilainen 5b4d98
+    return rc;
Panu Matilainen 5b4d98
+}
Panu Matilainen 5b4d98
+#endif
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
 /**
Panu Matilainen 5b4d98
  * Add a file to a binary package.
Panu Matilainen 5b4d98
  * @param pkg
Panu Matilainen 5b4d98
@@ -1963,6 +2330,11 @@ static rpmRC processPackageFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags,
Panu Matilainen 5b4d98
     if (fl.processingFailed)
Panu Matilainen 5b4d98
 	goto exit;
Panu Matilainen 5b4d98
 
Panu Matilainen 5b4d98
+#if HAVE_LIBDW
Panu Matilainen 5b4d98
+    if (generateBuildIDs (&fl) != 0)
Panu Matilainen 5b4d98
+	goto exit;
Panu Matilainen 5b4d98
+#endif
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
     /* Verify that file attributes scope over hardlinks correctly. */
Panu Matilainen 5b4d98
     if (checkHardLinks(&fl.files))
Panu Matilainen 5b4d98
 	(void) rpmlibNeedsFeature(pkg, "PartialHardlinkSets", "4.0.4-1");
Panu Matilainen 5b4d98
@@ -2161,6 +2533,9 @@ rpmRC processBinaryFiles(rpmSpec spec, rpmBuildPkgFlags pkgFlags,
Panu Matilainen 5b4d98
     Package pkg;
Panu Matilainen 5b4d98
     rpmRC rc = RPMRC_OK;
Panu Matilainen 5b4d98
     
Panu Matilainen 5b4d98
+#if HAVE_LIBDW
Panu Matilainen 5b4d98
+    elf_version (EV_CURRENT);
Panu Matilainen 5b4d98
+#endif
Panu Matilainen 5b4d98
     check_fileList = newStringBuf();
Panu Matilainen 5b4d98
     genSourceRpmName(spec);
Panu Matilainen 5b4d98
     
Panu Matilainen 5b4d98
diff --git a/configure.ac b/configure.ac
Igor Gnatenko 082d5d
index 91fadbade..8890c3c32 100644
Panu Matilainen 5b4d98
--- a/configure.ac
Panu Matilainen 5b4d98
+++ b/configure.ac
Igor Gnatenko 082d5d
@@ -360,6 +360,21 @@ AC_SUBST(WITH_ARCHIVE_LIB)
Panu Matilainen 5b4d98
 AM_CONDITIONAL(WITH_ARCHIVE,[test "$with_archive" = yes])
Panu Matilainen 5b4d98
 
Panu Matilainen 5b4d98
 #=================
Panu Matilainen 5b4d98
+# Check for elfutils libdw library with dwelf_elf_gnu_build_id.
Panu Matilainen 5b4d98
+AS_IF([test "$WITH_LIBELF" = yes],[
Panu Matilainen 5b4d98
+  AC_CHECK_HEADERS([elfutils/libdwelf.h],[
Panu Matilainen 5b4d98
+    AC_CHECK_LIB(dw, dwelf_elf_gnu_build_id, [
Panu Matilainen 5b4d98
+      AC_DEFINE(HAVE_LIBDW, 1,
Panu Matilainen 5b4d98
+                [Define to 1 if you have elfutils libdw library])
Panu Matilainen 5b4d98
+      WITH_LIBDW_LIB="-ldw"
Panu Matilainen 5b4d98
+      WITH_LIBDW=yes
Panu Matilainen 5b4d98
+    ])
Panu Matilainen 5b4d98
+  ])
Panu Matilainen 5b4d98
+  AC_SUBST(WITH_LIBDW_LIB)
Panu Matilainen 5b4d98
+  AM_CONDITIONAL(LIBDW,[test "$WITH_LIBDW" = yes])
Panu Matilainen 5b4d98
+])
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+#=================
Panu Matilainen 5b4d98
 # Process --with/without-external-db
Panu Matilainen 5b4d98
 AC_ARG_WITH(external_db, [AS_HELP_STRING([--with-external-db],[build against an external Berkeley db])],
Panu Matilainen 5b4d98
 [case "$with_external_db" in
Panu Matilainen 5b4d98
diff --git a/macros.in b/macros.in
Igor Gnatenko 082d5d
index fd57f2eba..e43d62b0a 100644
Panu Matilainen 5b4d98
--- a/macros.in
Panu Matilainen 5b4d98
+++ b/macros.in
Panu Matilainen 5b4d98
@@ -449,6 +449,34 @@ package or when debugging this package.\
Panu Matilainen 5b4d98
 #%_include_minidebuginfo	1
Panu Matilainen 5b4d98
 
Panu Matilainen 5b4d98
 #
Panu Matilainen 5b4d98
+# Defines how and if build_id links are generated for ELF files.
Panu Matilainen 5b4d98
+# The following settings are supported:
Panu Matilainen 5b4d98
+#
Panu Matilainen 5b4d98
+# - none
Panu Matilainen 5b4d98
+#   No build_id links are generated.
Panu Matilainen 5b4d98
+#
Panu Matilainen 5b4d98
+# - alldebug
Panu Matilainen 5b4d98
+#   build_id links are generated only when the __debug_package global is
Panu Matilainen 5b4d98
+#   defined. This will generate build_id links in the -debuginfo package
Panu Matilainen 5b4d98
+#   for both the main file as /usr/lib/debug/.build-id/xx/yyy and for
Panu Matilainen 5b4d98
+#   the .debug file as /usr/lib/debug/.build-id/xx/yyy.debug.
Panu Matilainen 5b4d98
+#   This is the old style build_id links as generated by the original
Panu Matilainen 5b4d98
+#   find-debuginfo.sh script.
Panu Matilainen 5b4d98
+#
Panu Matilainen 5b4d98
+# - separate
Panu Matilainen 5b4d98
+#   build_id links are generate for all binary packages. If this is a
Panu Matilainen 5b4d98
+#   main package (the __debug_package global isn't set) then the
Panu Matilainen 5b4d98
+#   build_id link is generated as /usr/lib/.build-id/xx/yyy. If this is
Panu Matilainen 5b4d98
+#   a -debuginfo package (the __debug_package global is set) then the
Panu Matilainen 5b4d98
+#   build_id link is generated as /usr/lib/debug/.build-id/xx/yyy.
Panu Matilainen 5b4d98
+#
Panu Matilainen 5b4d98
+# - compat
Panu Matilainen 5b4d98
+#   Same as for "separate" but if the __debug_package global is set then
Panu Matilainen 5b4d98
+#   the -debuginfo package will have a compatibility link for the main
Panu Matilainen 5b4d98
+#   ELF /usr/lib/debug/.build-id/xx/yyy -> /usr/lib/.build-id/xx/yyy
Panu Matilainen 5b4d98
+%_build_id_links compat
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+#
Panu Matilainen 5b4d98
 # Use internal dependency generator rather than external helpers?
Panu Matilainen 5b4d98
 %_use_internal_dependency_generator	1
Panu Matilainen 5b4d98
 
Panu Matilainen 5b4d98
diff --git a/scripts/find-debuginfo.sh b/scripts/find-debuginfo.sh
Igor Gnatenko 082d5d
index 4293261c9..c9e2293de 100644
Panu Matilainen 5b4d98
--- a/scripts/find-debuginfo.sh
Panu Matilainen 5b4d98
+++ b/scripts/find-debuginfo.sh
Panu Matilainen 5b4d98
@@ -207,57 +207,6 @@ debug_link()
Panu Matilainen 5b4d98
   link_relative "$t" "$l" "$RPM_BUILD_ROOT"
Panu Matilainen 5b4d98
 }
Panu Matilainen 5b4d98
 
Panu Matilainen 5b4d98
-# Provide .2, .3, ... symlinks to all filename instances of this build-id.
Panu Matilainen 5b4d98
-make_id_dup_link()
Panu Matilainen 5b4d98
-{
Panu Matilainen 5b4d98
-  local id="$1" file="$2" idfile
Panu Matilainen 5b4d98
-
Panu Matilainen 5b4d98
-  local n=1
Panu Matilainen 5b4d98
-  while true; do
Panu Matilainen 5b4d98
-    idfile=".build-id/${id:0:2}/${id:2}.$n"
Panu Matilainen 5b4d98
-    [ $# -eq 3 ] && idfile="${idfile}$3"
Panu Matilainen 5b4d98
-    if [ ! -L "$RPM_BUILD_ROOT/usr/lib/debug/$idfile" ]; then
Panu Matilainen 5b4d98
-      break
Panu Matilainen 5b4d98
-    fi
Panu Matilainen 5b4d98
-    n=$[$n+1]
Panu Matilainen 5b4d98
-  done
Panu Matilainen 5b4d98
-  debug_link "$file" "/$idfile"
Panu Matilainen 5b4d98
-}
Panu Matilainen 5b4d98
-
Panu Matilainen 5b4d98
-# Make a build-id symlink for id $1 with suffix $3 to file $2.
Panu Matilainen 5b4d98
-make_id_link()
Panu Matilainen 5b4d98
-{
Panu Matilainen 5b4d98
-  local id="$1" file="$2"
Panu Matilainen 5b4d98
-  local idfile=".build-id/${id:0:2}/${id:2}"
Panu Matilainen 5b4d98
-  [ $# -eq 3 ] && idfile="${idfile}$3"
Panu Matilainen 5b4d98
-  local root_idfile="$RPM_BUILD_ROOT/usr/lib/debug/$idfile"
Panu Matilainen 5b4d98
-
Panu Matilainen 5b4d98
-  if [ ! -L "$root_idfile" ]; then
Panu Matilainen 5b4d98
-    debug_link "$file" "/$idfile"
Panu Matilainen 5b4d98
-    return
Panu Matilainen 5b4d98
-  fi
Panu Matilainen 5b4d98
-
Panu Matilainen 5b4d98
-  make_id_dup_link "$@"
Panu Matilainen 5b4d98
-
Panu Matilainen 5b4d98
-  [ $# -eq 3 ] && return 0
Panu Matilainen 5b4d98
-
Panu Matilainen 5b4d98
-  local other=$(readlink -m "$root_idfile")
Panu Matilainen 5b4d98
-  other=${other#$RPM_BUILD_ROOT}
Panu Matilainen 5b4d98
-  if cmp -s "$root_idfile" "$RPM_BUILD_ROOT$file" ||
Panu Matilainen 5b4d98
-     eu-elfcmp -q "$root_idfile" "$RPM_BUILD_ROOT$file" 2> /dev/null; then
Panu Matilainen 5b4d98
-    # Two copies.  Maybe one has to be setuid or something.
Panu Matilainen 5b4d98
-    echo >&2 "*** WARNING: identical binaries are copied, not linked:"
Panu Matilainen 5b4d98
-    echo >&2 "        $file"
Panu Matilainen 5b4d98
-    echo >&2 "   and  $other"
Panu Matilainen 5b4d98
-  else
Panu Matilainen 5b4d98
-    # This is pathological, break the build.
Panu Matilainen 5b4d98
-    echo >&2 "*** ERROR: same build ID in nonidentical files!"
Panu Matilainen 5b4d98
-    echo >&2 "        $file"
Panu Matilainen 5b4d98
-    echo >&2 "   and  $other"
Panu Matilainen 5b4d98
-    exit 2
Panu Matilainen 5b4d98
-  fi
Panu Matilainen 5b4d98
-}
Panu Matilainen 5b4d98
-
Panu Matilainen 5b4d98
 get_debugfn()
Panu Matilainen 5b4d98
 {
Panu Matilainen 5b4d98
   dn=$(dirname "${1#$RPM_BUILD_ROOT}")
Panu Matilainen 5b4d98
@@ -288,8 +237,6 @@ while read nlinks inum f; do
Panu Matilainen 5b4d98
     eval linked=\$linked_$inum
Panu Matilainen 5b4d98
     if [ -n "$linked" ]; then
Panu Matilainen 5b4d98
       eval id=\$linkedid_$inum
Panu Matilainen 5b4d98
-      make_id_dup_link "$id" "$dn/$(basename $f)"
Panu Matilainen 5b4d98
-      make_id_dup_link "$id" "/usr/lib/debug$dn/$bn" .debug
Panu Matilainen 5b4d98
       link=$debugfn
Panu Matilainen 5b4d98
       get_debugfn "$linked"
Panu Matilainen 5b4d98
       echo "hard linked $link to $debugfn"
Panu Matilainen 5b4d98
@@ -318,7 +265,6 @@ while read nlinks inum f; do
Panu Matilainen 5b4d98
   # just has its file names collected and adjusted.
Panu Matilainen 5b4d98
   case "$dn" in
Panu Matilainen 5b4d98
   /usr/lib/debug/*)
Panu Matilainen 5b4d98
-    [ -z "$id" ] || make_id_link "$id" "$dn/$(basename $f)"
Panu Matilainen 5b4d98
     continue ;;
Panu Matilainen 5b4d98
   esac
Panu Matilainen 5b4d98
 
Panu Matilainen 5b4d98
@@ -336,10 +282,6 @@ while read nlinks inum f; do
Panu Matilainen 5b4d98
 
Panu Matilainen 5b4d98
   echo "./${f#$RPM_BUILD_ROOT}" >> "$ELFBINSFILE"
Panu Matilainen 5b4d98
 
Panu Matilainen 5b4d98
-  if [ -n "$id" ]; then
Panu Matilainen 5b4d98
-    make_id_link "$id" "$dn/$(basename $f)"
Panu Matilainen 5b4d98
-    make_id_link "$id" "/usr/lib/debug$dn/$bn" .debug
Panu Matilainen 5b4d98
-  fi
Panu Matilainen 5b4d98
 done || exit
Panu Matilainen 5b4d98
 
Panu Matilainen 5b4d98
 # Invoke the DWARF Compressor utility.
Panu Matilainen 5b4d98
@@ -367,8 +309,6 @@ if $run_dwz && type dwz >/dev/null 2>&1 \
Panu Matilainen 5b4d98
     if [ -f "${RPM_BUILD_ROOT}/usr/lib/debug/.dwz/${dwz_multifile_name}" ]; then
Panu Matilainen 5b4d98
       id="`readelf -Wn "${RPM_BUILD_ROOT}/usr/lib/debug/.dwz/${dwz_multifile_name}" \
Panu Matilainen 5b4d98
 	     2>/dev/null | sed -n 's/^    Build ID: \([0-9a-f]\+\)/\1/p'`"
Panu Matilainen 5b4d98
-      [ -n "$id" ] \
Panu Matilainen 5b4d98
-	&& make_id_link "$id" "/usr/lib/debug/.dwz/${dwz_multifile_name}" .debug
Panu Matilainen 5b4d98
     fi
Panu Matilainen 5b4d98
 
Panu Matilainen 5b4d98
     # dwz invalidates .gnu_debuglink CRC32 in the main files.
Panu Matilainen 5b4d98
diff --git a/tests/Makefile.am b/tests/Makefile.am
Igor Gnatenko 082d5d
index 7a5cc6544..10555ce9a 100644
Panu Matilainen 5b4d98
--- a/tests/Makefile.am
Panu Matilainen 5b4d98
+++ b/tests/Makefile.am
Panu Matilainen 5b4d98
@@ -19,6 +19,7 @@ TESTSUITE_AT += rpmquery.at
Panu Matilainen 5b4d98
 TESTSUITE_AT += rpmverify.at
Panu Matilainen 5b4d98
 TESTSUITE_AT += rpmdb.at
Panu Matilainen 5b4d98
 TESTSUITE_AT += rpmbuild.at
Panu Matilainen 5b4d98
+TESTSUITE_AT += rpmbuildid.at
Panu Matilainen 5b4d98
 TESTSUITE_AT += rpmi.at
Panu Matilainen 5b4d98
 TESTSUITE_AT += rpmvercmp.at
Panu Matilainen 5b4d98
 TESTSUITE_AT += rpmdeps.at
Panu Matilainen 5b4d98
diff --git a/tests/data/SPECS/hello2cp.spec b/tests/data/SPECS/hello2cp.spec
Panu Matilainen 5b4d98
new file mode 100644
Igor Gnatenko 082d5d
index 000000000..33d8dc260
Panu Matilainen 5b4d98
--- /dev/null
Panu Matilainen 5b4d98
+++ b/tests/data/SPECS/hello2cp.spec
Panu Matilainen 5b4d98
@@ -0,0 +1,64 @@
Panu Matilainen 5b4d98
+Summary: hello2 -- double hello, world rpm
Panu Matilainen 5b4d98
+Name: hello2
Panu Matilainen 5b4d98
+Version: 1.0
Panu Matilainen 5b4d98
+Release: 1
Panu Matilainen 5b4d98
+Group: Utilities
Panu Matilainen 5b4d98
+License: GPL
Panu Matilainen 5b4d98
+Distribution: RPM test suite.
Panu Matilainen 5b4d98
+Vendor: Red Hat Software
Panu Matilainen 5b4d98
+Packager: Red Hat Software <bugs@redhat.com>
Panu Matilainen 5b4d98
+URL: http://www.redhat.com
Panu Matilainen 5b4d98
+Source0: hello-1.0.tar.gz
Panu Matilainen 5b4d98
+Patch0: hello-1.0-modernize.patch
Panu Matilainen 5b4d98
+Excludearch: lsi
Panu Matilainen 5b4d98
+Excludeos: cpm
Panu Matilainen 5b4d98
+Provides: hi
Panu Matilainen 5b4d98
+Conflicts: goodbye
Panu Matilainen 5b4d98
+Obsoletes: howdy
Panu Matilainen 5b4d98
+Prefix: /usr
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+%description
Panu Matilainen 5b4d98
+Simple rpm demonstration.
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+%prep
Panu Matilainen 5b4d98
+%setup -q -n hello-1.0
Panu Matilainen 5b4d98
+%patch0 -p1 -b .modernize
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+%build
Panu Matilainen 5b4d98
+make CFLAGS="-g -O1"
Panu Matilainen 5b4d98
+cp hello hello2
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+%install
Panu Matilainen 5b4d98
+rm -rf $RPM_BUILD_ROOT
Panu Matilainen 5b4d98
+mkdir -p $RPM_BUILD_ROOT/usr/local/bin
Panu Matilainen 5b4d98
+make DESTDIR=$RPM_BUILD_ROOT install
Panu Matilainen 5b4d98
+cp hello2 $RPM_BUILD_ROOT/usr/local/bin/
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+%clean
Panu Matilainen 5b4d98
+rm -rf $RPM_BUILD_ROOT
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+%pre
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+%post
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+%preun
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+%postun
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+%files
Panu Matilainen 5b4d98
+%defattr(-,root,root)
Panu Matilainen 5b4d98
+%doc	FAQ
Panu Matilainen 5b4d98
+#%readme README
Panu Matilainen 5b4d98
+#%license COPYING
Panu Matilainen 5b4d98
+%attr(0751,root,root)	/usr/local/bin/hello
Panu Matilainen 5b4d98
+%attr(0751,root,root)	/usr/local/bin/hello2
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+%changelog
Panu Matilainen 5b4d98
+* Mon Jun  6 2016 Mark Wielaard <mjw@redhat.com>
Panu Matilainen 5b4d98
+- Copy hello to hello2 for duplicate build-id testing.
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+* Wed May 18 2016 Mark Wielaard <mjw@redhat.com>
Panu Matilainen 5b4d98
+- Add hello2 for dwz testing support.
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+* Tue Oct 20 1998 Jeff Johnson <jbj@redhat.com>
Panu Matilainen 5b4d98
+- create.
Panu Matilainen 5b4d98
diff --git a/tests/data/SPECS/hello2ln.spec b/tests/data/SPECS/hello2ln.spec
Panu Matilainen 5b4d98
new file mode 100644
Igor Gnatenko 082d5d
index 000000000..2c40dcc32
Panu Matilainen 5b4d98
--- /dev/null
Panu Matilainen 5b4d98
+++ b/tests/data/SPECS/hello2ln.spec
Panu Matilainen 5b4d98
@@ -0,0 +1,63 @@
Panu Matilainen 5b4d98
+Summary: hello2 -- double hello, world rpm
Panu Matilainen 5b4d98
+Name: hello2
Panu Matilainen 5b4d98
+Version: 1.0
Panu Matilainen 5b4d98
+Release: 1
Panu Matilainen 5b4d98
+Group: Utilities
Panu Matilainen 5b4d98
+License: GPL
Panu Matilainen 5b4d98
+Distribution: RPM test suite.
Panu Matilainen 5b4d98
+Vendor: Red Hat Software
Panu Matilainen 5b4d98
+Packager: Red Hat Software <bugs@redhat.com>
Panu Matilainen 5b4d98
+URL: http://www.redhat.com
Panu Matilainen 5b4d98
+Source0: hello-1.0.tar.gz
Panu Matilainen 5b4d98
+Patch0: hello-1.0-modernize.patch
Panu Matilainen 5b4d98
+Excludearch: lsi
Panu Matilainen 5b4d98
+Excludeos: cpm
Panu Matilainen 5b4d98
+Provides: hi
Panu Matilainen 5b4d98
+Conflicts: goodbye
Panu Matilainen 5b4d98
+Obsoletes: howdy
Panu Matilainen 5b4d98
+Prefix: /usr
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+%description
Panu Matilainen 5b4d98
+Simple rpm demonstration.
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+%prep
Panu Matilainen 5b4d98
+%setup -q -n hello-1.0
Panu Matilainen 5b4d98
+%patch0 -p1 -b .modernize
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+%build
Panu Matilainen 5b4d98
+make CFLAGS="-g -O1"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+%install
Panu Matilainen 5b4d98
+rm -rf $RPM_BUILD_ROOT
Panu Matilainen 5b4d98
+mkdir -p $RPM_BUILD_ROOT/usr/local/bin
Panu Matilainen 5b4d98
+make DESTDIR=$RPM_BUILD_ROOT install
Panu Matilainen 5b4d98
+ln $RPM_BUILD_ROOT/usr/local/bin/hello $RPM_BUILD_ROOT/usr/local/bin/hello2
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+%clean
Panu Matilainen 5b4d98
+rm -rf $RPM_BUILD_ROOT
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+%pre
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+%post
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+%preun
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+%postun
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+%files
Panu Matilainen 5b4d98
+%defattr(-,root,root)
Panu Matilainen 5b4d98
+%doc	FAQ
Panu Matilainen 5b4d98
+#%readme README
Panu Matilainen 5b4d98
+#%license COPYING
Panu Matilainen 5b4d98
+%attr(0751,root,root)	/usr/local/bin/hello
Panu Matilainen 5b4d98
+%attr(0751,root,root)	/usr/local/bin/hello2
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+%changelog
Panu Matilainen 5b4d98
+* Mon Jun  6 2016 Mark Wielaard <mjw@redhat.com>
Panu Matilainen 5b4d98
+- Hard link hello to hello2 for duplicate build-id testing.
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+* Wed May 18 2016 Mark Wielaard <mjw@redhat.com>
Panu Matilainen 5b4d98
+- Add hello2 for dwz testing support.
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+* Tue Oct 20 1998 Jeff Johnson <jbj@redhat.com>
Panu Matilainen 5b4d98
+- create.
Panu Matilainen 5b4d98
diff --git a/tests/rpmbuildid.at b/tests/rpmbuildid.at
Panu Matilainen 5b4d98
new file mode 100644
Igor Gnatenko 082d5d
index 000000000..eddca969b
Panu Matilainen 5b4d98
--- /dev/null
Panu Matilainen 5b4d98
+++ b/tests/rpmbuildid.at
Panu Matilainen 5b4d98
@@ -0,0 +1,761 @@
Panu Matilainen 5b4d98
+# rpmbuildid.at: test rpmbuild buildid symlink support
Panu Matilainen 5b4d98
+#
Panu Matilainen 5b4d98
+# This file is part of RPM, the RPM Package Manager.
Panu Matilainen 5b4d98
+# Copyright (C) 2016 Mark J. Wielaard <mjw@redhat.com>
Panu Matilainen 5b4d98
+#
Panu Matilainen 5b4d98
+# This file is free software; you can redistribute it and/or modify
Panu Matilainen 5b4d98
+# it under the terms of the GNU General Public License as published by
Panu Matilainen 5b4d98
+# the Free Software Foundation; either version 2 of the License, or
Panu Matilainen 5b4d98
+# (at your option) any later version.
Panu Matilainen 5b4d98
+#
Panu Matilainen 5b4d98
+# RPM is distributed in the hope that it will be useful, but
Panu Matilainen 5b4d98
+# WITHOUT ANY WARRANTY; without even the implied warranty of
Panu Matilainen 5b4d98
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Panu Matilainen 5b4d98
+# GNU General Public License for more details.
Panu Matilainen 5b4d98
+#
Panu Matilainen 5b4d98
+# You should have received a copy of the GNU General Public License
Panu Matilainen 5b4d98
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+AT_BANNER([RPM buildid tests])
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# ------------------------------
Panu Matilainen 5b4d98
+# Check if rpmbuild "none" doesn't generates buildid symlinks for hello program
Panu Matilainen 5b4d98
+AT_SETUP([rpmbuild buildid none])
Panu Matilainen 5b4d98
+AT_KEYWORDS([build] [debuginfo] [buildid])
Panu Matilainen 5b4d98
+AT_CHECK([
Panu Matilainen 5b4d98
+rm -rf ${TOPDIR}
Panu Matilainen 5b4d98
+AS_MKDIR_P(${TOPDIR}/SOURCES)
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Setup sources
Panu Matilainen 5b4d98
+cp "${abs_srcdir}"/data/SOURCES/hello-1.0.tar.gz "${abs_srcdir}"/data/SOURCES/hello-1.0-modernize.patch ${TOPDIR}/SOURCES
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Build, contains one ELF which should have a buildid.
Panu Matilainen 5b4d98
+run rpmbuild \
Panu Matilainen 5b4d98
+  --macros=${abs_top_builddir}/macros:${abs_top_builddir}/tests/testing/usr/local/lib/rpm/platform/%{_target_cpu}-%{_target_os}/macros:${top_srcdir}/macros.debug \
Panu Matilainen 5b4d98
+  --rcfile=${abs_top_builddir}/rpmrc \
Panu Matilainen 5b4d98
+  --define="_build_id_links none" \
Panu Matilainen 5b4d98
+  --quiet -ba "${abs_srcdir}"/data/SPECS/hello.spec
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# There should be zero build-id files in both the main and debuginfo package
Panu Matilainen 5b4d98
+echo -n "hello build-id files: "
Panu Matilainen 5b4d98
+run rpm -ql -p "${TOPDIR}"/RPMS/*/hello-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | grep /.build-id/ | wc --lines
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+echo -n "hello debuginfo build-id files: "
Panu Matilainen 5b4d98
+run rpm -ql -p "${TOPDIR}"/RPMS/*/hello-debuginfo-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | grep /.build-id/ | wc --lines
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+],
Panu Matilainen 5b4d98
+[0],
Panu Matilainen 5b4d98
+[hello build-id files: 0
Panu Matilainen 5b4d98
+hello debuginfo build-id files: 0
Panu Matilainen 5b4d98
+],
Panu Matilainen 5b4d98
+[ignore])
Panu Matilainen 5b4d98
+AT_CLEANUP
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# ------------------------------
Panu Matilainen 5b4d98
+# Check if rpmbuild "alldebug" generates debuginfo buildid symlinks
Panu Matilainen 5b4d98
+AT_SETUP([rpmbuild buildid alldebug])
Panu Matilainen 5b4d98
+AT_KEYWORDS([build] [debuginfo] [buildid])
Panu Matilainen 5b4d98
+AT_CHECK([
Panu Matilainen 5b4d98
+rm -rf ${TOPDIR}
Panu Matilainen 5b4d98
+AS_MKDIR_P(${TOPDIR}/SOURCES)
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Setup sources
Panu Matilainen 5b4d98
+cp "${abs_srcdir}"/data/SOURCES/hello-1.0.tar.gz "${abs_srcdir}"/data/SOURCES/hello-1.0-modernize.patch ${TOPDIR}/SOURCES
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Build, contains one ELF which should have a buildid.
Panu Matilainen 5b4d98
+run rpmbuild \
Panu Matilainen 5b4d98
+  --macros=${abs_top_builddir}/macros:${abs_top_builddir}/tests/testing/usr/local/lib/rpm/platform/%{_target_cpu}-%{_target_os}/macros:${top_srcdir}/macros.debug \
Panu Matilainen 5b4d98
+  --rcfile=${abs_top_builddir}/rpmrc \
Panu Matilainen 5b4d98
+  --define="_build_id_links alldebug" \
Panu Matilainen 5b4d98
+  --quiet -ba "${abs_srcdir}"/data/SPECS/hello.spec
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# There should be zero build-id files in the main package
Panu Matilainen 5b4d98
+# Main and debug should be in the debuginfo package,
Panu Matilainen 5b4d98
+# plus the .build-id/xx subdir, 3 in total.
Panu Matilainen 5b4d98
+echo -n "hello build-id files: "
Panu Matilainen 5b4d98
+run rpm -ql -p "${TOPDIR}"/RPMS/*/hello-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | grep /.build-id/ | wc --lines
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+echo -n "hello debuginfo build-id files: "
Panu Matilainen 5b4d98
+run rpm -ql -p "${TOPDIR}"/RPMS/*/hello-debuginfo-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | grep /.build-id/ | wc --lines
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Extract the both packages to check the build-id files link to the
Panu Matilainen 5b4d98
+# main and .debug files.
Panu Matilainen 5b4d98
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | cpio -diu
Panu Matilainen 5b4d98
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello-debuginfo-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | cpio -diu
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Check there is a build-id symlink for the main file.
Panu Matilainen 5b4d98
+main_file=./usr/local/bin/hello
Panu Matilainen 5b4d98
+test -f "${main_file}" || echo "No main file ${main_file}"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Extract the build-id from the main file
Panu Matilainen 5b4d98
+id_main=$(file $main_file | sed 's/.*, BuildID[.*]=\(.*\),.*/\1/')
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+id_main_file="./usr/lib/debug/.build-id/${id_main:0:2}/${id_main:2}"
Panu Matilainen 5b4d98
+test -L "$id_main_file" || echo "No build-id file $id_main_file"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+canon_main_file=$(readlink -f ${main_file})
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test -f "$canon_main_file" \
Panu Matilainen 5b4d98
+  || echo "Cannot resolve main file ${main_file} -> ${canon_main_file}"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+canon_main_id_file=$(readlink -f ${id_main_file})
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test -f "$canon_main_id_file" \
Panu Matilainen 5b4d98
+  || echo "Cannot resolve main build-id file ${id_main_file} -> ${canon_main_id_file}"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test "$canon_main_file" = "$canon_main_id_file" \
Panu Matilainen 5b4d98
+  || echo "main and build-id file not linked"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# And check the same for the debug file.
Panu Matilainen 5b4d98
+debug_file=./usr/lib/debug/usr/local/bin/hello.debug
Panu Matilainen 5b4d98
+test -f "${debug_file}" || echo "No debug file ${debug_file}"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Extract the build-id from the .debug file
Panu Matilainen 5b4d98
+id_debug=$(file $debug_file | sed 's/.*, BuildID[.*]=\(.*\),.*/\1/')
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test ${id_main} = ${id_debug} || echo "unequal main and debug id"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+id_debug_file="./usr/lib/debug/.build-id/${id_debug:0:2}/${id_debug:2}.debug"
Panu Matilainen 5b4d98
+test -L "$id_debug_file" || echo "No build-id file $id_debug_file"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+canon_debug_file=$(readlink -f ${debug_file})
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test -f "$canon_debug_file" \
Panu Matilainen 5b4d98
+  || echo "Cannot resolve debug file ${debug_file} -> ${canon_debug_file}"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+canon_debug_id_file=$(readlink -f ${id_debug_file})
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test -f "$canon_debug_id_file" \
Panu Matilainen 5b4d98
+  || echo "Cannot resolve debug build-id file ${id_debug_file} -> ${canon_debug_id_file}"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test "$canon_debug_file" = "$canon_debug_id_file" \
Panu Matilainen 5b4d98
+  || echo "debug and build-id not linked"
Panu Matilainen 5b4d98
+],
Panu Matilainen 5b4d98
+[0],
Panu Matilainen 5b4d98
+[hello build-id files: 0
Panu Matilainen 5b4d98
+hello debuginfo build-id files: 3
Panu Matilainen 5b4d98
+],
Panu Matilainen 5b4d98
+[ignore])
Panu Matilainen 5b4d98
+AT_CLEANUP
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# ------------------------------
Panu Matilainen 5b4d98
+# Check if rpmbuild "separate" generates main and debuginfo buildid symlinks
Panu Matilainen 5b4d98
+AT_SETUP([rpmbuild buildid separate])
Panu Matilainen 5b4d98
+AT_KEYWORDS([build] [debuginfo] [buildid])
Panu Matilainen 5b4d98
+AT_CHECK([
Panu Matilainen 5b4d98
+rm -rf ${TOPDIR}
Panu Matilainen 5b4d98
+AS_MKDIR_P(${TOPDIR}/SOURCES)
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Setup sources
Panu Matilainen 5b4d98
+cp "${abs_srcdir}"/data/SOURCES/hello-1.0.tar.gz "${abs_srcdir}"/data/SOURCES/hello-1.0-modernize.patch ${TOPDIR}/SOURCES
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Build, contains one ELF which should have a buildid.
Panu Matilainen 5b4d98
+run rpmbuild \
Panu Matilainen 5b4d98
+  --macros=${abs_top_builddir}/macros:${abs_top_builddir}/tests/testing/usr/local/lib/rpm/platform/%{_target_cpu}-%{_target_os}/macros:${top_srcdir}/macros.debug \
Panu Matilainen 5b4d98
+  --rcfile=${abs_top_builddir}/rpmrc \
Panu Matilainen 5b4d98
+  --define="_build_id_links separate" \
Panu Matilainen 5b4d98
+  --quiet -ba "${abs_srcdir}"/data/SPECS/hello.spec
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# There should be one build-id files in the main and debuginfo package
Panu Matilainen 5b4d98
+# plus the .build-id/xx subdir, 2 in total.
Panu Matilainen 5b4d98
+echo -n "hello build-id files: "
Panu Matilainen 5b4d98
+run rpm -ql -p "${TOPDIR}"/RPMS/*/hello-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | grep /.build-id/ | wc --lines
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+echo -n "hello debuginfo build-id files: "
Panu Matilainen 5b4d98
+run rpm -ql -p "${TOPDIR}"/RPMS/*/hello-debuginfo-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | grep /.build-id/ | wc --lines
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Extract the both packages to check the build-id files link to the
Panu Matilainen 5b4d98
+# main and .debug files.
Panu Matilainen 5b4d98
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | cpio -diu
Panu Matilainen 5b4d98
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello-debuginfo-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | cpio -diu
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Check there is a build-id symlink for the main file.
Panu Matilainen 5b4d98
+main_file=./usr/local/bin/hello
Panu Matilainen 5b4d98
+test -f "${main_file}" || echo "No main file ${main_file}"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Extract the build-id from the main file
Panu Matilainen 5b4d98
+id_main=$(file $main_file | sed 's/.*, BuildID[.*]=\(.*\),.*/\1/')
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+id_main_file="./usr/lib/.build-id/${id_main:0:2}/${id_main:2}"
Panu Matilainen 5b4d98
+test -L "$id_main_file" || echo "No build-id file $id_main_file"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+canon_main_file=$(readlink -f ${main_file})
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test -f "$canon_main_file" \
Panu Matilainen 5b4d98
+  || echo "Cannot resolve main file ${main_file} -> ${canon_main_file}"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+canon_main_id_file=$(readlink -f ${id_main_file})
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test -f "$canon_main_id_file" \
Panu Matilainen 5b4d98
+  || echo "Cannot resolve main build-id file ${id_main_file} -> ${canon_main_id_file}"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test "$canon_main_file" = "$canon_main_id_file" \
Panu Matilainen 5b4d98
+  || echo "main and build-id file not linked"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# And check the same for the debug file.
Panu Matilainen 5b4d98
+debug_file=./usr/lib/debug/usr/local/bin/hello.debug
Panu Matilainen 5b4d98
+test -f "${debug_file}" || echo "No debug file ${debug_file}"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Extract the build-id from the .debug file
Panu Matilainen 5b4d98
+id_debug=$(file $debug_file | sed 's/.*, BuildID[.*]=\(.*\),.*/\1/')
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test ${id_main} = ${id_debug} || echo "unequal main and debug id"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+id_debug_file="./usr/lib/debug/.build-id/${id_debug:0:2}/${id_debug:2}.debug"
Panu Matilainen 5b4d98
+test -L "$id_debug_file" || echo "No build-id file $id_debug_file"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+canon_debug_file=$(readlink -f ${debug_file})
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test -f "$canon_debug_file" \
Panu Matilainen 5b4d98
+  || echo "Cannot resolve debug file ${debug_file} -> ${canon_debug_file}"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+canon_debug_id_file=$(readlink -f ${id_debug_file})
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test -f "$canon_debug_id_file" \
Panu Matilainen 5b4d98
+  || echo "Cannot resolve debug build-id file ${id_debug_file} -> ${canon_debug_id_file}"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test "$canon_debug_file" = "$canon_debug_id_file" \
Panu Matilainen 5b4d98
+  || echo "debug and build-id not linked"
Panu Matilainen 5b4d98
+],
Panu Matilainen 5b4d98
+[0],
Panu Matilainen 5b4d98
+[hello build-id files: 2
Panu Matilainen 5b4d98
+hello debuginfo build-id files: 2
Panu Matilainen 5b4d98
+],
Panu Matilainen 5b4d98
+[ignore])
Panu Matilainen 5b4d98
+AT_CLEANUP
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# ------------------------------
Panu Matilainen 5b4d98
+# Check if rpmbuild "compat" generates main and debuginfo buildid symlinks
Panu Matilainen 5b4d98
+AT_SETUP([rpmbuild buildid compat])
Panu Matilainen 5b4d98
+AT_KEYWORDS([build] [debuginfo] [buildid])
Panu Matilainen 5b4d98
+AT_CHECK([
Panu Matilainen 5b4d98
+rm -rf ${TOPDIR}
Panu Matilainen 5b4d98
+AS_MKDIR_P(${TOPDIR}/SOURCES)
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Setup sources
Panu Matilainen 5b4d98
+cp "${abs_srcdir}"/data/SOURCES/hello-1.0.tar.gz "${abs_srcdir}"/data/SOURCES/hello-1.0-modernize.patch ${TOPDIR}/SOURCES
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Build, contains one ELF which should have a buildid.
Panu Matilainen 5b4d98
+run rpmbuild \
Panu Matilainen 5b4d98
+  --macros=${abs_top_builddir}/macros:${abs_top_builddir}/tests/testing/usr/local/lib/rpm/platform/%{_target_cpu}-%{_target_os}/macros:${top_srcdir}/macros.debug \
Panu Matilainen 5b4d98
+  --rcfile=${abs_top_builddir}/rpmrc \
Panu Matilainen 5b4d98
+  --define="_build_id_links compat" \
Panu Matilainen 5b4d98
+  --quiet -ba "${abs_srcdir}"/data/SPECS/hello.spec
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# There should be one build-id files in the main and debuginfo package.
Panu Matilainen 5b4d98
+# the debuginfo package has one extra main build-id compat symlink
Panu Matilainen 5b4d98
+# plus the .build-id/xx subdir, 2 in total in main, 3 in total in debug
Panu Matilainen 5b4d98
+echo -n "hello build-id files: "
Panu Matilainen 5b4d98
+run rpm -ql -p "${TOPDIR}"/RPMS/*/hello-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | grep /.build-id/ | wc --lines
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+echo -n "hello debuginfo build-id files: "
Panu Matilainen 5b4d98
+run rpm -ql -p "${TOPDIR}"/RPMS/*/hello-debuginfo-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | grep /.build-id/ | wc --lines
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Extract the both packages to check the build-id files link to the
Panu Matilainen 5b4d98
+# main and .debug files.
Panu Matilainen 5b4d98
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | cpio -diu
Panu Matilainen 5b4d98
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello-debuginfo-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | cpio -diu
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Check there is a build-id symlink for the main file.
Panu Matilainen 5b4d98
+main_file=./usr/local/bin/hello
Panu Matilainen 5b4d98
+test -f "${main_file}" || echo "No main file ${main_file}"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Extract the build-id from the main file
Panu Matilainen 5b4d98
+id_main=$(file $main_file | sed 's/.*, BuildID[.*]=\(.*\),.*/\1/')
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+id_main_file="./usr/lib/.build-id/${id_main:0:2}/${id_main:2}"
Panu Matilainen 5b4d98
+test -L "$id_main_file" || echo "No build-id file $id_main_file"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+canon_main_file=$(readlink -f ${main_file})
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test -f "$canon_main_file" \
Panu Matilainen 5b4d98
+  || echo "Cannot resolve main file ${main_file} -> ${canon_main_file}"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+canon_main_id_file=$(readlink -f ${id_main_file})
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test -f "$canon_main_id_file" \
Panu Matilainen 5b4d98
+  || echo "Cannot resolve main build-id file ${id_main_file} -> ${canon_main_id_file}"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test "$canon_main_file" = "$canon_main_id_file" \
Panu Matilainen 5b4d98
+  || echo "main and build-id file not linked"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# And check the same for the debug file.
Panu Matilainen 5b4d98
+debug_file=./usr/lib/debug/usr/local/bin/hello.debug
Panu Matilainen 5b4d98
+test -f "${debug_file}" || echo "No debug file ${debug_file}"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Extract the build-id from the .debug file
Panu Matilainen 5b4d98
+id_debug=$(file $debug_file | sed 's/.*, BuildID[.*]=\(.*\),.*/\1/')
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test ${id_main} = ${id_debug} || echo "unequal main and debug id"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+id_debug_file="./usr/lib/debug/.build-id/${id_debug:0:2}/${id_debug:2}.debug"
Panu Matilainen 5b4d98
+test -L "$id_debug_file" || echo "No build-id file $id_debug_file"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+canon_debug_file=$(readlink -f ${debug_file})
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test -f "$canon_debug_file" \
Panu Matilainen 5b4d98
+  || echo "Cannot resolve debug file ${debug_file} -> ${canon_debug_file}"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+canon_debug_id_file=$(readlink -f ${id_debug_file})
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test -f "$canon_debug_id_file" \
Panu Matilainen 5b4d98
+  || echo "Cannot resolve debug build-id file ${id_debug_file} -> ${canon_debug_id_file}"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test "$canon_debug_file" = "$canon_debug_id_file" \
Panu Matilainen 5b4d98
+  || echo "debug and build-id not linked"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# The compat link should also point to the same (indirectly).
Panu Matilainen 5b4d98
+id_compat_file="./usr/lib/debug/.build-id/${id_main:0:2}/${id_main:2}"
Panu Matilainen 5b4d98
+test -L "$id_compat_file" || echo "No build-id compat file $id_compat_file"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+canon_compat_file=$(readlink -f ${id_compat_file})
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test -f "$canon_compat_file" \
Panu Matilainen 5b4d98
+  || echo "Cannot resolve compat file ${id_compat_file} -> ${canon_compat_file}"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+test "$canon_compat_file" = "$canon_main_file" \
Panu Matilainen 5b4d98
+  || echo "compat and build-id not linked"
Panu Matilainen 5b4d98
+],
Panu Matilainen 5b4d98
+[0],
Panu Matilainen 5b4d98
+[hello build-id files: 2
Panu Matilainen 5b4d98
+hello debuginfo build-id files: 3
Panu Matilainen 5b4d98
+],
Panu Matilainen 5b4d98
+[ignore])
Panu Matilainen 5b4d98
+AT_CLEANUP
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# ------------------------------
Panu Matilainen 5b4d98
+# Check that (copied) files with duplicate build-ids are handled correctly.
Panu Matilainen 5b4d98
+# This should create "numbered" build-id files.
Panu Matilainen 5b4d98
+# This is simply the hello example with one binary copied.
Panu Matilainen 5b4d98
+AT_SETUP([rpmbuild buildid duplicate alldebug])
Panu Matilainen 5b4d98
+AT_KEYWORDS([build] [debuginfo] [buildid])
Panu Matilainen 5b4d98
+AT_CHECK([
Panu Matilainen 5b4d98
+rm -rf ${TOPDIR}
Panu Matilainen 5b4d98
+AS_MKDIR_P(${TOPDIR}/SOURCES)
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+cp "${abs_srcdir}"/data/SOURCES/hello-1.0.tar.gz "${abs_srcdir}"/data/SOURCES/hello-1.0-modernize.patch ${TOPDIR}/SOURCES
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Should create two warnings
Panu Matilainen 5b4d98
+run rpmbuild --quiet \
Panu Matilainen 5b4d98
+  --macros=${abs_top_builddir}/macros:${abs_top_builddir}/tests/testing/usr/local/lib/rpm/platform/%{_target_cpu}-%{_target_os}/macros:${top_srcdir}/macros.debug \
Panu Matilainen 5b4d98
+  --rcfile=${abs_top_builddir}/rpmrc \
Panu Matilainen 5b4d98
+  --define="_build_id_links alldebug" \
Panu Matilainen 5b4d98
+  -ba "${abs_srcdir}"/data/SPECS/hello2cp.spec 2>&1 | grep "^warning: " \
Panu Matilainen 5b4d98
+  | cut -f1-3 -d' '
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello2-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | cpio -diu --quiet
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+hello_file=./usr/local/bin/hello
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Extract the build-id from the main file
Panu Matilainen 5b4d98
+id=$(file $hello_file | sed 's/.*, BuildID[.*]=\(.*\),.*/\1/')
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# alldebug not here...
Panu Matilainen 5b4d98
+id_file="./usr/lib/debug/.build-id/${id:0:2}/${id:2}"
Panu Matilainen 5b4d98
+test -L "$id_file" && echo "main id in main package"
Panu Matilainen 5b4d98
+id_dup_file="./usr/lib/debug/.build-id/${id:0:2}/${id:2}.1"
Panu Matilainen 5b4d98
+test -L "$id_dup_file" && echo "main dup id in main package"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello2-debuginfo-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | cpio -diu --quiet
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# alldebug, so they are all here
Panu Matilainen 5b4d98
+test -L "$id_file" && echo "main id in debug package"
Panu Matilainen 5b4d98
+test -L "$id_dup_file" && echo "main dup id in debug package"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+debug_id_file="./usr/lib/debug/.build-id/${id:0:2}/${id:2}.debug"
Panu Matilainen 5b4d98
+test -L "$debug_id_file" && echo "debug id in debug package"
Panu Matilainen 5b4d98
+debug_dup_file="./usr/lib/debug/.build-id/${id:0:2}/${id:2}.1.debug"
Panu Matilainen 5b4d98
+test -L "$debug_dup_file" && echo "debug dup id in debug package"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# We don't know which points to which, but we do know they point
Panu Matilainen 5b4d98
+# to different files.
Panu Matilainen 5b4d98
+canon_id_file=$(readlink -f ${id_file})
Panu Matilainen 5b4d98
+canon_dup_file=$(readlink -f ${id_dup_file})
Panu Matilainen 5b4d98
+test "$canon_id_file" != "$canon_dup_file" \
Panu Matilainen 5b4d98
+  || echo "id and dup same"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+canon_debug_id_file=$(readlink -f ${debug_id_file})
Panu Matilainen 5b4d98
+canon_debug_dup_file=$(readlink -f ${debug_dup_file})
Panu Matilainen 5b4d98
+test "$canon_debug_id_file" != "$canon_debug_dup_file" \
Panu Matilainen 5b4d98
+  || echo "debug id and dup same"
Panu Matilainen 5b4d98
+],
Panu Matilainen 5b4d98
+[0],
Panu Matilainen 5b4d98
+[warning: Duplicate build-ids
Panu Matilainen 5b4d98
+warning: Duplicate build-ids
Panu Matilainen 5b4d98
+main id in debug package
Panu Matilainen 5b4d98
+main dup id in debug package
Panu Matilainen 5b4d98
+debug id in debug package
Panu Matilainen 5b4d98
+debug dup id in debug package
Panu Matilainen 5b4d98
+],
Panu Matilainen 5b4d98
+[])
Panu Matilainen 5b4d98
+AT_CLEANUP
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# ------------------------------
Panu Matilainen 5b4d98
+# Check that hard linked files are handled correctly.
Panu Matilainen 5b4d98
+# Since the hard linked files have duplicate build-ids,
Panu Matilainen 5b4d98
+# it should create "numbered" build-id files.
Panu Matilainen 5b4d98
+# This is simply the hello example with one binary hard linked.
Panu Matilainen 5b4d98
+AT_SETUP([rpmbuild buildid hardlink alldebug])
Panu Matilainen 5b4d98
+AT_KEYWORDS([build] [debuginfo] [buildid])
Panu Matilainen 5b4d98
+AT_CHECK([
Panu Matilainen 5b4d98
+rm -rf ${TOPDIR}
Panu Matilainen 5b4d98
+AS_MKDIR_P(${TOPDIR}/SOURCES)
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+cp "${abs_srcdir}"/data/SOURCES/hello-1.0.tar.gz "${abs_srcdir}"/data/SOURCES/hello-1.0-modernize.patch ${TOPDIR}/SOURCES
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# No warnings for hard links
Panu Matilainen 5b4d98
+run rpmbuild --quiet \
Panu Matilainen 5b4d98
+  --macros=${abs_top_builddir}/macros:${abs_top_builddir}/tests/testing/usr/local/lib/rpm/platform/%{_target_cpu}-%{_target_os}/macros:${top_srcdir}/macros.debug \
Panu Matilainen 5b4d98
+  --rcfile=${abs_top_builddir}/rpmrc \
Panu Matilainen 5b4d98
+  --define="_build_id_links alldebug" \
Panu Matilainen 5b4d98
+  -ba "${abs_srcdir}"/data/SPECS/hello2ln.spec 2>&1 | grep "^warning: " \
Panu Matilainen 5b4d98
+  | cut -f1-3 -d' '
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello2-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | cpio -diu --quiet
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+hello_file=./usr/local/bin/hello
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Extract the build-id from the main file
Panu Matilainen 5b4d98
+id=$(file $hello_file | sed 's/.*, BuildID[.*]=\(.*\),.*/\1/')
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# alldebug not here...
Panu Matilainen 5b4d98
+id_file="./usr/lib/debug/.build-id/${id:0:2}/${id:2}"
Panu Matilainen 5b4d98
+test -L "$id_file" && echo "main id in main package"
Panu Matilainen 5b4d98
+id_dup_file="./usr/lib/debug/.build-id/${id:0:2}/${id:2}.1"
Panu Matilainen 5b4d98
+test -L "$id_dup_file" && echo "main dup id in main package"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello2-debuginfo-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | cpio -diu --quiet
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# alldebug, so they are all here
Panu Matilainen 5b4d98
+test -L "$id_file" && echo "main id in debug package"
Panu Matilainen 5b4d98
+test -L "$id_dup_file" && echo "main dup id in debug package"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+debug_id_file="./usr/lib/debug/.build-id/${id:0:2}/${id:2}.debug"
Panu Matilainen 5b4d98
+test -L "$debug_id_file" && echo "debug id in debug package"
Panu Matilainen 5b4d98
+debug_dup_file="./usr/lib/debug/.build-id/${id:0:2}/${id:2}.1.debug"
Panu Matilainen 5b4d98
+test -L "$debug_dup_file" && echo "debug dup id in debug package"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# We don't know which points to which, but we do know they point
Panu Matilainen 5b4d98
+# to different files.
Panu Matilainen 5b4d98
+canon_id_file=$(readlink -f ${id_file})
Panu Matilainen 5b4d98
+canon_dup_file=$(readlink -f ${id_dup_file})
Panu Matilainen 5b4d98
+test "$canon_id_file" != "$canon_dup_file" \
Panu Matilainen 5b4d98
+  || echo "id and dup same"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+canon_debug_id_file=$(readlink -f ${debug_id_file})
Panu Matilainen 5b4d98
+canon_debug_dup_file=$(readlink -f ${debug_dup_file})
Panu Matilainen 5b4d98
+test "$canon_debug_id_file" != "$canon_debug_dup_file" \
Panu Matilainen 5b4d98
+  || echo "debug id and dup same"
Panu Matilainen 5b4d98
+],
Panu Matilainen 5b4d98
+[0],
Panu Matilainen 5b4d98
+[main id in debug package
Panu Matilainen 5b4d98
+main dup id in debug package
Panu Matilainen 5b4d98
+debug id in debug package
Panu Matilainen 5b4d98
+debug dup id in debug package
Panu Matilainen 5b4d98
+],
Panu Matilainen 5b4d98
+[])
Panu Matilainen 5b4d98
+AT_CLEANUP
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# ------------------------------
Panu Matilainen 5b4d98
+# Check that (copied) files with duplicate build-ids are handled correctly.
Panu Matilainen 5b4d98
+# This should create "numbered" build-id files.
Panu Matilainen 5b4d98
+# This is simply the hello example with one binary copied.
Panu Matilainen 5b4d98
+AT_SETUP([rpmbuild buildid duplicate separate])
Panu Matilainen 5b4d98
+AT_KEYWORDS([build] [debuginfo] [buildid])
Panu Matilainen 5b4d98
+AT_CHECK([
Panu Matilainen 5b4d98
+rm -rf ${TOPDIR}
Panu Matilainen 5b4d98
+AS_MKDIR_P(${TOPDIR}/SOURCES)
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+cp "${abs_srcdir}"/data/SOURCES/hello-1.0.tar.gz "${abs_srcdir}"/data/SOURCES/hello-1.0-modernize.patch ${TOPDIR}/SOURCES
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Should create two warnings
Panu Matilainen 5b4d98
+run rpmbuild --quiet \
Panu Matilainen 5b4d98
+  --macros=${abs_top_builddir}/macros:${abs_top_builddir}/tests/testing/usr/local/lib/rpm/platform/%{_target_cpu}-%{_target_os}/macros:${top_srcdir}/macros.debug \
Panu Matilainen 5b4d98
+  --rcfile=${abs_top_builddir}/rpmrc \
Panu Matilainen 5b4d98
+  --define="_build_id_links separate" \
Panu Matilainen 5b4d98
+  -ba "${abs_srcdir}"/data/SPECS/hello2cp.spec 2>&1 | grep "^warning: " \
Panu Matilainen 5b4d98
+  | cut -f1-3 -d' '
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello2-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | cpio -diu --quiet
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+hello_file=./usr/local/bin/hello
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Extract the build-id from the main file
Panu Matilainen 5b4d98
+id=$(file $hello_file | sed 's/.*, BuildID[.*]=\(.*\),.*/\1/')
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# separate build-ids split...
Panu Matilainen 5b4d98
+id_file="./usr/lib/.build-id/${id:0:2}/${id:2}"
Panu Matilainen 5b4d98
+test -L "$id_file" && echo "main id in main package"
Panu Matilainen 5b4d98
+id_dup_file="./usr/lib/.build-id/${id:0:2}/${id:2}.1"
Panu Matilainen 5b4d98
+test -L "$id_dup_file" && echo "main dup id in main package"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello2-debuginfo-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | cpio -diu --quiet
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# seperate, so debug ids are here
Panu Matilainen 5b4d98
+debug_id_file="./usr/lib/debug/.build-id/${id:0:2}/${id:2}.debug"
Panu Matilainen 5b4d98
+test -L "$debug_id_file" && echo "debug id in debug package"
Panu Matilainen 5b4d98
+debug_dup_file="./usr/lib/debug/.build-id/${id:0:2}/${id:2}.1.debug"
Panu Matilainen 5b4d98
+test -L "$debug_dup_file" && echo "debug dup id in debug package"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# We don't know which points to which, but we do know they point
Panu Matilainen 5b4d98
+# to different files.
Panu Matilainen 5b4d98
+canon_id_file=$(readlink -f ${id_file})
Panu Matilainen 5b4d98
+canon_dup_file=$(readlink -f ${id_dup_file})
Panu Matilainen 5b4d98
+test "$canon_id_file" != "$canon_dup_file" \
Panu Matilainen 5b4d98
+  || echo "id and dup same"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+canon_debug_id_file=$(readlink -f ${debug_id_file})
Panu Matilainen 5b4d98
+canon_debug_dup_file=$(readlink -f ${debug_dup_file})
Panu Matilainen 5b4d98
+test "$canon_debug_id_file" != "$canon_debug_dup_file" \
Panu Matilainen 5b4d98
+  || echo "debug id and dup same"
Panu Matilainen 5b4d98
+],
Panu Matilainen 5b4d98
+[0],
Panu Matilainen 5b4d98
+[warning: Duplicate build-ids
Panu Matilainen 5b4d98
+warning: Duplicate build-ids
Panu Matilainen 5b4d98
+main id in main package
Panu Matilainen 5b4d98
+main dup id in main package
Panu Matilainen 5b4d98
+debug id in debug package
Panu Matilainen 5b4d98
+debug dup id in debug package
Panu Matilainen 5b4d98
+],
Panu Matilainen 5b4d98
+[])
Panu Matilainen 5b4d98
+AT_CLEANUP
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# ------------------------------
Panu Matilainen 5b4d98
+# Check that hard linked files are handled correctly.
Panu Matilainen 5b4d98
+# Since the hard linked files have duplicate build-ids,
Panu Matilainen 5b4d98
+# it should create "numbered" build-id files.
Panu Matilainen 5b4d98
+# This is simply the hello example with one binary hard linked.
Panu Matilainen 5b4d98
+AT_SETUP([rpmbuild buildid hardlink separate])
Panu Matilainen 5b4d98
+AT_KEYWORDS([build] [debuginfo] [buildid])
Panu Matilainen 5b4d98
+AT_CHECK([
Panu Matilainen 5b4d98
+rm -rf ${TOPDIR}
Panu Matilainen 5b4d98
+AS_MKDIR_P(${TOPDIR}/SOURCES)
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+cp "${abs_srcdir}"/data/SOURCES/hello-1.0.tar.gz "${abs_srcdir}"/data/SOURCES/hello-1.0-modernize.patch ${TOPDIR}/SOURCES
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# No warnings for hard links
Panu Matilainen 5b4d98
+run rpmbuild --quiet \
Panu Matilainen 5b4d98
+  --macros=${abs_top_builddir}/macros:${abs_top_builddir}/tests/testing/usr/local/lib/rpm/platform/%{_target_cpu}-%{_target_os}/macros:${top_srcdir}/macros.debug \
Panu Matilainen 5b4d98
+  --rcfile=${abs_top_builddir}/rpmrc \
Panu Matilainen 5b4d98
+  --define="_build_id_links separate" \
Panu Matilainen 5b4d98
+  -ba "${abs_srcdir}"/data/SPECS/hello2ln.spec 2>&1 | grep "^warning: " \
Panu Matilainen 5b4d98
+  | cut -f1-3 -d' '
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello2-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | cpio -diu --quiet
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+hello_file=./usr/local/bin/hello
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Extract the build-id from the main file
Panu Matilainen 5b4d98
+id=$(file $hello_file | sed 's/.*, BuildID[.*]=\(.*\),.*/\1/')
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# separate build-ids split...
Panu Matilainen 5b4d98
+id_file="./usr/lib/.build-id/${id:0:2}/${id:2}"
Panu Matilainen 5b4d98
+test -L "$id_file" && echo "main id in main package"
Panu Matilainen 5b4d98
+id_dup_file="./usr/lib/.build-id/${id:0:2}/${id:2}.1"
Panu Matilainen 5b4d98
+test -L "$id_dup_file" && echo "main dup id in main package"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello2-debuginfo-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | cpio -diu --quiet
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# separate, so debug ids are here
Panu Matilainen 5b4d98
+debug_id_file="./usr/lib/debug/.build-id/${id:0:2}/${id:2}.debug"
Panu Matilainen 5b4d98
+test -L "$debug_id_file" && echo "debug id in debug package"
Panu Matilainen 5b4d98
+debug_dup_file="./usr/lib/debug/.build-id/${id:0:2}/${id:2}.1.debug"
Panu Matilainen 5b4d98
+test -L "$debug_dup_file" && echo "debug dup id in debug package"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# We don't know which points to which, but we do know they point
Panu Matilainen 5b4d98
+# to different files.
Panu Matilainen 5b4d98
+canon_id_file=$(readlink -f ${id_file})
Panu Matilainen 5b4d98
+canon_dup_file=$(readlink -f ${id_dup_file})
Panu Matilainen 5b4d98
+test "$canon_id_file" != "$canon_dup_file" \
Panu Matilainen 5b4d98
+  || echo "id and dup same"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+canon_debug_id_file=$(readlink -f ${debug_id_file})
Panu Matilainen 5b4d98
+canon_debug_dup_file=$(readlink -f ${debug_dup_file})
Panu Matilainen 5b4d98
+test "$canon_debug_id_file" != "$canon_debug_dup_file" \
Panu Matilainen 5b4d98
+  || echo "debug id and dup same"
Panu Matilainen 5b4d98
+],
Panu Matilainen 5b4d98
+[0],
Panu Matilainen 5b4d98
+[main id in main package
Panu Matilainen 5b4d98
+main dup id in main package
Panu Matilainen 5b4d98
+debug id in debug package
Panu Matilainen 5b4d98
+debug dup id in debug package
Panu Matilainen 5b4d98
+],
Panu Matilainen 5b4d98
+[])
Panu Matilainen 5b4d98
+AT_CLEANUP
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# ------------------------------
Panu Matilainen 5b4d98
+# Check that (copied) files with duplicate build-ids are handled correctly.
Panu Matilainen 5b4d98
+# This should create "numbered" build-id files.
Panu Matilainen 5b4d98
+# This is simply the hello example with one binary copied.
Panu Matilainen 5b4d98
+AT_SETUP([rpmbuild buildid duplicate compat])
Panu Matilainen 5b4d98
+AT_KEYWORDS([build] [debuginfo] [buildid])
Panu Matilainen 5b4d98
+AT_CHECK([
Panu Matilainen 5b4d98
+rm -rf ${TOPDIR}
Panu Matilainen 5b4d98
+AS_MKDIR_P(${TOPDIR}/SOURCES)
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+cp "${abs_srcdir}"/data/SOURCES/hello-1.0.tar.gz "${abs_srcdir}"/data/SOURCES/hello-1.0-modernize.patch ${TOPDIR}/SOURCES
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Should create two warnings
Panu Matilainen 5b4d98
+run rpmbuild --quiet \
Panu Matilainen 5b4d98
+  --macros=${abs_top_builddir}/macros:${abs_top_builddir}/tests/testing/usr/local/lib/rpm/platform/%{_target_cpu}-%{_target_os}/macros:${top_srcdir}/macros.debug \
Panu Matilainen 5b4d98
+  --rcfile=${abs_top_builddir}/rpmrc \
Panu Matilainen 5b4d98
+  --define="_build_id_links compat" \
Panu Matilainen 5b4d98
+  -ba "${abs_srcdir}"/data/SPECS/hello2cp.spec 2>&1 | grep "^warning: " \
Panu Matilainen 5b4d98
+  | cut -f1-3 -d' '
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello2-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | cpio -diu --quiet
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+hello_file=./usr/local/bin/hello
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Extract the build-id from the main file
Panu Matilainen 5b4d98
+id=$(file $hello_file | sed 's/.*, BuildID[.*]=\(.*\),.*/\1/')
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# compat build-ids split...
Panu Matilainen 5b4d98
+id_file="./usr/lib/.build-id/${id:0:2}/${id:2}"
Panu Matilainen 5b4d98
+test -L "$id_file" && echo "main id in main package"
Panu Matilainen 5b4d98
+id_dup_file="./usr/lib/.build-id/${id:0:2}/${id:2}.1"
Panu Matilainen 5b4d98
+test -L "$id_dup_file" && echo "main dup id in main package"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello2-debuginfo-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | cpio -diu --quiet
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# compat, so main (and debug) ids are (also) here
Panu Matilainen 5b4d98
+compat_file="./usr/lib/debug/.build-id/${id:0:2}/${id:2}"
Panu Matilainen 5b4d98
+test -L "$compat_file" && echo "compat id in debug package"
Panu Matilainen 5b4d98
+compat_dup_file="./usr/lib/debug/.build-id/${id:0:2}/${id:2}.1"
Panu Matilainen 5b4d98
+test -L "$compat_dup_file" && echo "compat dup id in debug package"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+debug_id_file="./usr/lib/debug/.build-id/${id:0:2}/${id:2}.debug"
Panu Matilainen 5b4d98
+test -L "$debug_id_file" && echo "debug id in debug package"
Panu Matilainen 5b4d98
+debug_dup_file="./usr/lib/debug/.build-id/${id:0:2}/${id:2}.1.debug"
Panu Matilainen 5b4d98
+test -L "$debug_dup_file" && echo "debug dup id in debug package"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# We don't know which points to which, but we do know they point
Panu Matilainen 5b4d98
+# to different files.
Panu Matilainen 5b4d98
+canon_id_file=$(readlink -f ${id_file})
Panu Matilainen 5b4d98
+canon_dup_file=$(readlink -f ${id_dup_file})
Panu Matilainen 5b4d98
+test "$canon_id_file" != "$canon_dup_file" \
Panu Matilainen 5b4d98
+  || echo "id and dup same"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+canon_debug_id_file=$(readlink -f ${debug_id_file})
Panu Matilainen 5b4d98
+canon_debug_dup_file=$(readlink -f ${debug_dup_file})
Panu Matilainen 5b4d98
+test "$canon_debug_id_file" != "$canon_debug_dup_file" \
Panu Matilainen 5b4d98
+  || echo "debug id and dup same"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+canon_compat_file=$(readlink -f ${compat_file})
Panu Matilainen 5b4d98
+canon_compat_dup_file=$(readlink -f ${compat_dup_file})
Panu Matilainen 5b4d98
+test "$canon_compat_file" != "$canon_compat_dup_file" \
Panu Matilainen 5b4d98
+  || echo "compat id and dup same"
Panu Matilainen 5b4d98
+],
Panu Matilainen 5b4d98
+[0],
Panu Matilainen 5b4d98
+[warning: Duplicate build-ids
Panu Matilainen 5b4d98
+warning: Duplicate build-ids
Panu Matilainen 5b4d98
+main id in main package
Panu Matilainen 5b4d98
+main dup id in main package
Panu Matilainen 5b4d98
+compat id in debug package
Panu Matilainen 5b4d98
+compat dup id in debug package
Panu Matilainen 5b4d98
+debug id in debug package
Panu Matilainen 5b4d98
+debug dup id in debug package
Panu Matilainen 5b4d98
+],
Panu Matilainen 5b4d98
+[])
Panu Matilainen 5b4d98
+AT_CLEANUP
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# ------------------------------
Panu Matilainen 5b4d98
+# Check that hard linked files are handled correctly.
Panu Matilainen 5b4d98
+# Since the hard linked files have duplicate build-ids,
Panu Matilainen 5b4d98
+# it should create "numbered" build-id files.
Panu Matilainen 5b4d98
+# This is simply the hello example with one binary hard linked.
Panu Matilainen 5b4d98
+AT_SETUP([rpmbuild buildid hardlink compat])
Panu Matilainen 5b4d98
+AT_KEYWORDS([build] [debuginfo] [buildid])
Panu Matilainen 5b4d98
+AT_CHECK([
Panu Matilainen 5b4d98
+rm -rf ${TOPDIR}
Panu Matilainen 5b4d98
+AS_MKDIR_P(${TOPDIR}/SOURCES)
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+cp "${abs_srcdir}"/data/SOURCES/hello-1.0.tar.gz "${abs_srcdir}"/data/SOURCES/hello-1.0-modernize.patch ${TOPDIR}/SOURCES
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# No warnings for hard links
Panu Matilainen 5b4d98
+run rpmbuild --quiet \
Panu Matilainen 5b4d98
+  --macros=${abs_top_builddir}/macros:${abs_top_builddir}/tests/testing/usr/local/lib/rpm/platform/%{_target_cpu}-%{_target_os}/macros:${top_srcdir}/macros.debug \
Panu Matilainen 5b4d98
+  --rcfile=${abs_top_builddir}/rpmrc \
Panu Matilainen 5b4d98
+  --define="_build_id_links compat" \
Panu Matilainen 5b4d98
+  -ba "${abs_srcdir}"/data/SPECS/hello2ln.spec 2>&1 | grep "^warning: " \
Panu Matilainen 5b4d98
+  | cut -f1-3 -d' '
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello2-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | cpio -diu --quiet
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+hello_file=./usr/local/bin/hello
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# Extract the build-id from the main file
Panu Matilainen 5b4d98
+id=$(file $hello_file | sed 's/.*, BuildID[.*]=\(.*\),.*/\1/')
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# compat build-ids split...
Panu Matilainen 5b4d98
+id_file="./usr/lib/.build-id/${id:0:2}/${id:2}"
Panu Matilainen 5b4d98
+test -L "$id_file" && echo "main id in main package"
Panu Matilainen 5b4d98
+id_dup_file="./usr/lib/.build-id/${id:0:2}/${id:2}.1"
Panu Matilainen 5b4d98
+test -L "$id_dup_file" && echo "main dup id in main package"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello2-debuginfo-1.0-1.*.rpm \
Panu Matilainen 5b4d98
+  | cpio -diu --quiet
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# compat, so main (and debug) ids are (also) here
Panu Matilainen 5b4d98
+compat_file="./usr/lib/debug/.build-id/${id:0:2}/${id:2}"
Panu Matilainen 5b4d98
+test -L "$compat_file" && echo "compat id in debug package"
Panu Matilainen 5b4d98
+compat_dup_file="./usr/lib/debug/.build-id/${id:0:2}/${id:2}.1"
Panu Matilainen 5b4d98
+test -L "$compat_dup_file" && echo "compat dup id in debug package"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+debug_id_file="./usr/lib/debug/.build-id/${id:0:2}/${id:2}.debug"
Panu Matilainen 5b4d98
+test -L "$debug_id_file" && echo "debug id in debug package"
Panu Matilainen 5b4d98
+debug_dup_file="./usr/lib/debug/.build-id/${id:0:2}/${id:2}.1.debug"
Panu Matilainen 5b4d98
+test -L "$debug_dup_file" && echo "debug dup id in debug package"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+# We don't know which points to which, but we do know they point
Panu Matilainen 5b4d98
+# to different files.
Panu Matilainen 5b4d98
+canon_id_file=$(readlink -f ${id_file})
Panu Matilainen 5b4d98
+canon_dup_file=$(readlink -f ${id_dup_file})
Panu Matilainen 5b4d98
+test "$canon_id_file" != "$canon_dup_file" \
Panu Matilainen 5b4d98
+  || echo "id and dup same"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+canon_debug_id_file=$(readlink -f ${debug_id_file})
Panu Matilainen 5b4d98
+canon_debug_dup_file=$(readlink -f ${debug_dup_file})
Panu Matilainen 5b4d98
+test "$canon_debug_id_file" != "$canon_debug_dup_file" \
Panu Matilainen 5b4d98
+  || echo "debug id and dup same"
Panu Matilainen 5b4d98
+
Panu Matilainen 5b4d98
+canon_compat_file=$(readlink -f ${compat_file})
Panu Matilainen 5b4d98
+canon_compat_dup_file=$(readlink -f ${compat_dup_file})
Panu Matilainen 5b4d98
+test "$canon_compat_file" != "$canon_compat_dup_file" \
Panu Matilainen 5b4d98
+  || echo "compat id and dup same"
Panu Matilainen 5b4d98
+],
Panu Matilainen 5b4d98
+[0],
Panu Matilainen 5b4d98
+[main id in main package
Panu Matilainen 5b4d98
+main dup id in main package
Panu Matilainen 5b4d98
+compat id in debug package
Panu Matilainen 5b4d98
+compat dup id in debug package
Panu Matilainen 5b4d98
+debug id in debug package
Panu Matilainen 5b4d98
+debug dup id in debug package
Panu Matilainen 5b4d98
+],
Panu Matilainen 5b4d98
+[])
Panu Matilainen 5b4d98
+AT_CLEANUP
Panu Matilainen 5b4d98
\ No newline at end of file
Panu Matilainen 5b4d98
diff --git a/tests/rpmtests.at b/tests/rpmtests.at
Igor Gnatenko 082d5d
index b51266a2d..5495cced1 100644
Panu Matilainen 5b4d98
--- a/tests/rpmtests.at
Panu Matilainen 5b4d98
+++ b/tests/rpmtests.at
Panu Matilainen 5b4d98
@@ -4,6 +4,7 @@ m4_include([rpmverify.at])
Panu Matilainen 5b4d98
 m4_include([rpmdb.at])
Panu Matilainen 5b4d98
 m4_include([rpmi.at])
Panu Matilainen 5b4d98
 m4_include([rpmbuild.at])
Panu Matilainen 5b4d98
+m4_include([rpmbuildid.at])
Panu Matilainen 5b4d98
 m4_include([rpmscript.at])
Panu Matilainen 5b4d98
 m4_include([rpmvercmp.at])
Panu Matilainen 5b4d98
 m4_include([rpmdeps.at])
Panu Matilainen 5b4d98
-- 
Igor Gnatenko 082d5d
2.13.2
Panu Matilainen 5b4d98