[gdb/tdep] Fix reverse execution of LDR(immediate) T4
[binutils-gdb.git] / gdb / debuginfod-support.c
blob7d8ada39e96bdaa9d79d58eb7b1a971df415d995
1 /* debuginfod utilities for GDB.
2 Copyright (C) 2020-2024 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/>. */
19 #include "defs.h"
20 #include "diagnostics.h"
21 #include <errno.h>
22 #include "gdbsupport/scoped_fd.h"
23 #include "debuginfod-support.h"
24 #include <optional>
25 #include "cli/cli-cmds.h"
26 #include "cli/cli-style.h"
27 #include "cli-out.h"
28 #include "target.h"
30 /* Set/show debuginfod commands. */
31 static cmd_list_element *set_debuginfod_prefix_list;
32 static cmd_list_element *show_debuginfod_prefix_list;
34 /* maint set/show debuginfod commands. */
35 static cmd_list_element *maint_set_debuginfod_cmdlist;
36 static cmd_list_element *maint_show_debuginfod_cmdlist;
38 static const char debuginfod_on[] = "on";
39 static const char debuginfod_off[] = "off";
40 static const char debuginfod_ask[] = "ask";
42 static const char *debuginfod_enabled_enum[] =
44 debuginfod_on,
45 debuginfod_off,
46 debuginfod_ask,
47 nullptr
50 static const char *debuginfod_enabled =
51 #if defined(HAVE_LIBDEBUGINFOD)
52 debuginfod_ask;
53 #else
54 debuginfod_off;
55 #endif
57 /* Controls whether ELF/DWARF section downloading is enabled. */
58 static bool debuginfod_download_sections =
59 #if defined(HAVE_LIBDEBUGINFOD_FIND_SECTION)
60 true;
61 #else
62 false;
63 #endif
65 static unsigned int debuginfod_verbose = 1;
67 #ifndef HAVE_LIBDEBUGINFOD
68 scoped_fd
69 debuginfod_source_query (const unsigned char *build_id,
70 int build_id_len,
71 const char *srcpath,
72 gdb::unique_xmalloc_ptr<char> *destname)
74 return scoped_fd (-ENOSYS);
77 scoped_fd
78 debuginfod_debuginfo_query (const unsigned char *build_id,
79 int build_id_len,
80 const char *filename,
81 gdb::unique_xmalloc_ptr<char> *destname)
83 return scoped_fd (-ENOSYS);
86 scoped_fd
87 debuginfod_exec_query (const unsigned char *build_id,
88 int build_id_len,
89 const char *filename,
90 gdb::unique_xmalloc_ptr<char> *destname)
92 return scoped_fd (-ENOSYS);
95 scoped_fd
96 debuginfod_section_query (const unsigned char *build_id,
97 int build_id_len,
98 const char *filename,
99 const char *section_name,
100 gdb::unique_xmalloc_ptr<char> *destname)
102 return scoped_fd (-ENOSYS);
104 #define NO_IMPL _("Support for debuginfod is not compiled into GDB.")
106 #else
107 #include <elfutils/debuginfod.h>
109 struct user_data
111 user_data (const char *desc, const char *fname)
112 : desc (desc), fname (fname)
115 const char * const desc;
116 const char * const fname;
117 ui_out::progress_update progress;
120 /* Convert SIZE into a unit suitable for use with progress updates.
121 SIZE should in given in bytes and will be converted into KB, MB, GB
122 or remain unchanged. UNIT will be set to "B", "KB", "MB" or "GB"
123 accordingly. */
125 static const char *
126 get_size_and_unit (double &size)
128 if (size < 1024)
129 /* If size is less than 1 KB then set unit to B. */
130 return "B";
132 size /= 1024;
133 if (size < 1024)
134 /* If size is less than 1 MB then set unit to KB. */
135 return "K";
137 size /= 1024;
138 if (size < 1024)
139 /* If size is less than 1 GB then set unit to MB. */
140 return "M";
142 size /= 1024;
143 return "G";
146 static int
147 progressfn (debuginfod_client *c, long cur, long total)
149 user_data *data = static_cast<user_data *> (debuginfod_get_user_data (c));
150 gdb_assert (data != nullptr);
152 string_file styled_fname (current_uiout->can_emit_style_escape ());
153 fprintf_styled (&styled_fname, file_name_style.style (), "%s",
154 data->fname);
156 if (check_quit_flag ())
158 ui_file *outstream = get_unbuffered (gdb_stdout);
159 gdb_printf (outstream, _("Cancelling download of %s %s...\n"),
160 data->desc, styled_fname.c_str ());
161 return 1;
164 if (debuginfod_verbose == 0)
165 return 0;
167 /* Print progress update. Include the transfer size if available. */
168 if (total > 0)
170 /* Transfer size is known. */
171 double howmuch = (double) cur / (double) total;
173 if (howmuch >= 0.0 && howmuch <= 1.0)
175 double d_total = (double) total;
176 const char *unit = get_size_and_unit (d_total);
177 std::string msg = string_printf ("Downloading %0.2f %s %s %s",
178 d_total, unit, data->desc,
179 styled_fname.c_str ());
180 data->progress.update_progress (msg, unit, howmuch, d_total);
181 return 0;
185 std::string msg = string_printf ("Downloading %s %s",
186 data->desc, styled_fname.c_str ());
187 data->progress.update_progress (msg);
188 return 0;
191 /* Cleanup ARG, which is a debuginfod_client pointer. */
193 static void
194 cleanup_debuginfod_client (void *arg)
196 debuginfod_client *client = static_cast<debuginfod_client *> (arg);
197 debuginfod_end (client);
200 /* Return a pointer to the single global debuginfod_client, initialising it
201 first if needed. */
203 static debuginfod_client *
204 get_debuginfod_client ()
206 static debuginfod_client *global_client = nullptr;
208 if (global_client == nullptr)
210 global_client = debuginfod_begin ();
212 if (global_client != nullptr)
214 /* It is important that we cleanup the debuginfod_client object
215 before calling exit. Some of the libraries used by debuginfod
216 make use of at_exit handlers to perform cleanup.
218 If we wrapped the debuginfod_client in a unique_ptr and relied
219 on its destructor to cleanup then this would be run as part of
220 the global C++ object destructors, which is after the at_exit
221 handlers, which is too late.
223 So instead, we make use of GDB's final cleanup mechanism. */
224 make_final_cleanup (cleanup_debuginfod_client, global_client);
225 debuginfod_set_progressfn (global_client, progressfn);
229 return global_client;
232 /* Check if debuginfod is enabled. If configured to do so, ask the user
233 whether to enable debuginfod. */
235 static bool
236 debuginfod_is_enabled ()
238 const char *urls = skip_spaces (getenv (DEBUGINFOD_URLS_ENV_VAR));
240 if (debuginfod_enabled == debuginfod_off
241 || urls == nullptr
242 || *urls == '\0')
243 return false;
245 if (debuginfod_enabled == debuginfod_ask)
247 gdb_printf (_("\nThis GDB supports auto-downloading debuginfo " \
248 "from the following URLs:\n"));
250 std::string_view url_view (urls);
251 while (true)
253 size_t off = url_view.find_first_not_of (' ');
254 if (off == std::string_view::npos)
255 break;
256 url_view = url_view.substr (off);
257 /* g++ 11.2.1 on s390x, g++ 11.3.1 on ppc64le and g++ 11 on
258 hppa seem convinced url_view might be of SIZE_MAX length.
259 And so complains because the length of an array can only
260 be PTRDIFF_MAX. */
261 DIAGNOSTIC_PUSH
262 DIAGNOSTIC_IGNORE_STRINGOP_OVERREAD
263 off = url_view.find_first_of (' ');
264 DIAGNOSTIC_POP
265 gdb_printf
266 (_(" <%ps>\n"),
267 styled_string (file_name_style.style (),
268 std::string (url_view.substr (0, off)).c_str ()));
269 if (off == std::string_view::npos)
270 break;
271 url_view = url_view.substr (off);
274 int resp = nquery (_("Enable debuginfod for this session? "));
275 if (!resp)
277 gdb_printf (_("Debuginfod has been disabled.\nTo make this " \
278 "setting permanent, add \'set debuginfod " \
279 "enabled off\' to .gdbinit.\n"));
280 debuginfod_enabled = debuginfod_off;
281 return false;
284 gdb_printf (_("Debuginfod has been enabled.\nTo make this " \
285 "setting permanent, add \'set debuginfod enabled " \
286 "on\' to .gdbinit.\n"));
287 debuginfod_enabled = debuginfod_on;
290 return true;
293 /* Print the result of the most recent attempted download. */
295 static void
296 print_outcome (int fd, const char *desc, const char *fname)
298 if (fd < 0 && fd != -ENOENT)
300 ui_file *outstream = get_unbuffered (gdb_stdout);
301 gdb_printf (outstream,
302 _("Download failed: %s. Continuing without %s %ps.\n"),
303 safe_strerror (-fd),
304 desc,
305 styled_string (file_name_style.style (), fname));
309 /* See debuginfod-support.h */
311 scoped_fd
312 debuginfod_source_query (const unsigned char *build_id,
313 int build_id_len,
314 const char *srcpath,
315 gdb::unique_xmalloc_ptr<char> *destname)
317 if (!debuginfod_is_enabled ())
318 return scoped_fd (-ENOSYS);
320 debuginfod_client *c = get_debuginfod_client ();
322 if (c == nullptr)
323 return scoped_fd (-ENOMEM);
325 char *dname = nullptr;
326 scoped_fd fd;
327 std::optional<target_terminal::scoped_restore_terminal_state> term_state;
330 user_data data ("source file", srcpath);
332 debuginfod_set_user_data (c, &data);
333 if (target_supports_terminal_ours ())
335 term_state.emplace ();
336 target_terminal::ours ();
339 fd = scoped_fd (debuginfod_find_source (c,
340 build_id,
341 build_id_len,
342 srcpath,
343 &dname));
344 debuginfod_set_user_data (c, nullptr);
347 print_outcome (fd.get (), "source file", srcpath);
349 if (fd.get () >= 0)
350 destname->reset (dname);
352 return fd;
355 /* See debuginfod-support.h */
357 scoped_fd
358 debuginfod_debuginfo_query (const unsigned char *build_id,
359 int build_id_len,
360 const char *filename,
361 gdb::unique_xmalloc_ptr<char> *destname)
363 if (!debuginfod_is_enabled ())
364 return scoped_fd (-ENOSYS);
366 debuginfod_client *c = get_debuginfod_client ();
368 if (c == nullptr)
369 return scoped_fd (-ENOMEM);
371 char *dname = nullptr;
372 scoped_fd fd;
373 std::optional<target_terminal::scoped_restore_terminal_state> term_state;
376 user_data data ("separate debug info for", filename);
378 debuginfod_set_user_data (c, &data);
379 if (target_supports_terminal_ours ())
381 term_state.emplace ();
382 target_terminal::ours ();
385 fd = scoped_fd (debuginfod_find_debuginfo (c, build_id, build_id_len,
386 &dname));
387 debuginfod_set_user_data (c, nullptr);
390 print_outcome (fd.get (), "separate debug info for", filename);
392 if (fd.get () >= 0)
393 destname->reset (dname);
395 return fd;
398 /* See debuginfod-support.h */
400 scoped_fd
401 debuginfod_exec_query (const unsigned char *build_id,
402 int build_id_len,
403 const char *filename,
404 gdb::unique_xmalloc_ptr<char> *destname)
406 if (!debuginfod_is_enabled ())
407 return scoped_fd (-ENOSYS);
409 debuginfod_client *c = get_debuginfod_client ();
411 if (c == nullptr)
412 return scoped_fd (-ENOMEM);
414 char *dname = nullptr;
415 scoped_fd fd;
416 std::optional<target_terminal::scoped_restore_terminal_state> term_state;
419 user_data data ("executable for", filename);
421 debuginfod_set_user_data (c, &data);
422 if (target_supports_terminal_ours ())
424 term_state.emplace ();
425 target_terminal::ours ();
428 fd = scoped_fd (debuginfod_find_executable (c, build_id, build_id_len,
429 &dname));
430 debuginfod_set_user_data (c, nullptr);
433 print_outcome (fd.get (), "executable for", filename);
435 if (fd.get () >= 0)
436 destname->reset (dname);
438 return fd;
441 /* See debuginfod-support.h */
443 scoped_fd
444 debuginfod_section_query (const unsigned char *build_id,
445 int build_id_len,
446 const char *filename,
447 const char *section_name,
448 gdb::unique_xmalloc_ptr<char> *destname)
450 #if !defined (HAVE_LIBDEBUGINFOD_FIND_SECTION)
451 return scoped_fd (-ENOSYS);
452 #else
454 if (!debuginfod_download_sections || !debuginfod_is_enabled ())
455 return scoped_fd (-ENOSYS);
457 debuginfod_client *c = get_debuginfod_client ();
459 if (c == nullptr)
460 return scoped_fd (-ENOMEM);
462 char *dname = nullptr;
463 std::string desc = std::string ("section ") + section_name + " for";
464 scoped_fd fd;
465 std::optional<target_terminal::scoped_restore_terminal_state> term_state;
468 user_data data (desc.c_str (), filename);
469 debuginfod_set_user_data (c, &data);
470 if (target_supports_terminal_ours ())
472 term_state.emplace ();
473 target_terminal::ours ();
476 fd = scoped_fd (debuginfod_find_section (c, build_id, build_id_len,
477 section_name, &dname));
478 debuginfod_set_user_data (c, nullptr);
481 print_outcome (fd.get (), desc.c_str (), filename);
482 gdb_assert (destname != nullptr);
484 if (fd.get () >= 0)
485 destname->reset (dname);
487 return fd;
488 #endif /* HAVE_LIBDEBUGINFOD_FIND_SECTION */
491 #endif
493 /* Set callback for "set debuginfod enabled". */
495 static void
496 set_debuginfod_enabled (const char *value)
498 #if defined(HAVE_LIBDEBUGINFOD)
499 debuginfod_enabled = value;
500 #else
501 /* Disabling debuginfod when gdb is not built with it is a no-op. */
502 if (value != debuginfod_off)
503 error (NO_IMPL);
504 #endif
507 /* Get callback for "set debuginfod enabled". */
509 static const char *
510 get_debuginfod_enabled ()
512 return debuginfod_enabled;
515 /* Show callback for "set debuginfod enabled". */
517 static void
518 show_debuginfod_enabled (ui_file *file, int from_tty, cmd_list_element *cmd,
519 const char *value)
521 gdb_printf (file,
522 _("Debuginfod functionality is currently set to "
523 "\"%s\".\n"), debuginfod_enabled);
526 /* Set callback for "set debuginfod urls". */
528 static void
529 set_debuginfod_urls (const std::string &urls)
531 #if defined(HAVE_LIBDEBUGINFOD)
532 if (setenv (DEBUGINFOD_URLS_ENV_VAR, urls.c_str (), 1) != 0)
533 warning (_("Unable to set debuginfod URLs: %s"), safe_strerror (errno));
534 #else
535 error (NO_IMPL);
536 #endif
539 /* Get callback for "set debuginfod urls". */
541 static const std::string&
542 get_debuginfod_urls ()
544 static std::string urls;
545 #if defined(HAVE_LIBDEBUGINFOD)
546 const char *envvar = getenv (DEBUGINFOD_URLS_ENV_VAR);
548 if (envvar != nullptr)
549 urls = envvar;
550 else
551 urls.clear ();
552 #endif
554 return urls;
557 /* Show callback for "set debuginfod urls". */
559 static void
560 show_debuginfod_urls (ui_file *file, int from_tty, cmd_list_element *cmd,
561 const char *value)
563 if (value[0] == '\0')
564 gdb_printf (file, _("Debuginfod URLs have not been set.\n"));
565 else
566 gdb_printf (file, _("Debuginfod URLs are currently set to:\n%s\n"),
567 value);
570 /* Show callback for "set debuginfod verbose". */
572 static void
573 show_debuginfod_verbose_command (ui_file *file, int from_tty,
574 cmd_list_element *cmd, const char *value)
576 gdb_printf (file, _("Debuginfod verbose output is set to %s.\n"),
577 value);
580 /* Set callback for "maint set debuginfod download-sections". */
582 static void
583 maint_set_debuginfod_download_sections (bool value)
585 #if !defined(HAVE_LIBDEBUGINFOD_FIND_SECTION)
586 if (value)
587 error (_("Support for section downloading is not compiled into GDB. " \
588 "Defaulting to \"off\"."));
589 #endif
591 debuginfod_download_sections = value;
594 /* Get callback for "maint set debuginfod download-sections". */
596 static bool
597 maint_get_debuginfod_download_sections ()
599 return debuginfod_download_sections;
602 /* Register debuginfod commands. */
604 void _initialize_debuginfod ();
605 void
606 _initialize_debuginfod ()
608 /* set/show debuginfod */
609 add_setshow_prefix_cmd ("debuginfod", class_run,
610 _("Set debuginfod options."),
611 _("Show debuginfod options."),
612 &set_debuginfod_prefix_list,
613 &show_debuginfod_prefix_list,
614 &setlist, &showlist);
616 add_setshow_enum_cmd ("enabled", class_run, debuginfod_enabled_enum,
617 _("Set whether to use debuginfod."),
618 _("Show whether to use debuginfod."),
619 _("\
620 When set to \"on\", enable the use of debuginfod to download missing\n\
621 debug info and source files. GDB may also download components of debug\n\
622 info instead of entire files. \"off\" disables the use of debuginfod.\n\
623 When set to \"ask\", prompt whether to enable or disable debuginfod." ),
624 set_debuginfod_enabled,
625 get_debuginfod_enabled,
626 show_debuginfod_enabled,
627 &set_debuginfod_prefix_list,
628 &show_debuginfod_prefix_list);
630 /* set/show debuginfod urls */
631 add_setshow_string_noescape_cmd ("urls", class_run, _("\
632 Set the list of debuginfod server URLs."), _("\
633 Show the list of debuginfod server URLs."), _("\
634 Manage the space-separated list of debuginfod server URLs that GDB will query \
635 when missing debuginfo, executables or source files.\nThe default value is \
636 copied from the DEBUGINFOD_URLS environment variable."),
637 set_debuginfod_urls,
638 get_debuginfod_urls,
639 show_debuginfod_urls,
640 &set_debuginfod_prefix_list,
641 &show_debuginfod_prefix_list);
643 /* set/show debuginfod verbose */
644 add_setshow_zuinteger_cmd ("verbose", class_support,
645 &debuginfod_verbose, _("\
646 Set verbosity of debuginfod output."), _("\
647 Show debuginfod debugging."), _("\
648 When set to a non-zero value, display verbose output for each debuginfod \
649 query.\nTo disable, set to zero. Verbose output is displayed by default."),
650 nullptr,
651 show_debuginfod_verbose_command,
652 &set_debuginfod_prefix_list,
653 &show_debuginfod_prefix_list);
655 /* maint set/show debuginfod. */
656 add_setshow_prefix_cmd ("debuginfod", class_maintenance,
657 _("Set debuginfod specific variables."),
658 _("Show debuginfod specific variables."),
659 &maint_set_debuginfod_cmdlist,
660 &maint_show_debuginfod_cmdlist,
661 &maintenance_set_cmdlist, &maintenance_show_cmdlist);
663 /* maint set/show debuginfod download-sections. */
664 add_setshow_boolean_cmd ("download-sections", class_maintenance, _("\
665 Set whether debuginfod may download individual ELF/DWARF sections."), _("\
666 Show whether debuginfod may download individual ELF/DWARF sections."), _("\
667 When enabled, debuginfod may attempt to download individual ELF/DWARF \
668 sections from debug info files.\nIf disabled, only whole debug info files \
669 may be downloaded."),
670 maint_set_debuginfod_download_sections,
671 maint_get_debuginfod_download_sections,
672 nullptr,
673 &maint_set_debuginfod_cmdlist,
674 &maint_show_debuginfod_cmdlist);