1 /* debuginfod utilities for GDB.
2 Copyright (C) 2020 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 #include "cli/cli-style.h"
22 #include "gdbsupport/scoped_fd.h"
23 #include "debuginfod-support.h"
25 #ifndef HAVE_LIBDEBUGINFOD
27 debuginfod_source_query (const unsigned char *build_id
,
30 gdb::unique_xmalloc_ptr
<char> *destname
)
32 return scoped_fd (-ENOSYS
);
36 debuginfod_debuginfo_query (const unsigned char *build_id
,
39 gdb::unique_xmalloc_ptr
<char> *destname
)
41 return scoped_fd (-ENOSYS
);
44 #include <elfutils/debuginfod.h>
48 user_data (const char *desc
, const char *fname
)
49 : desc (desc
), fname (fname
), has_printed (false)
52 const char * const desc
;
53 const char * const fname
;
57 /* Deleter for a debuginfod_client. */
59 struct debuginfod_client_deleter
61 void operator() (debuginfod_client
*c
)
67 using debuginfod_client_up
68 = std::unique_ptr
<debuginfod_client
, debuginfod_client_deleter
>;
71 progressfn (debuginfod_client
*c
, long cur
, long total
)
73 user_data
*data
= static_cast<user_data
*> (debuginfod_get_user_data (c
));
75 if (check_quit_flag ())
77 printf_filtered ("Cancelling download of %s %ps...\n",
79 styled_string (file_name_style
.style (), data
->fname
));
83 if (!data
->has_printed
&& total
!= 0)
85 /* Print this message only once. */
86 data
->has_printed
= true;
87 printf_filtered ("Downloading %s %ps...\n",
89 styled_string (file_name_style
.style (), data
->fname
));
95 static debuginfod_client_up
98 debuginfod_client_up
c (debuginfod_begin ());
101 debuginfod_set_progressfn (c
.get (), progressfn
);
106 /* See debuginfod-support.h */
109 debuginfod_source_query (const unsigned char *build_id
,
112 gdb::unique_xmalloc_ptr
<char> *destname
)
114 const char *urls_env_var
= getenv (DEBUGINFOD_URLS_ENV_VAR
);
115 if (urls_env_var
== NULL
|| urls_env_var
[0] == '\0')
116 return scoped_fd (-ENOSYS
);
118 debuginfod_client_up c
= debuginfod_init ();
121 return scoped_fd (-ENOMEM
);
123 user_data
data ("source file", srcpath
);
125 debuginfod_set_user_data (c
.get (), &data
);
126 scoped_fd
fd (debuginfod_find_source (c
.get (),
132 /* TODO: Add 'set debug debuginfod' command to control when error messages are shown. */
133 if (fd
.get () < 0 && fd
.get () != -ENOENT
)
134 printf_filtered (_("Download failed: %s. Continuing without source file %ps.\n"),
135 safe_strerror (-fd
.get ()),
136 styled_string (file_name_style
.style (), srcpath
));
139 *destname
= make_unique_xstrdup (srcpath
);
144 /* See debuginfod-support.h */
147 debuginfod_debuginfo_query (const unsigned char *build_id
,
149 const char *filename
,
150 gdb::unique_xmalloc_ptr
<char> *destname
)
152 const char *urls_env_var
= getenv (DEBUGINFOD_URLS_ENV_VAR
);
153 if (urls_env_var
== NULL
|| urls_env_var
[0] == '\0')
154 return scoped_fd (-ENOSYS
);
156 debuginfod_client_up c
= debuginfod_init ();
159 return scoped_fd (-ENOMEM
);
161 char *dname
= nullptr;
162 user_data
data ("separate debug info for", filename
);
164 debuginfod_set_user_data (c
.get (), &data
);
165 scoped_fd
fd (debuginfod_find_debuginfo (c
.get (), build_id
, build_id_len
,
168 if (fd
.get () < 0 && fd
.get () != -ENOENT
)
169 printf_filtered (_("Download failed: %s. Continuing without debug info for %ps.\n"),
170 safe_strerror (-fd
.get ()),
171 styled_string (file_name_style
.style (), filename
));
174 destname
->reset (dname
);