xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/debuginfod-support.c (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
17d62b00eSchristos /* debuginfod utilities for GDB.
2*6881a400Schristos    Copyright (C) 2020-2023 Free Software Foundation, Inc.
37d62b00eSchristos 
47d62b00eSchristos    This file is part of GDB.
57d62b00eSchristos 
67d62b00eSchristos    This program is free software; you can redistribute it and/or modify
77d62b00eSchristos    it under the terms of the GNU General Public License as published by
87d62b00eSchristos    the Free Software Foundation; either version 3 of the License, or
97d62b00eSchristos    (at your option) any later version.
107d62b00eSchristos 
117d62b00eSchristos    This program is distributed in the hope that it will be useful,
127d62b00eSchristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
137d62b00eSchristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
147d62b00eSchristos    GNU General Public License for more details.
157d62b00eSchristos 
167d62b00eSchristos    You should have received a copy of the GNU General Public License
177d62b00eSchristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
187d62b00eSchristos 
197d62b00eSchristos #include "defs.h"
20*6881a400Schristos #include "diagnostics.h"
217d62b00eSchristos #include <errno.h>
227d62b00eSchristos #include "gdbsupport/scoped_fd.h"
237d62b00eSchristos #include "debuginfod-support.h"
24*6881a400Schristos #include "gdbsupport/gdb_optional.h"
25*6881a400Schristos #include "cli/cli-cmds.h"
26*6881a400Schristos #include "cli/cli-style.h"
27*6881a400Schristos #include "cli-out.h"
28*6881a400Schristos #include "target.h"
29*6881a400Schristos 
30*6881a400Schristos /* Set/show debuginfod commands.  */
31*6881a400Schristos static cmd_list_element *set_debuginfod_prefix_list;
32*6881a400Schristos static cmd_list_element *show_debuginfod_prefix_list;
33*6881a400Schristos 
34*6881a400Schristos static const char debuginfod_on[] = "on";
35*6881a400Schristos static const char debuginfod_off[] = "off";
36*6881a400Schristos static const char debuginfod_ask[] = "ask";
37*6881a400Schristos 
38*6881a400Schristos static const char *debuginfod_enabled_enum[] =
39*6881a400Schristos {
40*6881a400Schristos   debuginfod_on,
41*6881a400Schristos   debuginfod_off,
42*6881a400Schristos   debuginfod_ask,
43*6881a400Schristos   nullptr
44*6881a400Schristos };
45*6881a400Schristos 
46*6881a400Schristos static const char *debuginfod_enabled =
47*6881a400Schristos #if defined(HAVE_LIBDEBUGINFOD)
48*6881a400Schristos   debuginfod_ask;
49*6881a400Schristos #else
50*6881a400Schristos   debuginfod_off;
51*6881a400Schristos #endif
52*6881a400Schristos 
53*6881a400Schristos static unsigned int debuginfod_verbose = 1;
547d62b00eSchristos 
557d62b00eSchristos #ifndef HAVE_LIBDEBUGINFOD
567d62b00eSchristos scoped_fd
577d62b00eSchristos debuginfod_source_query (const unsigned char *build_id,
587d62b00eSchristos 			 int build_id_len,
597d62b00eSchristos 			 const char *srcpath,
607d62b00eSchristos 			 gdb::unique_xmalloc_ptr<char> *destname)
617d62b00eSchristos {
627d62b00eSchristos   return scoped_fd (-ENOSYS);
637d62b00eSchristos }
647d62b00eSchristos 
657d62b00eSchristos scoped_fd
667d62b00eSchristos debuginfod_debuginfo_query (const unsigned char *build_id,
677d62b00eSchristos 			    int build_id_len,
687d62b00eSchristos 			    const char *filename,
697d62b00eSchristos 			    gdb::unique_xmalloc_ptr<char> *destname)
707d62b00eSchristos {
717d62b00eSchristos   return scoped_fd (-ENOSYS);
727d62b00eSchristos }
73*6881a400Schristos 
74*6881a400Schristos scoped_fd
75*6881a400Schristos debuginfod_exec_query (const unsigned char *build_id,
76*6881a400Schristos 		       int build_id_len,
77*6881a400Schristos 		       const char *filename,
78*6881a400Schristos 		       gdb::unique_xmalloc_ptr<char> *destname)
79*6881a400Schristos {
80*6881a400Schristos   return scoped_fd (-ENOSYS);
81*6881a400Schristos }
82*6881a400Schristos 
83*6881a400Schristos #define NO_IMPL _("Support for debuginfod is not compiled into GDB.")
84*6881a400Schristos 
857d62b00eSchristos #else
867d62b00eSchristos #include <elfutils/debuginfod.h>
877d62b00eSchristos 
887d62b00eSchristos struct user_data
897d62b00eSchristos {
907d62b00eSchristos   user_data (const char *desc, const char *fname)
91*6881a400Schristos     : desc (desc), fname (fname)
927d62b00eSchristos   { }
937d62b00eSchristos 
947d62b00eSchristos   const char * const desc;
957d62b00eSchristos   const char * const fname;
96*6881a400Schristos   ui_out::progress_update progress;
977d62b00eSchristos };
987d62b00eSchristos 
99*6881a400Schristos /* Deleter for a debuginfod_client.  */
100*6881a400Schristos 
101*6881a400Schristos struct debuginfod_client_deleter
102*6881a400Schristos {
103*6881a400Schristos   void operator() (debuginfod_client *c)
104*6881a400Schristos   {
105*6881a400Schristos     debuginfod_end (c);
106*6881a400Schristos   }
107*6881a400Schristos };
108*6881a400Schristos 
109*6881a400Schristos using debuginfod_client_up
110*6881a400Schristos   = std::unique_ptr<debuginfod_client, debuginfod_client_deleter>;
111*6881a400Schristos 
112*6881a400Schristos 
113*6881a400Schristos /* Convert SIZE into a unit suitable for use with progress updates.
114*6881a400Schristos    SIZE should in given in bytes and will be converted into KB, MB, GB
115*6881a400Schristos    or remain unchanged. UNIT will be set to "B", "KB", "MB" or "GB"
116*6881a400Schristos    accordingly.  */
117*6881a400Schristos 
118*6881a400Schristos static const char *
119*6881a400Schristos get_size_and_unit (double &size)
120*6881a400Schristos {
121*6881a400Schristos   if (size < 1024)
122*6881a400Schristos     /* If size is less than 1 KB then set unit to B.  */
123*6881a400Schristos     return "B";
124*6881a400Schristos 
125*6881a400Schristos   size /= 1024;
126*6881a400Schristos   if (size < 1024)
127*6881a400Schristos     /* If size is less than 1 MB then set unit to KB.  */
128*6881a400Schristos     return "K";
129*6881a400Schristos 
130*6881a400Schristos   size /= 1024;
131*6881a400Schristos   if (size < 1024)
132*6881a400Schristos     /* If size is less than 1 GB then set unit to MB.  */
133*6881a400Schristos     return "M";
134*6881a400Schristos 
135*6881a400Schristos   size /= 1024;
136*6881a400Schristos   return "G";
137*6881a400Schristos }
138*6881a400Schristos 
1397d62b00eSchristos static int
1407d62b00eSchristos progressfn (debuginfod_client *c, long cur, long total)
1417d62b00eSchristos {
1427d62b00eSchristos   user_data *data = static_cast<user_data *> (debuginfod_get_user_data (c));
143*6881a400Schristos   gdb_assert (data != nullptr);
144*6881a400Schristos 
145*6881a400Schristos   string_file styled_fname (current_uiout->can_emit_style_escape ());
146*6881a400Schristos   fprintf_styled (&styled_fname, file_name_style.style (), "%s",
147*6881a400Schristos 		  data->fname);
1487d62b00eSchristos 
1497d62b00eSchristos   if (check_quit_flag ())
1507d62b00eSchristos     {
151*6881a400Schristos       gdb_printf ("Cancelling download of %s %s...\n",
152*6881a400Schristos 		  data->desc, styled_fname.c_str ());
1537d62b00eSchristos       return 1;
1547d62b00eSchristos     }
1557d62b00eSchristos 
156*6881a400Schristos   if (debuginfod_verbose == 0)
157*6881a400Schristos     return 0;
158*6881a400Schristos 
159*6881a400Schristos   /* Print progress update.  Include the transfer size if available.  */
160*6881a400Schristos   if (total > 0)
1617d62b00eSchristos     {
162*6881a400Schristos       /* Transfer size is known.  */
163*6881a400Schristos       double howmuch = (double) cur / (double) total;
164*6881a400Schristos 
165*6881a400Schristos       if (howmuch >= 0.0 && howmuch <= 1.0)
166*6881a400Schristos 	{
167*6881a400Schristos 	  double d_total = (double) total;
168*6881a400Schristos 	  const char *unit =  get_size_and_unit (d_total);
169*6881a400Schristos 	  std::string msg = string_printf ("Downloading %0.2f %s %s %s",
170*6881a400Schristos 					   d_total, unit, data->desc,
171*6881a400Schristos 					   styled_fname.c_str ());
172*6881a400Schristos 	  data->progress.update_progress (msg, unit, howmuch, d_total);
173*6881a400Schristos 	  return 0;
174*6881a400Schristos 	}
1757d62b00eSchristos     }
1767d62b00eSchristos 
177*6881a400Schristos   std::string msg = string_printf ("Downloading %s %s",
178*6881a400Schristos 				   data->desc, styled_fname.c_str ());
179*6881a400Schristos   data->progress.update_progress (msg);
1807d62b00eSchristos   return 0;
1817d62b00eSchristos }
1827d62b00eSchristos 
1837d62b00eSchristos static debuginfod_client *
184*6881a400Schristos get_debuginfod_client ()
1857d62b00eSchristos {
186*6881a400Schristos   static debuginfod_client_up global_client;
1877d62b00eSchristos 
188*6881a400Schristos   if (global_client == nullptr)
189*6881a400Schristos     {
190*6881a400Schristos       global_client.reset (debuginfod_begin ());
1917d62b00eSchristos 
192*6881a400Schristos       if (global_client != nullptr)
193*6881a400Schristos 	debuginfod_set_progressfn (global_client.get (), progressfn);
194*6881a400Schristos     }
195*6881a400Schristos 
196*6881a400Schristos   return global_client.get ();
197*6881a400Schristos }
198*6881a400Schristos 
199*6881a400Schristos /* Check if debuginfod is enabled.  If configured to do so, ask the user
200*6881a400Schristos    whether to enable debuginfod.  */
201*6881a400Schristos 
202*6881a400Schristos static bool
203*6881a400Schristos debuginfod_is_enabled ()
204*6881a400Schristos {
205*6881a400Schristos   const char *urls = skip_spaces (getenv (DEBUGINFOD_URLS_ENV_VAR));
206*6881a400Schristos 
207*6881a400Schristos   if (debuginfod_enabled == debuginfod_off
208*6881a400Schristos       || urls == nullptr
209*6881a400Schristos       || *urls == '\0')
210*6881a400Schristos     return false;
211*6881a400Schristos 
212*6881a400Schristos   if (debuginfod_enabled == debuginfod_ask)
213*6881a400Schristos     {
214*6881a400Schristos       gdb_printf (_("\nThis GDB supports auto-downloading debuginfo " \
215*6881a400Schristos 		    "from the following URLs:\n"));
216*6881a400Schristos 
217*6881a400Schristos       gdb::string_view url_view (urls);
218*6881a400Schristos       while (true)
219*6881a400Schristos 	{
220*6881a400Schristos 	  size_t off = url_view.find_first_not_of (' ');
221*6881a400Schristos 	  if (off == gdb::string_view::npos)
222*6881a400Schristos 	    break;
223*6881a400Schristos 	  url_view = url_view.substr (off);
224*6881a400Schristos 	  /* g++ 11.2.1 on s390x, g++ 11.3.1 on ppc64le and g++ 11 on
225*6881a400Schristos 	     hppa seem convinced url_view might be of SIZE_MAX length.
226*6881a400Schristos 	     And so complains because the length of an array can only
227*6881a400Schristos 	     be PTRDIFF_MAX.  */
228*6881a400Schristos 	  DIAGNOSTIC_PUSH
229*6881a400Schristos 	  DIAGNOSTIC_IGNORE_STRINGOP_OVERREAD
230*6881a400Schristos 	  off = url_view.find_first_of (' ');
231*6881a400Schristos 	  DIAGNOSTIC_POP
232*6881a400Schristos 	  gdb_printf
233*6881a400Schristos 	    (_("  <%ps>\n"),
234*6881a400Schristos 	     styled_string (file_name_style.style (),
235*6881a400Schristos 			    gdb::to_string (url_view.substr (0,
236*6881a400Schristos 							     off)).c_str ()));
237*6881a400Schristos 	  if (off == gdb::string_view::npos)
238*6881a400Schristos 	    break;
239*6881a400Schristos 	  url_view = url_view.substr (off);
240*6881a400Schristos 	}
241*6881a400Schristos 
242*6881a400Schristos       int resp = nquery (_("Enable debuginfod for this session? "));
243*6881a400Schristos       if (!resp)
244*6881a400Schristos 	{
245*6881a400Schristos 	  gdb_printf (_("Debuginfod has been disabled.\nTo make this " \
246*6881a400Schristos 			"setting permanent, add \'set debuginfod " \
247*6881a400Schristos 			"enabled off\' to .gdbinit.\n"));
248*6881a400Schristos 	  debuginfod_enabled = debuginfod_off;
249*6881a400Schristos 	  return false;
250*6881a400Schristos 	}
251*6881a400Schristos 
252*6881a400Schristos       gdb_printf (_("Debuginfod has been enabled.\nTo make this " \
253*6881a400Schristos 		    "setting permanent, add \'set debuginfod enabled " \
254*6881a400Schristos 		    "on\' to .gdbinit.\n"));
255*6881a400Schristos       debuginfod_enabled = debuginfod_on;
256*6881a400Schristos     }
257*6881a400Schristos 
258*6881a400Schristos   return true;
259*6881a400Schristos }
260*6881a400Schristos 
261*6881a400Schristos /* Print the result of the most recent attempted download.  */
262*6881a400Schristos 
263*6881a400Schristos static void
264*6881a400Schristos print_outcome (user_data &data, int fd)
265*6881a400Schristos {
266*6881a400Schristos   /* Clears the current line of progress output.  */
267*6881a400Schristos   current_uiout->do_progress_end ();
268*6881a400Schristos 
269*6881a400Schristos   if (fd < 0 && fd != -ENOENT)
270*6881a400Schristos     gdb_printf (_("Download failed: %s.  Continuing without %s %ps.\n"),
271*6881a400Schristos 		safe_strerror (-fd),
272*6881a400Schristos 		data.desc,
273*6881a400Schristos 		styled_string (file_name_style.style (), data.fname));
2747d62b00eSchristos }
2757d62b00eSchristos 
2767d62b00eSchristos /* See debuginfod-support.h  */
2777d62b00eSchristos 
2787d62b00eSchristos scoped_fd
2797d62b00eSchristos debuginfod_source_query (const unsigned char *build_id,
2807d62b00eSchristos 			 int build_id_len,
2817d62b00eSchristos 			 const char *srcpath,
2827d62b00eSchristos 			 gdb::unique_xmalloc_ptr<char> *destname)
2837d62b00eSchristos {
284*6881a400Schristos   if (!debuginfod_is_enabled ())
2857d62b00eSchristos     return scoped_fd (-ENOSYS);
2867d62b00eSchristos 
287*6881a400Schristos   debuginfod_client *c = get_debuginfod_client ();
2887d62b00eSchristos 
2897d62b00eSchristos   if (c == nullptr)
2907d62b00eSchristos     return scoped_fd (-ENOMEM);
2917d62b00eSchristos 
292*6881a400Schristos   char *dname = nullptr;
2937d62b00eSchristos   user_data data ("source file", srcpath);
2947d62b00eSchristos 
2957d62b00eSchristos   debuginfod_set_user_data (c, &data);
296*6881a400Schristos   gdb::optional<target_terminal::scoped_restore_terminal_state> term_state;
297*6881a400Schristos   if (target_supports_terminal_ours ())
298*6881a400Schristos     {
299*6881a400Schristos       term_state.emplace ();
300*6881a400Schristos       target_terminal::ours ();
301*6881a400Schristos     }
302*6881a400Schristos 
3037d62b00eSchristos   scoped_fd fd (debuginfod_find_source (c,
3047d62b00eSchristos 					build_id,
3057d62b00eSchristos 					build_id_len,
3067d62b00eSchristos 					srcpath,
307*6881a400Schristos 					&dname));
308*6881a400Schristos   debuginfod_set_user_data (c, nullptr);
309*6881a400Schristos   print_outcome (data, fd.get ());
3107d62b00eSchristos 
311*6881a400Schristos   if (fd.get () >= 0)
312*6881a400Schristos     destname->reset (dname);
3137d62b00eSchristos 
3147d62b00eSchristos   return fd;
3157d62b00eSchristos }
3167d62b00eSchristos 
3177d62b00eSchristos /* See debuginfod-support.h  */
3187d62b00eSchristos 
3197d62b00eSchristos scoped_fd
3207d62b00eSchristos debuginfod_debuginfo_query (const unsigned char *build_id,
3217d62b00eSchristos 			    int build_id_len,
3227d62b00eSchristos 			    const char *filename,
3237d62b00eSchristos 			    gdb::unique_xmalloc_ptr<char> *destname)
3247d62b00eSchristos {
325*6881a400Schristos   if (!debuginfod_is_enabled ())
3267d62b00eSchristos     return scoped_fd (-ENOSYS);
3277d62b00eSchristos 
328*6881a400Schristos   debuginfod_client *c = get_debuginfod_client ();
3297d62b00eSchristos 
3307d62b00eSchristos   if (c == nullptr)
3317d62b00eSchristos     return scoped_fd (-ENOMEM);
3327d62b00eSchristos 
3337d62b00eSchristos   char *dname = nullptr;
3347d62b00eSchristos   user_data data ("separate debug info for", filename);
3357d62b00eSchristos 
3367d62b00eSchristos   debuginfod_set_user_data (c, &data);
337*6881a400Schristos   gdb::optional<target_terminal::scoped_restore_terminal_state> term_state;
338*6881a400Schristos   if (target_supports_terminal_ours ())
339*6881a400Schristos     {
340*6881a400Schristos       term_state.emplace ();
341*6881a400Schristos       target_terminal::ours ();
342*6881a400Schristos     }
3437d62b00eSchristos 
344*6881a400Schristos   scoped_fd fd (debuginfod_find_debuginfo (c, build_id, build_id_len,
345*6881a400Schristos 					   &dname));
346*6881a400Schristos   debuginfod_set_user_data (c, nullptr);
347*6881a400Schristos   print_outcome (data, fd.get ());
3487d62b00eSchristos 
349*6881a400Schristos   if (fd.get () >= 0)
3507d62b00eSchristos     destname->reset (dname);
351*6881a400Schristos 
352*6881a400Schristos   return fd;
353*6881a400Schristos }
354*6881a400Schristos 
355*6881a400Schristos /* See debuginfod-support.h  */
356*6881a400Schristos 
357*6881a400Schristos scoped_fd
358*6881a400Schristos debuginfod_exec_query (const unsigned char *build_id,
359*6881a400Schristos 		       int build_id_len,
360*6881a400Schristos 		       const char *filename,
361*6881a400Schristos 		       gdb::unique_xmalloc_ptr<char> *destname)
362*6881a400Schristos {
363*6881a400Schristos   if (!debuginfod_is_enabled ())
364*6881a400Schristos     return scoped_fd (-ENOSYS);
365*6881a400Schristos 
366*6881a400Schristos   debuginfod_client *c = get_debuginfod_client ();
367*6881a400Schristos 
368*6881a400Schristos   if (c == nullptr)
369*6881a400Schristos     return scoped_fd (-ENOMEM);
370*6881a400Schristos 
371*6881a400Schristos   char *dname = nullptr;
372*6881a400Schristos   user_data data ("executable for", filename);
373*6881a400Schristos 
374*6881a400Schristos   debuginfod_set_user_data (c, &data);
375*6881a400Schristos   gdb::optional<target_terminal::scoped_restore_terminal_state> term_state;
376*6881a400Schristos   if (target_supports_terminal_ours ())
377*6881a400Schristos     {
378*6881a400Schristos       term_state.emplace ();
379*6881a400Schristos       target_terminal::ours ();
380*6881a400Schristos     }
381*6881a400Schristos 
382*6881a400Schristos   scoped_fd fd (debuginfod_find_executable (c, build_id, build_id_len, &dname));
383*6881a400Schristos   debuginfod_set_user_data (c, nullptr);
384*6881a400Schristos   print_outcome (data, fd.get ());
385*6881a400Schristos 
386*6881a400Schristos   if (fd.get () >= 0)
387*6881a400Schristos     destname->reset (dname);
388*6881a400Schristos 
3897d62b00eSchristos   return fd;
3907d62b00eSchristos }
3917d62b00eSchristos #endif
392*6881a400Schristos 
393*6881a400Schristos /* Set callback for "set debuginfod enabled".  */
394*6881a400Schristos 
395*6881a400Schristos static void
396*6881a400Schristos set_debuginfod_enabled (const char *value)
397*6881a400Schristos {
398*6881a400Schristos #if defined(HAVE_LIBDEBUGINFOD)
399*6881a400Schristos   debuginfod_enabled = value;
400*6881a400Schristos #else
401*6881a400Schristos   /* Disabling debuginfod when gdb is not built with it is a no-op.  */
402*6881a400Schristos   if (value != debuginfod_off)
403*6881a400Schristos     error (NO_IMPL);
404*6881a400Schristos #endif
405*6881a400Schristos }
406*6881a400Schristos 
407*6881a400Schristos /* Get callback for "set debuginfod enabled".  */
408*6881a400Schristos 
409*6881a400Schristos static const char *
410*6881a400Schristos get_debuginfod_enabled ()
411*6881a400Schristos {
412*6881a400Schristos   return debuginfod_enabled;
413*6881a400Schristos }
414*6881a400Schristos 
415*6881a400Schristos /* Show callback for "set debuginfod enabled".  */
416*6881a400Schristos 
417*6881a400Schristos static void
418*6881a400Schristos show_debuginfod_enabled (ui_file *file, int from_tty, cmd_list_element *cmd,
419*6881a400Schristos 			 const char *value)
420*6881a400Schristos {
421*6881a400Schristos   gdb_printf (file,
422*6881a400Schristos 	      _("Debuginfod functionality is currently set to "
423*6881a400Schristos 		"\"%s\".\n"), debuginfod_enabled);
424*6881a400Schristos }
425*6881a400Schristos 
426*6881a400Schristos /* Set callback for "set debuginfod urls".  */
427*6881a400Schristos 
428*6881a400Schristos static void
429*6881a400Schristos set_debuginfod_urls (const std::string &urls)
430*6881a400Schristos {
431*6881a400Schristos #if defined(HAVE_LIBDEBUGINFOD)
432*6881a400Schristos   if (setenv (DEBUGINFOD_URLS_ENV_VAR, urls.c_str (), 1) != 0)
433*6881a400Schristos     warning (_("Unable to set debuginfod URLs: %s"), safe_strerror (errno));
434*6881a400Schristos #else
435*6881a400Schristos   error (NO_IMPL);
436*6881a400Schristos #endif
437*6881a400Schristos }
438*6881a400Schristos 
439*6881a400Schristos /* Get callback for "set debuginfod urls".  */
440*6881a400Schristos 
441*6881a400Schristos static const std::string&
442*6881a400Schristos get_debuginfod_urls ()
443*6881a400Schristos {
444*6881a400Schristos   static std::string urls;
445*6881a400Schristos #if defined(HAVE_LIBDEBUGINFOD)
446*6881a400Schristos   const char *envvar = getenv (DEBUGINFOD_URLS_ENV_VAR);
447*6881a400Schristos 
448*6881a400Schristos   if (envvar != nullptr)
449*6881a400Schristos     urls = envvar;
450*6881a400Schristos   else
451*6881a400Schristos     urls.clear ();
452*6881a400Schristos #endif
453*6881a400Schristos 
454*6881a400Schristos   return urls;
455*6881a400Schristos }
456*6881a400Schristos 
457*6881a400Schristos /* Show callback for "set debuginfod urls".  */
458*6881a400Schristos 
459*6881a400Schristos static void
460*6881a400Schristos show_debuginfod_urls (ui_file *file, int from_tty, cmd_list_element *cmd,
461*6881a400Schristos 		      const char *value)
462*6881a400Schristos {
463*6881a400Schristos   if (value[0] == '\0')
464*6881a400Schristos     gdb_printf (file, _("Debuginfod URLs have not been set.\n"));
465*6881a400Schristos   else
466*6881a400Schristos     gdb_printf (file, _("Debuginfod URLs are currently set to:\n%s\n"),
467*6881a400Schristos 		value);
468*6881a400Schristos }
469*6881a400Schristos 
470*6881a400Schristos /* Show callback for "set debuginfod verbose".  */
471*6881a400Schristos 
472*6881a400Schristos static void
473*6881a400Schristos show_debuginfod_verbose_command (ui_file *file, int from_tty,
474*6881a400Schristos 				 cmd_list_element *cmd, const char *value)
475*6881a400Schristos {
476*6881a400Schristos   gdb_printf (file, _("Debuginfod verbose output is set to %s.\n"),
477*6881a400Schristos 	      value);
478*6881a400Schristos }
479*6881a400Schristos 
480*6881a400Schristos /* Register debuginfod commands.  */
481*6881a400Schristos 
482*6881a400Schristos void _initialize_debuginfod ();
483*6881a400Schristos void
484*6881a400Schristos _initialize_debuginfod ()
485*6881a400Schristos {
486*6881a400Schristos   /* set/show debuginfod */
487*6881a400Schristos   add_setshow_prefix_cmd ("debuginfod", class_run,
488*6881a400Schristos 			  _("Set debuginfod options."),
489*6881a400Schristos 			  _("Show debuginfod options."),
490*6881a400Schristos 			  &set_debuginfod_prefix_list,
491*6881a400Schristos 			  &show_debuginfod_prefix_list,
492*6881a400Schristos 			  &setlist, &showlist);
493*6881a400Schristos 
494*6881a400Schristos   add_setshow_enum_cmd ("enabled", class_run, debuginfod_enabled_enum,
495*6881a400Schristos 			_("Set whether to use debuginfod."),
496*6881a400Schristos 			_("Show whether to use debuginfod."),
497*6881a400Schristos 			_("\
498*6881a400Schristos When on, enable the use of debuginfod to download missing debug info and\n\
499*6881a400Schristos source files."),
500*6881a400Schristos 			set_debuginfod_enabled,
501*6881a400Schristos 			get_debuginfod_enabled,
502*6881a400Schristos 			show_debuginfod_enabled,
503*6881a400Schristos 			&set_debuginfod_prefix_list,
504*6881a400Schristos 			&show_debuginfod_prefix_list);
505*6881a400Schristos 
506*6881a400Schristos   /* set/show debuginfod urls */
507*6881a400Schristos   add_setshow_string_noescape_cmd ("urls", class_run, _("\
508*6881a400Schristos Set the list of debuginfod server URLs."), _("\
509*6881a400Schristos Show the list of debuginfod server URLs."), _("\
510*6881a400Schristos Manage the space-separated list of debuginfod server URLs that GDB will query \
511*6881a400Schristos when missing debuginfo, executables or source files.\nThe default value is \
512*6881a400Schristos copied from the DEBUGINFOD_URLS environment variable."),
513*6881a400Schristos 				   set_debuginfod_urls,
514*6881a400Schristos 				   get_debuginfod_urls,
515*6881a400Schristos 				   show_debuginfod_urls,
516*6881a400Schristos 				   &set_debuginfod_prefix_list,
517*6881a400Schristos 				   &show_debuginfod_prefix_list);
518*6881a400Schristos 
519*6881a400Schristos   /* set/show debuginfod verbose */
520*6881a400Schristos   add_setshow_zuinteger_cmd ("verbose", class_support,
521*6881a400Schristos 			     &debuginfod_verbose, _("\
522*6881a400Schristos Set verbosity of debuginfod output."), _("\
523*6881a400Schristos Show debuginfod debugging."), _("\
524*6881a400Schristos When set to a non-zero value, display verbose output for each debuginfod \
525*6881a400Schristos query.\nTo disable, set to zero.  Verbose output is displayed by default."),
526*6881a400Schristos 			     nullptr,
527*6881a400Schristos 			     show_debuginfod_verbose_command,
528*6881a400Schristos 			     &set_debuginfod_prefix_list,
529*6881a400Schristos 			     &show_debuginfod_prefix_list);
530*6881a400Schristos }
531