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"
24 #include "gdbsupport/gdb_optional.h"
26 #ifndef HAVE_LIBDEBUGINFOD
28 debuginfod_source_query (const unsigned char *build_id,
31 gdb::unique_xmalloc_ptr<char> *destname)
33 return scoped_fd (-ENOSYS);
37 debuginfod_debuginfo_query (const unsigned char *build_id,
40 gdb::unique_xmalloc_ptr<char> *destname)
42 return scoped_fd (-ENOSYS);
45 #include <elfutils/debuginfod.h>
49 user_data (const char *desc, const char *fname)
50 : desc (desc), fname (fname)
53 const char * const desc;
54 const char * const fname;
55 gdb::optional<ui_out::progress_meter> meter;
58 /* Deleter for a debuginfod_client. */
60 struct debuginfod_client_deleter
62 void operator() (debuginfod_client *c)
68 using debuginfod_client_up
69 = std::unique_ptr<debuginfod_client, debuginfod_client_deleter>;
72 progressfn (debuginfod_client *c, long cur, long total)
74 user_data *data = static_cast<user_data *> (debuginfod_get_user_data (c));
76 if (check_quit_flag ())
78 printf_filtered ("Cancelling download of %s %ps...\n",
80 styled_string (file_name_style.style (), data->fname));
87 if (!data->meter.has_value ())
89 float size_in_mb = 1.0f * total / (1024 * 1024);
90 string_file styled_filename (current_uiout->can_emit_style_escape ());
91 fprintf_styled (&styled_filename,
92 file_name_style.style (),
96 = string_printf ("Downloading %.2f MB %s %s", size_in_mb, data->desc,
97 styled_filename.c_str());
98 data->meter.emplace (current_uiout, message, 1);
101 current_uiout->progress ((double)cur / (double)total);
106 static debuginfod_client_up
109 debuginfod_client_up c (debuginfod_begin ());
112 debuginfod_set_progressfn (c.get (), progressfn);
117 /* See debuginfod-support.h */
120 debuginfod_source_query (const unsigned char *build_id,
123 gdb::unique_xmalloc_ptr<char> *destname)
125 const char *urls_env_var = getenv (DEBUGINFOD_URLS_ENV_VAR);
126 if (urls_env_var == NULL || urls_env_var[0] == '\0')
127 return scoped_fd (-ENOSYS);
129 debuginfod_client_up c = debuginfod_init ();
132 return scoped_fd (-ENOMEM);
134 user_data data ("source file", srcpath);
136 debuginfod_set_user_data (c.get (), &data);
137 scoped_fd fd (debuginfod_find_source (c.get (),
143 /* TODO: Add 'set debug debuginfod' command to control when error messages are shown. */
144 if (fd.get () < 0 && fd.get () != -ENOENT)
145 printf_filtered (_("Download failed: %s. Continuing without source file %ps.\n"),
146 safe_strerror (-fd.get ()),
147 styled_string (file_name_style.style (), srcpath));
150 *destname = make_unique_xstrdup (srcpath);
155 /* See debuginfod-support.h */
158 debuginfod_debuginfo_query (const unsigned char *build_id,
160 const char *filename,
161 gdb::unique_xmalloc_ptr<char> *destname)
163 const char *urls_env_var = getenv (DEBUGINFOD_URLS_ENV_VAR);
164 if (urls_env_var == NULL || urls_env_var[0] == '\0')
165 return scoped_fd (-ENOSYS);
167 debuginfod_client_up c = debuginfod_init ();
170 return scoped_fd (-ENOMEM);
172 char *dname = nullptr;
173 user_data data ("separate debug info for", filename);
175 debuginfod_set_user_data (c.get (), &data);
176 scoped_fd fd (debuginfod_find_debuginfo (c.get (), build_id, build_id_len,
179 if (fd.get () < 0 && fd.get () != -ENOENT)
180 printf_filtered (_("Download failed: %s. Continuing without debug info for %ps.\n"),
181 safe_strerror (-fd.get ()),
182 styled_string (file_name_style.style (), filename));
185 destname->reset (dname);