aboutsummaryrefslogtreecommitdiffstats
path: root/debuginfod
diff options
context:
space:
mode:
authorFrank Ch. Eigler <fche@redhat.com>2020-02-05 15:04:18 -0500
committerFrank Ch. Eigler <fche@redhat.com>2020-02-10 11:09:49 -0500
commit8ef876aa170abec983d4359e51a33209ceb01caa (patch)
treeddae99dc4dbe29892a3d1aa0dfb0e8bd5aee6a54 /debuginfod
parentb86d781e3ee41ecd96db72370c40a523588a4021 (diff)
downloadplatform_external_elfutils-8ef876aa170abec983d4359e51a33209ceb01caa.tar.gz
platform_external_elfutils-8ef876aa170abec983d4359e51a33209ceb01caa.tar.bz2
platform_external_elfutils-8ef876aa170abec983d4359e51a33209ceb01caa.zip
debuginfod: generalized archive support
Add a '-Z EXT[=CMD]' option to debuginfod, which lets it scan any given extension and run CMD on it to unwrap distro archives. For example, for arch-linux pacman files, -Z '.tar.zst=zstdcat' lets debuginfod grok debug and source content in split-debuginfo files. Signed-off-by: Frank Ch. Eigler <fche@redhat.com>
Diffstat (limited to 'debuginfod')
-rw-r--r--debuginfod/ChangeLog6
-rw-r--r--debuginfod/debuginfod.cxx49
2 files changed, 45 insertions, 10 deletions
diff --git a/debuginfod/ChangeLog b/debuginfod/ChangeLog
index 8c97fdcf..d812e6d7 100644
--- a/debuginfod/ChangeLog
+++ b/debuginfod/ChangeLog
@@ -1,3 +1,9 @@
+2020-02-05 Frank Ch. Eigler <fche@redhat.com>
+
+ * debuginfod.cxx (argp options): Add -Z option.
+ (canonicalized_archive_entry_pathname): New function for
+ distro-agnostic file name matching/storage.
+
2020-01-22 Frank Ch. Eigler <fche@redhat.com>
* debuginfod.cxx (dwarf_extract_source_paths): Don't print
diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx
index 623dbc59..6d729023 100644
--- a/debuginfod/debuginfod.cxx
+++ b/debuginfod/debuginfod.cxx
@@ -333,9 +333,10 @@ ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
static const struct argp_option options[] =
{
{ NULL, 0, NULL, 0, "Scanners:", 1 },
- { "scan-file-dir", 'F', NULL, 0, "Enable ELF/DWARF file scanning threads.", 0 },
- { "scan-rpm-dir", 'R', NULL, 0, "Enable RPM scanning threads.", 0 },
- { "scan-deb-dir", 'U', NULL, 0, "Enable DEB scanning threads.", 0 },
+ { "scan-file-dir", 'F', NULL, 0, "Enable ELF/DWARF file scanning.", 0 },
+ { "scan-rpm-dir", 'R', NULL, 0, "Enable RPM scanning.", 0 },
+ { "scan-deb-dir", 'U', NULL, 0, "Enable DEB scanning.", 0 },
+ { "scan-archive", 'Z', "EXT=CMD", 0, "Enable arbitrary archive scanning.", 0 },
// "source-oci-imageregistry" ...
{ NULL, 0, NULL, 0, "Options:", 2 },
@@ -428,6 +429,17 @@ parse_opt (int key, char *arg,
scan_archives[".deb"]="dpkg-deb --fsys-tarfile";
scan_archives[".ddeb"]="dpkg-deb --fsys-tarfile";
break;
+ case 'Z':
+ {
+ char* extension = strchr(arg, '=');
+ if (arg[0] == '\0')
+ argp_failure(state, 1, EINVAL, "missing EXT");
+ else if (extension)
+ scan_archives[string(arg, (extension-arg))]=string(extension+1);
+ else
+ scan_archives[string(arg)]=string("cat");
+ }
+ break;
case 'L':
traverse_logical = true;
break;
@@ -1068,6 +1080,25 @@ public:
static libarchive_fdcache fdcache;
+// For security/portability reasons, many distro-package archives have
+// a "./" in front of path names; others have nothing, others have
+// "/". Canonicalize them all to a single leading "/", with the
+// assumption that this matches the dwarf-derived file names too.
+string canonicalized_archive_entry_pathname(struct archive_entry *e)
+{
+ string fn = archive_entry_pathname(e);
+ if (fn.size() == 0)
+ return fn;
+ if (fn[0] == '/')
+ return fn;
+ if (fn[0] == '.')
+ return fn.substr(1);
+ else
+ return string("/")+fn;
+}
+
+
+
static struct MHD_Response*
handle_buildid_r_match (int64_t b_mtime,
const string& b_source0,
@@ -1162,8 +1193,8 @@ handle_buildid_r_match (int64_t b_mtime,
if (! S_ISREG(archive_entry_mode (e))) // skip non-files completely
continue;
- string fn = archive_entry_pathname (e);
- if (fn != string(".")+b_source1)
+ string fn = canonicalized_archive_entry_pathname (e);
+ if (fn != b_source1)
continue;
// extract this file to a temporary file
@@ -2055,9 +2086,7 @@ archive_classify (const string& rps, string& archive_extension,
if (! S_ISREG(archive_entry_mode (e))) // skip non-files completely
continue;
- string fn = archive_entry_pathname (e);
- if (fn.size() > 1 && fn[0] == '.')
- fn = fn.substr(1); // trim off the leading '.'
+ string fn = canonicalized_archive_entry_pathname (e);
if (verbose > 3)
obatched(clog) << "libarchive checking " << fn << endl;
@@ -2764,7 +2793,7 @@ main (int argc, char *argv[])
"unexpected argument: %s", argv[remaining]);
if (scan_archives.size()==0 && !scan_files && source_paths.size()>0)
- obatched(clog) << "warning: without -F -R -U, ignoring PATHs" << endl;
+ obatched(clog) << "warning: without -F -R -U -Z, ignoring PATHs" << endl;
fdcache.limit(fdcache_fds, fdcache_mbs);
@@ -2894,7 +2923,7 @@ main (int argc, char *argv[])
obatched ob(clog);
auto& o = ob << "scanning archive types ";
for (auto&& arch : scan_archives)
- o << arch.first << " ";
+ o << arch.first << "(" << arch.second << ") ";
o << endl;
}
const char* du = getenv(DEBUGINFOD_URLS_ENV_VAR);