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