patch PR25722: /path/name based debuginfod-find & API lookups
Frank Ch. Eigler
fche@redhat.com
Sat Mar 28 00:52:14 GMT 2020
Hi -
Like this?
Author: Frank Ch. Eigler <fche@redhat.com>
Date: Fri Mar 27 20:47:45 2020 -0400
PR25722: debuginfod-find: accept /path/names in place of buildid hex
Extend the debuginfod-find command line interface to permit
/file/names instead of only buildid hexadecimal strings.
v2: move code into debuginfod-find; client API remains buildid only.
Signed-off-by: Frank Ch. Eigler <fche@redhat.com>
diff --git a/debuginfod/ChangeLog b/debuginfod/ChangeLog
index 3329be3510d2..6fc4c0981687 100644
--- a/debuginfod/ChangeLog
+++ b/debuginfod/ChangeLog
@@ -1,3 +1,9 @@
+2020-03-27 Frank Ch. Eigler <fche@redhat.com>
+
+ * debuginfod-find.c (main): Extract buildid from /binary/ if
+ given instead of hex string.
+ * Makefile.am: Add elfutils library prereqs for debuginfod-find.
+
2020-03-24 Frank Ch. Eigler <fche@redhat.com>
* debuginfod.h, libdebuginfod.map: New functions for _add_url_header.
diff --git a/debuginfod/Makefile.am b/debuginfod/Makefile.am
index 52ead30aebf8..51965f65dbb7 100644
--- a/debuginfod/Makefile.am
+++ b/debuginfod/Makefile.am
@@ -62,7 +62,7 @@ debuginfod_SOURCES = debuginfod.cxx
debuginfod_LDADD = $(libdw) $(libelf) $(libeu) $(libdebuginfod) $(libmicrohttpd_LIBS) $(libcurl_LIBS) $(sqlite3_LIBS) $(libarchive_LIBS) -lpthread -ldl
debuginfod_find_SOURCES = debuginfod-find.c
-debuginfod_find_LDADD = $(libeu) $(libdebuginfod)
+debuginfod_find_LDADD = $(libdw) $(libelf) $(libeu) $(libdebuginfod)
noinst_LIBRARIES = libdebuginfod.a
noinst_LIBRARIES += libdebuginfod_pic.a
diff --git a/debuginfod/debuginfod-find.c b/debuginfod/debuginfod-find.c
index 400c268224fb..83a43ce4be2e 100644
--- a/debuginfod/debuginfod-find.c
+++ b/debuginfod/debuginfod-find.c
@@ -25,6 +25,10 @@
#include <stdlib.h>
#include <string.h>
#include <argp.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <libdwelf.h>
/* Name and version of program. */
@@ -39,8 +43,12 @@ static const char doc[] = N_("Request debuginfo-related content "
/* Strings for arguments in help texts. */
static const char args_doc[] = N_("debuginfo BUILDID\n"
+ "debuginfo PATH\n"
"executable BUILDID\n"
- "source BUILDID /FILENAME");
+ "executable PATH\n"
+ "source BUILDID /FILENAME\n"
+ "source PATH /FILENAME\n");
+
/* Definitions of arguments for argp functions. */
static const struct argp_option options[] =
@@ -86,6 +94,8 @@ static struct argp argp =
int
main(int argc, char** argv)
{
+ elf_version (EV_CURRENT);
+
client = debuginfod_begin ();
if (client == NULL)
{
@@ -105,19 +115,61 @@ main(int argc, char** argv)
return 1;
}
- int rc;
+ /* If we were passed an ELF file name in the BUILDID slot, look in there. */
+ unsigned char* build_id = (unsigned char*) argv[remaining+1];
+ int build_id_len = 0; /* assume text */
+
+ int any_non_hex = 0;
+ int i;
+ for (i = 0; build_id[i] != '\0'; i++)
+ if ((build_id[i] >= '0' && build_id[i] <= '9') ||
+ (build_id[i] >= 'a' && build_id[i] <= 'f'))
+ ;
+ else
+ any_non_hex = 1;
+
+ int fd = -1;
+ Elf* elf = NULL;
+ if (any_non_hex) /* raw build-id */
+ {
+ fd = open ((char*) build_id, O_RDONLY);
+ if (fd < 0)
+ fprintf (stderr, "Cannot open %s: %s\n", build_id, strerror(errno));
+ }
+ if (fd >= 0)
+ {
+ elf = elf_begin (fd, ELF_C_READ_MMAP_PRIVATE, NULL);
+ if (elf == NULL)
+ fprintf (stderr, "Cannot elf_begin %s: %s\n", build_id, elf_errmsg(-1));
+ }
+ if (elf != NULL)
+ {
+ const void *extracted_build_id;
+ ssize_t s = dwelf_elf_gnu_build_id(elf, &extracted_build_id);
+ if (s > 0)
+ {
+ /* Success: replace the build_id pointer/len with the binary blob
+ that elfutils is keeping for us. It'll remain valid until elf_end(). */
+ build_id = (unsigned char*) extracted_build_id;
+ build_id_len = s;
+ }
+ else
+ fprintf (stderr, "Cannot extract build-id from %s: %s\n", build_id, elf_errmsg(-1));
+ }
+
char *cache_name;
+ int rc = 0;
/* Check whether FILETYPE is valid and call the appropriate
debuginfod_find_* function. If FILETYPE is "source"
then ensure a FILENAME was also supplied as an argument. */
if (strcmp(argv[remaining], "debuginfo") == 0)
rc = debuginfod_find_debuginfo(client,
- (unsigned char *)argv[remaining+1], 0,
+ build_id, build_id_len,
&cache_name);
else if (strcmp(argv[remaining], "executable") == 0)
rc = debuginfod_find_executable(client,
- (unsigned char *)argv[remaining+1], 0,
+ build_id, build_id_len,
&cache_name);
else if (strcmp(argv[remaining], "source") == 0)
{
@@ -126,8 +178,9 @@ main(int argc, char** argv)
fprintf(stderr, "If FILETYPE is \"source\" then absolute /FILENAME must be given\n");
return 1;
}
- rc = debuginfod_find_source(client, (unsigned char *)argv[remaining+1],
- 0, argv[remaining+2], &cache_name);
+ rc = debuginfod_find_source(client,
+ build_id, build_id_len,
+ argv[remaining+2], &cache_name);
}
else
{
@@ -143,6 +196,10 @@ main(int argc, char** argv)
}
debuginfod_end (client);
+ if (elf)
+ elf_end(elf);
+ if (fd >= 0)
+ close (fd);
if (rc < 0)
{
diff --git a/doc/ChangeLog b/doc/ChangeLog
index 38ce441c4076..25404e5876ba 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,7 @@
+2020-03-27 Frank Ch. Eigler <fche@redhat.com>
+
+ * debuginfod-find.1: Document /path/-based buildid passing.
+
2020-03-24 Frank Ch. Eigler <fche@redhat.com>
* debuginfod_add_http_header.3: New function, documented ...
diff --git a/doc/debuginfod-find.1 b/doc/debuginfod-find.1
index a861a48ed1d1..aeb1cb120918 100644
--- a/doc/debuginfod-find.1
+++ b/doc/debuginfod-find.1
@@ -19,10 +19,11 @@ debuginfod-find \- request debuginfo-related data
.SH SYNOPSIS
.B debuginfod-find [\fIOPTION\fP]... debuginfo \fIBUILDID\fP
-
+.B debuginfod-find [\fIOPTION\fP]... debuginfo \fIPATH\fP
.B debuginfod-find [\fIOPTION\fP]... executable \fIBUILDID\fP
-
+.B debuginfod-find [\fIOPTION\fP]... executable \fIPATH\fP
.B debuginfod-find [\fIOPTION\fP]... source \fIBUILDID\fP \fI/FILENAME\fP
+.B debuginfod-find [\fIOPTION\fP]... source \fIPATH\fP \fI/FILENAME\fP
.SH DESCRIPTION
\fBdebuginfod-find\fP queries one or more \fBdebuginfod\fP servers for
@@ -52,6 +53,14 @@ Build ID: 8713b9c3fb8a720137a4a08b325905c7aaf8429d
8713b9c3fb8a720137a4a08b325905c7aaf8429d
.ESAMPLE
+In place of the hexadecimal \fIBUILDID\fP, debuginfod-find also
+accepts a path name to to an ELF binary, from which it extracts the
+buildid. In this case, ensure the file name has some character other
+than \fB[0-9a-f]\fP. Files ambiguously named files like
+"\fBdeadbeef\fP" can be passed with a \fB./deadbeef\fP extra path
+component.
+
+
.SS debuginfo \fIBUILDID\fP
If the given buildid is known to a server, this request will result
diff --git a/tests/ChangeLog b/tests/ChangeLog
index d1c9e952870a..66df34ced63c 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,7 @@
+2020-03-27 Frank Ch. Eigler <fche@redhat.com>
+
+ * run-debuginfod-find.sh: Test /path/-based debuginfod-find.
+
2020-03-24 Frank Ch. Eigler <fche@redhat.com>
* run-debuginfod-find.sh: Test relay of UA and XFF headers across
diff --git a/tests/run-debuginfod-find.sh b/tests/run-debuginfod-find.sh
index 799b7005a26e..bba04c1fe20a 100755
--- a/tests/run-debuginfod-find.sh
+++ b/tests/run-debuginfod-find.sh
@@ -144,7 +144,7 @@ rm -rf $DEBUGINFOD_CACHE_PATH # clean it from previous tests
filename=`testrun ${abs_top_builddir}/debuginfod/debuginfod-find debuginfo $BUILDID`
cmp $filename F/prog.debug
-filename=`testrun ${abs_top_builddir}/debuginfod/debuginfod-find executable $BUILDID`
+filename=`testrun ${abs_top_builddir}/debuginfod/debuginfod-find executable F/prog`
cmp $filename F/prog
# raw source filename
More information about the Elfutils-devel
mailing list