1 1.1 christos /* debuginfod utilities for GDB. 2 1.1.1.3 christos Copyright (C) 2020-2024 Free Software Foundation, Inc. 3 1.1 christos 4 1.1 christos This file is part of GDB. 5 1.1 christos 6 1.1 christos This program is free software; you can redistribute it and/or modify 7 1.1 christos it under the terms of the GNU General Public License as published by 8 1.1 christos the Free Software Foundation; either version 3 of the License, or 9 1.1 christos (at your option) any later version. 10 1.1 christos 11 1.1 christos This program is distributed in the hope that it will be useful, 12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 christos GNU General Public License for more details. 15 1.1 christos 16 1.1 christos You should have received a copy of the GNU General Public License 17 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 1.1 christos 19 1.1.1.2 christos #include "diagnostics.h" 20 1.1 christos #include <errno.h> 21 1.1 christos #include "gdbsupport/scoped_fd.h" 22 1.1 christos #include "debuginfod-support.h" 23 1.1.1.3 christos #include <optional> 24 1.1.1.2 christos #include "cli/cli-cmds.h" 25 1.1.1.2 christos #include "cli/cli-style.h" 26 1.1.1.2 christos #include "cli-out.h" 27 1.1.1.2 christos #include "target.h" 28 1.1.1.2 christos 29 1.1.1.2 christos /* Set/show debuginfod commands. */ 30 1.1.1.2 christos static cmd_list_element *set_debuginfod_prefix_list; 31 1.1.1.2 christos static cmd_list_element *show_debuginfod_prefix_list; 32 1.1.1.2 christos 33 1.1.1.3 christos /* maint set/show debuginfod commands. */ 34 1.1.1.3 christos static cmd_list_element *maint_set_debuginfod_cmdlist; 35 1.1.1.3 christos static cmd_list_element *maint_show_debuginfod_cmdlist; 36 1.1.1.3 christos 37 1.1.1.2 christos static const char debuginfod_on[] = "on"; 38 1.1.1.2 christos static const char debuginfod_off[] = "off"; 39 1.1.1.2 christos static const char debuginfod_ask[] = "ask"; 40 1.1.1.2 christos 41 1.1.1.2 christos static const char *debuginfod_enabled_enum[] = 42 1.1.1.2 christos { 43 1.1.1.2 christos debuginfod_on, 44 1.1.1.2 christos debuginfod_off, 45 1.1.1.2 christos debuginfod_ask, 46 1.1.1.2 christos nullptr 47 1.1.1.2 christos }; 48 1.1.1.2 christos 49 1.1.1.2 christos static const char *debuginfod_enabled = 50 1.1.1.2 christos #if defined(HAVE_LIBDEBUGINFOD) 51 1.1.1.2 christos debuginfod_ask; 52 1.1.1.2 christos #else 53 1.1.1.2 christos debuginfod_off; 54 1.1.1.2 christos #endif 55 1.1.1.2 christos 56 1.1.1.3 christos /* Controls whether ELF/DWARF section downloading is enabled. */ 57 1.1.1.3 christos static bool debuginfod_download_sections = 58 1.1.1.3 christos #if defined(HAVE_LIBDEBUGINFOD_FIND_SECTION) 59 1.1.1.3 christos true; 60 1.1.1.3 christos #else 61 1.1.1.3 christos false; 62 1.1.1.3 christos #endif 63 1.1.1.3 christos 64 1.1.1.2 christos static unsigned int debuginfod_verbose = 1; 65 1.1 christos 66 1.1 christos #ifndef HAVE_LIBDEBUGINFOD 67 1.1 christos scoped_fd 68 1.1 christos debuginfod_source_query (const unsigned char *build_id, 69 1.1 christos int build_id_len, 70 1.1 christos const char *srcpath, 71 1.1 christos gdb::unique_xmalloc_ptr<char> *destname) 72 1.1 christos { 73 1.1 christos return scoped_fd (-ENOSYS); 74 1.1 christos } 75 1.1 christos 76 1.1 christos scoped_fd 77 1.1 christos debuginfod_debuginfo_query (const unsigned char *build_id, 78 1.1 christos int build_id_len, 79 1.1 christos const char *filename, 80 1.1 christos gdb::unique_xmalloc_ptr<char> *destname) 81 1.1 christos { 82 1.1 christos return scoped_fd (-ENOSYS); 83 1.1 christos } 84 1.1.1.2 christos 85 1.1.1.2 christos scoped_fd 86 1.1.1.2 christos debuginfod_exec_query (const unsigned char *build_id, 87 1.1.1.2 christos int build_id_len, 88 1.1.1.2 christos const char *filename, 89 1.1.1.2 christos gdb::unique_xmalloc_ptr<char> *destname) 90 1.1.1.2 christos { 91 1.1.1.2 christos return scoped_fd (-ENOSYS); 92 1.1.1.2 christos } 93 1.1.1.2 christos 94 1.1.1.3 christos scoped_fd 95 1.1.1.3 christos debuginfod_section_query (const unsigned char *build_id, 96 1.1.1.3 christos int build_id_len, 97 1.1.1.3 christos const char *filename, 98 1.1.1.3 christos const char *section_name, 99 1.1.1.3 christos gdb::unique_xmalloc_ptr<char> *destname) 100 1.1.1.3 christos { 101 1.1.1.3 christos return scoped_fd (-ENOSYS); 102 1.1.1.3 christos } 103 1.1.1.2 christos #define NO_IMPL _("Support for debuginfod is not compiled into GDB.") 104 1.1.1.2 christos 105 1.1 christos #else 106 1.1 christos #include <elfutils/debuginfod.h> 107 1.1 christos 108 1.1 christos struct user_data 109 1.1 christos { 110 1.1 christos user_data (const char *desc, const char *fname) 111 1.1.1.2 christos : desc (desc), fname (fname) 112 1.1 christos { } 113 1.1 christos 114 1.1 christos const char * const desc; 115 1.1 christos const char * const fname; 116 1.1.1.2 christos ui_out::progress_update progress; 117 1.1.1.2 christos }; 118 1.1.1.2 christos 119 1.1.1.2 christos /* Convert SIZE into a unit suitable for use with progress updates. 120 1.1.1.2 christos SIZE should in given in bytes and will be converted into KB, MB, GB 121 1.1.1.2 christos or remain unchanged. UNIT will be set to "B", "KB", "MB" or "GB" 122 1.1.1.2 christos accordingly. */ 123 1.1.1.2 christos 124 1.1.1.2 christos static const char * 125 1.1.1.2 christos get_size_and_unit (double &size) 126 1.1.1.2 christos { 127 1.1.1.2 christos if (size < 1024) 128 1.1.1.2 christos /* If size is less than 1 KB then set unit to B. */ 129 1.1.1.2 christos return "B"; 130 1.1.1.2 christos 131 1.1.1.2 christos size /= 1024; 132 1.1.1.2 christos if (size < 1024) 133 1.1.1.2 christos /* If size is less than 1 MB then set unit to KB. */ 134 1.1.1.2 christos return "K"; 135 1.1.1.2 christos 136 1.1.1.2 christos size /= 1024; 137 1.1.1.2 christos if (size < 1024) 138 1.1.1.2 christos /* If size is less than 1 GB then set unit to MB. */ 139 1.1.1.2 christos return "M"; 140 1.1.1.2 christos 141 1.1.1.2 christos size /= 1024; 142 1.1.1.2 christos return "G"; 143 1.1.1.2 christos } 144 1.1.1.2 christos 145 1.1 christos static int 146 1.1 christos progressfn (debuginfod_client *c, long cur, long total) 147 1.1 christos { 148 1.1 christos user_data *data = static_cast<user_data *> (debuginfod_get_user_data (c)); 149 1.1.1.2 christos gdb_assert (data != nullptr); 150 1.1.1.2 christos 151 1.1.1.2 christos string_file styled_fname (current_uiout->can_emit_style_escape ()); 152 1.1.1.2 christos fprintf_styled (&styled_fname, file_name_style.style (), "%s", 153 1.1.1.2 christos data->fname); 154 1.1 christos 155 1.1 christos if (check_quit_flag ()) 156 1.1 christos { 157 1.1.1.3 christos ui_file *outstream = get_unbuffered (gdb_stdout); 158 1.1.1.3 christos gdb_printf (outstream, _("Cancelling download of %s %s...\n"), 159 1.1.1.2 christos data->desc, styled_fname.c_str ()); 160 1.1 christos return 1; 161 1.1 christos } 162 1.1 christos 163 1.1.1.2 christos if (debuginfod_verbose == 0) 164 1.1.1.2 christos return 0; 165 1.1.1.2 christos 166 1.1.1.2 christos /* Print progress update. Include the transfer size if available. */ 167 1.1.1.2 christos if (total > 0) 168 1.1 christos { 169 1.1.1.2 christos /* Transfer size is known. */ 170 1.1.1.2 christos double howmuch = (double) cur / (double) total; 171 1.1.1.2 christos 172 1.1.1.2 christos if (howmuch >= 0.0 && howmuch <= 1.0) 173 1.1.1.2 christos { 174 1.1.1.2 christos double d_total = (double) total; 175 1.1.1.2 christos const char *unit = get_size_and_unit (d_total); 176 1.1.1.2 christos std::string msg = string_printf ("Downloading %0.2f %s %s %s", 177 1.1.1.2 christos d_total, unit, data->desc, 178 1.1.1.2 christos styled_fname.c_str ()); 179 1.1.1.2 christos data->progress.update_progress (msg, unit, howmuch, d_total); 180 1.1.1.2 christos return 0; 181 1.1.1.2 christos } 182 1.1 christos } 183 1.1 christos 184 1.1.1.2 christos std::string msg = string_printf ("Downloading %s %s", 185 1.1.1.2 christos data->desc, styled_fname.c_str ()); 186 1.1.1.2 christos data->progress.update_progress (msg); 187 1.1 christos return 0; 188 1.1 christos } 189 1.1 christos 190 1.1.1.3 christos /* Return a pointer to the single global debuginfod_client, initialising it 191 1.1.1.3 christos first if needed. */ 192 1.1.1.3 christos 193 1.1 christos static debuginfod_client * 194 1.1.1.2 christos get_debuginfod_client () 195 1.1 christos { 196 1.1.1.3 christos static debuginfod_client *global_client = nullptr; 197 1.1.1.2 christos 198 1.1.1.2 christos if (global_client == nullptr) 199 1.1.1.2 christos { 200 1.1.1.3 christos global_client = debuginfod_begin (); 201 1.1.1.2 christos 202 1.1.1.2 christos if (global_client != nullptr) 203 1.1.1.3 christos { 204 1.1.1.3 christos /* It is important that we cleanup the debuginfod_client object 205 1.1.1.3 christos before calling exit. Some of the libraries used by debuginfod 206 1.1.1.3 christos make use of at_exit handlers to perform cleanup. 207 1.1.1.3 christos 208 1.1.1.3 christos If we wrapped the debuginfod_client in a unique_ptr and relied 209 1.1.1.3 christos on its destructor to cleanup then this would be run as part of 210 1.1.1.3 christos the global C++ object destructors, which is after the at_exit 211 1.1.1.3 christos handlers, which is too late. 212 1.1.1.3 christos 213 1.1.1.3 christos So instead, we make use of GDB's final cleanup mechanism. */ 214 1.1.1.3 christos add_final_cleanup ([] () 215 1.1.1.3 christos { 216 1.1.1.3 christos debuginfod_end (global_client); 217 1.1.1.3 christos }); 218 1.1.1.3 christos debuginfod_set_progressfn (global_client, progressfn); 219 1.1.1.3 christos } 220 1.1.1.2 christos } 221 1.1.1.2 christos 222 1.1.1.3 christos return global_client; 223 1.1.1.2 christos } 224 1.1.1.2 christos 225 1.1.1.2 christos /* Check if debuginfod is enabled. If configured to do so, ask the user 226 1.1.1.2 christos whether to enable debuginfod. */ 227 1.1.1.2 christos 228 1.1.1.2 christos static bool 229 1.1.1.2 christos debuginfod_is_enabled () 230 1.1.1.2 christos { 231 1.1.1.2 christos const char *urls = skip_spaces (getenv (DEBUGINFOD_URLS_ENV_VAR)); 232 1.1.1.2 christos 233 1.1.1.2 christos if (debuginfod_enabled == debuginfod_off 234 1.1.1.2 christos || urls == nullptr 235 1.1.1.2 christos || *urls == '\0') 236 1.1.1.2 christos return false; 237 1.1.1.2 christos 238 1.1.1.2 christos if (debuginfod_enabled == debuginfod_ask) 239 1.1.1.2 christos { 240 1.1.1.2 christos gdb_printf (_("\nThis GDB supports auto-downloading debuginfo " \ 241 1.1.1.2 christos "from the following URLs:\n")); 242 1.1.1.2 christos 243 1.1.1.3 christos std::string_view url_view (urls); 244 1.1.1.2 christos while (true) 245 1.1.1.2 christos { 246 1.1.1.2 christos size_t off = url_view.find_first_not_of (' '); 247 1.1.1.3 christos if (off == std::string_view::npos) 248 1.1.1.2 christos break; 249 1.1.1.2 christos url_view = url_view.substr (off); 250 1.1.1.2 christos /* g++ 11.2.1 on s390x, g++ 11.3.1 on ppc64le and g++ 11 on 251 1.1.1.2 christos hppa seem convinced url_view might be of SIZE_MAX length. 252 1.1.1.2 christos And so complains because the length of an array can only 253 1.1.1.2 christos be PTRDIFF_MAX. */ 254 1.1.1.2 christos DIAGNOSTIC_PUSH 255 1.1.1.2 christos DIAGNOSTIC_IGNORE_STRINGOP_OVERREAD 256 1.1.1.2 christos off = url_view.find_first_of (' '); 257 1.1.1.2 christos DIAGNOSTIC_POP 258 1.1.1.2 christos gdb_printf 259 1.1.1.2 christos (_(" <%ps>\n"), 260 1.1.1.2 christos styled_string (file_name_style.style (), 261 1.1.1.3 christos std::string (url_view.substr (0, off)).c_str ())); 262 1.1.1.3 christos if (off == std::string_view::npos) 263 1.1.1.2 christos break; 264 1.1.1.2 christos url_view = url_view.substr (off); 265 1.1.1.2 christos } 266 1.1.1.2 christos 267 1.1.1.2 christos int resp = nquery (_("Enable debuginfod for this session? ")); 268 1.1.1.2 christos if (!resp) 269 1.1.1.2 christos { 270 1.1.1.2 christos gdb_printf (_("Debuginfod has been disabled.\nTo make this " \ 271 1.1.1.2 christos "setting permanent, add \'set debuginfod " \ 272 1.1.1.2 christos "enabled off\' to .gdbinit.\n")); 273 1.1.1.2 christos debuginfod_enabled = debuginfod_off; 274 1.1.1.2 christos return false; 275 1.1.1.2 christos } 276 1.1.1.2 christos 277 1.1.1.2 christos gdb_printf (_("Debuginfod has been enabled.\nTo make this " \ 278 1.1.1.2 christos "setting permanent, add \'set debuginfod enabled " \ 279 1.1.1.2 christos "on\' to .gdbinit.\n")); 280 1.1.1.2 christos debuginfod_enabled = debuginfod_on; 281 1.1.1.2 christos } 282 1.1 christos 283 1.1.1.2 christos return true; 284 1.1.1.2 christos } 285 1.1.1.2 christos 286 1.1.1.2 christos /* Print the result of the most recent attempted download. */ 287 1.1.1.2 christos 288 1.1.1.2 christos static void 289 1.1.1.3 christos print_outcome (int fd, const char *desc, const char *fname) 290 1.1.1.2 christos { 291 1.1.1.2 christos if (fd < 0 && fd != -ENOENT) 292 1.1.1.3 christos { 293 1.1.1.3 christos ui_file *outstream = get_unbuffered (gdb_stdout); 294 1.1.1.3 christos gdb_printf (outstream, 295 1.1.1.3 christos _("Download failed: %s. Continuing without %s %ps.\n"), 296 1.1.1.3 christos safe_strerror (-fd), 297 1.1.1.3 christos desc, 298 1.1.1.3 christos styled_string (file_name_style.style (), fname)); 299 1.1.1.3 christos } 300 1.1 christos } 301 1.1 christos 302 1.1 christos /* See debuginfod-support.h */ 303 1.1 christos 304 1.1 christos scoped_fd 305 1.1 christos debuginfod_source_query (const unsigned char *build_id, 306 1.1 christos int build_id_len, 307 1.1 christos const char *srcpath, 308 1.1 christos gdb::unique_xmalloc_ptr<char> *destname) 309 1.1 christos { 310 1.1.1.2 christos if (!debuginfod_is_enabled ()) 311 1.1 christos return scoped_fd (-ENOSYS); 312 1.1 christos 313 1.1.1.2 christos debuginfod_client *c = get_debuginfod_client (); 314 1.1 christos 315 1.1 christos if (c == nullptr) 316 1.1 christos return scoped_fd (-ENOMEM); 317 1.1 christos 318 1.1.1.2 christos char *dname = nullptr; 319 1.1.1.3 christos scoped_fd fd; 320 1.1.1.3 christos std::optional<target_terminal::scoped_restore_terminal_state> term_state; 321 1.1 christos 322 1.1.1.3 christos { 323 1.1.1.3 christos user_data data ("source file", srcpath); 324 1.1.1.2 christos 325 1.1.1.3 christos debuginfod_set_user_data (c, &data); 326 1.1.1.3 christos if (target_supports_terminal_ours ()) 327 1.1.1.3 christos { 328 1.1.1.3 christos term_state.emplace (); 329 1.1.1.3 christos target_terminal::ours (); 330 1.1.1.3 christos } 331 1.1.1.3 christos 332 1.1.1.3 christos fd = scoped_fd (debuginfod_find_source (c, 333 1.1.1.3 christos build_id, 334 1.1.1.3 christos build_id_len, 335 1.1.1.3 christos srcpath, 336 1.1.1.3 christos &dname)); 337 1.1.1.3 christos debuginfod_set_user_data (c, nullptr); 338 1.1.1.3 christos } 339 1.1.1.3 christos 340 1.1.1.3 christos print_outcome (fd.get (), "source file", srcpath); 341 1.1 christos 342 1.1.1.2 christos if (fd.get () >= 0) 343 1.1.1.2 christos destname->reset (dname); 344 1.1 christos 345 1.1 christos return fd; 346 1.1 christos } 347 1.1 christos 348 1.1 christos /* See debuginfod-support.h */ 349 1.1 christos 350 1.1 christos scoped_fd 351 1.1 christos debuginfod_debuginfo_query (const unsigned char *build_id, 352 1.1 christos int build_id_len, 353 1.1 christos const char *filename, 354 1.1 christos gdb::unique_xmalloc_ptr<char> *destname) 355 1.1 christos { 356 1.1.1.2 christos if (!debuginfod_is_enabled ()) 357 1.1 christos return scoped_fd (-ENOSYS); 358 1.1 christos 359 1.1.1.2 christos debuginfod_client *c = get_debuginfod_client (); 360 1.1 christos 361 1.1 christos if (c == nullptr) 362 1.1 christos return scoped_fd (-ENOMEM); 363 1.1 christos 364 1.1 christos char *dname = nullptr; 365 1.1.1.3 christos scoped_fd fd; 366 1.1.1.3 christos std::optional<target_terminal::scoped_restore_terminal_state> term_state; 367 1.1 christos 368 1.1.1.3 christos { 369 1.1.1.3 christos user_data data ("separate debug info for", filename); 370 1.1.1.2 christos 371 1.1.1.3 christos debuginfod_set_user_data (c, &data); 372 1.1.1.3 christos if (target_supports_terminal_ours ()) 373 1.1.1.3 christos { 374 1.1.1.3 christos term_state.emplace (); 375 1.1.1.3 christos target_terminal::ours (); 376 1.1.1.3 christos } 377 1.1.1.3 christos 378 1.1.1.3 christos fd = scoped_fd (debuginfod_find_debuginfo (c, build_id, build_id_len, 379 1.1.1.3 christos &dname)); 380 1.1.1.3 christos debuginfod_set_user_data (c, nullptr); 381 1.1.1.3 christos } 382 1.1.1.3 christos 383 1.1.1.3 christos print_outcome (fd.get (), "separate debug info for", filename); 384 1.1 christos 385 1.1.1.2 christos if (fd.get () >= 0) 386 1.1.1.2 christos destname->reset (dname); 387 1.1 christos 388 1.1 christos return fd; 389 1.1 christos } 390 1.1.1.2 christos 391 1.1.1.2 christos /* See debuginfod-support.h */ 392 1.1.1.2 christos 393 1.1.1.2 christos scoped_fd 394 1.1.1.2 christos debuginfod_exec_query (const unsigned char *build_id, 395 1.1.1.2 christos int build_id_len, 396 1.1.1.2 christos const char *filename, 397 1.1.1.2 christos gdb::unique_xmalloc_ptr<char> *destname) 398 1.1.1.2 christos { 399 1.1.1.2 christos if (!debuginfod_is_enabled ()) 400 1.1.1.2 christos return scoped_fd (-ENOSYS); 401 1.1.1.2 christos 402 1.1.1.2 christos debuginfod_client *c = get_debuginfod_client (); 403 1.1.1.2 christos 404 1.1.1.2 christos if (c == nullptr) 405 1.1.1.2 christos return scoped_fd (-ENOMEM); 406 1.1.1.2 christos 407 1.1.1.2 christos char *dname = nullptr; 408 1.1.1.3 christos scoped_fd fd; 409 1.1.1.3 christos std::optional<target_terminal::scoped_restore_terminal_state> term_state; 410 1.1.1.2 christos 411 1.1.1.3 christos { 412 1.1.1.3 christos user_data data ("executable for", filename); 413 1.1.1.2 christos 414 1.1.1.3 christos debuginfod_set_user_data (c, &data); 415 1.1.1.3 christos if (target_supports_terminal_ours ()) 416 1.1.1.3 christos { 417 1.1.1.3 christos term_state.emplace (); 418 1.1.1.3 christos target_terminal::ours (); 419 1.1.1.3 christos } 420 1.1.1.3 christos 421 1.1.1.3 christos fd = scoped_fd (debuginfod_find_executable (c, build_id, build_id_len, 422 1.1.1.3 christos &dname)); 423 1.1.1.3 christos debuginfod_set_user_data (c, nullptr); 424 1.1.1.3 christos } 425 1.1.1.3 christos 426 1.1.1.3 christos print_outcome (fd.get (), "executable for", filename); 427 1.1.1.2 christos 428 1.1.1.2 christos if (fd.get () >= 0) 429 1.1.1.2 christos destname->reset (dname); 430 1.1.1.2 christos 431 1.1.1.2 christos return fd; 432 1.1.1.2 christos } 433 1.1.1.3 christos 434 1.1.1.3 christos /* See debuginfod-support.h */ 435 1.1.1.3 christos 436 1.1.1.3 christos scoped_fd 437 1.1.1.3 christos debuginfod_section_query (const unsigned char *build_id, 438 1.1.1.3 christos int build_id_len, 439 1.1.1.3 christos const char *filename, 440 1.1.1.3 christos const char *section_name, 441 1.1.1.3 christos gdb::unique_xmalloc_ptr<char> *destname) 442 1.1.1.3 christos { 443 1.1.1.3 christos #if !defined (HAVE_LIBDEBUGINFOD_FIND_SECTION) 444 1.1.1.3 christos return scoped_fd (-ENOSYS); 445 1.1.1.3 christos #else 446 1.1.1.3 christos 447 1.1.1.3 christos if (!debuginfod_download_sections || !debuginfod_is_enabled ()) 448 1.1.1.3 christos return scoped_fd (-ENOSYS); 449 1.1.1.3 christos 450 1.1.1.3 christos debuginfod_client *c = get_debuginfod_client (); 451 1.1.1.3 christos 452 1.1.1.3 christos if (c == nullptr) 453 1.1.1.3 christos return scoped_fd (-ENOMEM); 454 1.1.1.3 christos 455 1.1.1.3 christos char *dname = nullptr; 456 1.1.1.3 christos std::string desc = std::string ("section ") + section_name + " for"; 457 1.1.1.3 christos scoped_fd fd; 458 1.1.1.3 christos std::optional<target_terminal::scoped_restore_terminal_state> term_state; 459 1.1.1.3 christos 460 1.1.1.3 christos { 461 1.1.1.3 christos user_data data (desc.c_str (), filename); 462 1.1.1.3 christos debuginfod_set_user_data (c, &data); 463 1.1.1.3 christos if (target_supports_terminal_ours ()) 464 1.1.1.3 christos { 465 1.1.1.3 christos term_state.emplace (); 466 1.1.1.3 christos target_terminal::ours (); 467 1.1.1.3 christos } 468 1.1.1.3 christos 469 1.1.1.3 christos fd = scoped_fd (debuginfod_find_section (c, build_id, build_id_len, 470 1.1.1.3 christos section_name, &dname)); 471 1.1.1.3 christos debuginfod_set_user_data (c, nullptr); 472 1.1.1.3 christos } 473 1.1.1.3 christos 474 1.1.1.3 christos print_outcome (fd.get (), desc.c_str (), filename); 475 1.1.1.3 christos gdb_assert (destname != nullptr); 476 1.1.1.3 christos 477 1.1.1.3 christos if (fd.get () >= 0) 478 1.1.1.3 christos destname->reset (dname); 479 1.1.1.3 christos 480 1.1.1.3 christos return fd; 481 1.1.1.3 christos #endif /* HAVE_LIBDEBUGINFOD_FIND_SECTION */ 482 1.1.1.3 christos } 483 1.1.1.3 christos 484 1.1.1.2 christos #endif 485 1.1.1.2 christos 486 1.1.1.2 christos /* Set callback for "set debuginfod enabled". */ 487 1.1.1.2 christos 488 1.1.1.2 christos static void 489 1.1.1.2 christos set_debuginfod_enabled (const char *value) 490 1.1.1.2 christos { 491 1.1.1.2 christos #if defined(HAVE_LIBDEBUGINFOD) 492 1.1.1.2 christos debuginfod_enabled = value; 493 1.1.1.2 christos #else 494 1.1.1.2 christos /* Disabling debuginfod when gdb is not built with it is a no-op. */ 495 1.1.1.2 christos if (value != debuginfod_off) 496 1.1.1.2 christos error (NO_IMPL); 497 1.1 christos #endif 498 1.1.1.2 christos } 499 1.1.1.2 christos 500 1.1.1.2 christos /* Get callback for "set debuginfod enabled". */ 501 1.1.1.2 christos 502 1.1.1.2 christos static const char * 503 1.1.1.2 christos get_debuginfod_enabled () 504 1.1.1.2 christos { 505 1.1.1.2 christos return debuginfod_enabled; 506 1.1.1.2 christos } 507 1.1.1.2 christos 508 1.1.1.2 christos /* Show callback for "set debuginfod enabled". */ 509 1.1.1.2 christos 510 1.1.1.2 christos static void 511 1.1.1.2 christos show_debuginfod_enabled (ui_file *file, int from_tty, cmd_list_element *cmd, 512 1.1.1.2 christos const char *value) 513 1.1.1.2 christos { 514 1.1.1.2 christos gdb_printf (file, 515 1.1.1.2 christos _("Debuginfod functionality is currently set to " 516 1.1.1.2 christos "\"%s\".\n"), debuginfod_enabled); 517 1.1.1.2 christos } 518 1.1.1.2 christos 519 1.1.1.2 christos /* Set callback for "set debuginfod urls". */ 520 1.1.1.2 christos 521 1.1.1.2 christos static void 522 1.1.1.2 christos set_debuginfod_urls (const std::string &urls) 523 1.1.1.2 christos { 524 1.1.1.2 christos #if defined(HAVE_LIBDEBUGINFOD) 525 1.1.1.2 christos if (setenv (DEBUGINFOD_URLS_ENV_VAR, urls.c_str (), 1) != 0) 526 1.1.1.2 christos warning (_("Unable to set debuginfod URLs: %s"), safe_strerror (errno)); 527 1.1.1.2 christos #else 528 1.1.1.2 christos error (NO_IMPL); 529 1.1.1.2 christos #endif 530 1.1.1.2 christos } 531 1.1.1.2 christos 532 1.1.1.2 christos /* Get callback for "set debuginfod urls". */ 533 1.1.1.2 christos 534 1.1.1.2 christos static const std::string& 535 1.1.1.2 christos get_debuginfod_urls () 536 1.1.1.2 christos { 537 1.1.1.2 christos static std::string urls; 538 1.1.1.2 christos #if defined(HAVE_LIBDEBUGINFOD) 539 1.1.1.2 christos const char *envvar = getenv (DEBUGINFOD_URLS_ENV_VAR); 540 1.1.1.2 christos 541 1.1.1.2 christos if (envvar != nullptr) 542 1.1.1.2 christos urls = envvar; 543 1.1.1.2 christos else 544 1.1.1.2 christos urls.clear (); 545 1.1.1.2 christos #endif 546 1.1.1.2 christos 547 1.1.1.2 christos return urls; 548 1.1.1.2 christos } 549 1.1.1.2 christos 550 1.1.1.2 christos /* Show callback for "set debuginfod urls". */ 551 1.1.1.2 christos 552 1.1.1.2 christos static void 553 1.1.1.2 christos show_debuginfod_urls (ui_file *file, int from_tty, cmd_list_element *cmd, 554 1.1.1.2 christos const char *value) 555 1.1.1.2 christos { 556 1.1.1.2 christos if (value[0] == '\0') 557 1.1.1.2 christos gdb_printf (file, _("Debuginfod URLs have not been set.\n")); 558 1.1.1.2 christos else 559 1.1.1.2 christos gdb_printf (file, _("Debuginfod URLs are currently set to:\n%s\n"), 560 1.1.1.2 christos value); 561 1.1.1.2 christos } 562 1.1.1.2 christos 563 1.1.1.2 christos /* Show callback for "set debuginfod verbose". */ 564 1.1.1.2 christos 565 1.1.1.2 christos static void 566 1.1.1.2 christos show_debuginfod_verbose_command (ui_file *file, int from_tty, 567 1.1.1.2 christos cmd_list_element *cmd, const char *value) 568 1.1.1.2 christos { 569 1.1.1.2 christos gdb_printf (file, _("Debuginfod verbose output is set to %s.\n"), 570 1.1.1.2 christos value); 571 1.1.1.2 christos } 572 1.1.1.2 christos 573 1.1.1.3 christos /* Set callback for "maint set debuginfod download-sections". */ 574 1.1.1.3 christos 575 1.1.1.3 christos static void 576 1.1.1.3 christos maint_set_debuginfod_download_sections (bool value) 577 1.1.1.3 christos { 578 1.1.1.3 christos #if !defined(HAVE_LIBDEBUGINFOD_FIND_SECTION) 579 1.1.1.3 christos if (value) 580 1.1.1.3 christos error (_("Support for section downloading is not compiled into GDB. " \ 581 1.1.1.3 christos "Defaulting to \"off\".")); 582 1.1.1.3 christos #endif 583 1.1.1.3 christos 584 1.1.1.3 christos debuginfod_download_sections = value; 585 1.1.1.3 christos } 586 1.1.1.3 christos 587 1.1.1.3 christos /* Get callback for "maint set debuginfod download-sections". */ 588 1.1.1.3 christos 589 1.1.1.3 christos static bool 590 1.1.1.3 christos maint_get_debuginfod_download_sections () 591 1.1.1.3 christos { 592 1.1.1.3 christos return debuginfod_download_sections; 593 1.1.1.3 christos } 594 1.1.1.3 christos 595 1.1.1.2 christos /* Register debuginfod commands. */ 596 1.1.1.2 christos 597 1.1.1.2 christos void _initialize_debuginfod (); 598 1.1.1.2 christos void 599 1.1.1.2 christos _initialize_debuginfod () 600 1.1.1.2 christos { 601 1.1.1.2 christos /* set/show debuginfod */ 602 1.1.1.2 christos add_setshow_prefix_cmd ("debuginfod", class_run, 603 1.1.1.2 christos _("Set debuginfod options."), 604 1.1.1.2 christos _("Show debuginfod options."), 605 1.1.1.2 christos &set_debuginfod_prefix_list, 606 1.1.1.2 christos &show_debuginfod_prefix_list, 607 1.1.1.2 christos &setlist, &showlist); 608 1.1.1.2 christos 609 1.1.1.2 christos add_setshow_enum_cmd ("enabled", class_run, debuginfod_enabled_enum, 610 1.1.1.2 christos _("Set whether to use debuginfod."), 611 1.1.1.2 christos _("Show whether to use debuginfod."), 612 1.1.1.2 christos _("\ 613 1.1.1.3 christos When set to \"on\", enable the use of debuginfod to download missing\n\ 614 1.1.1.3 christos debug info and source files. GDB may also download components of debug\n\ 615 1.1.1.3 christos info instead of entire files. \"off\" disables the use of debuginfod.\n\ 616 1.1.1.3 christos When set to \"ask\", prompt whether to enable or disable debuginfod." ), 617 1.1.1.2 christos set_debuginfod_enabled, 618 1.1.1.2 christos get_debuginfod_enabled, 619 1.1.1.2 christos show_debuginfod_enabled, 620 1.1.1.2 christos &set_debuginfod_prefix_list, 621 1.1.1.2 christos &show_debuginfod_prefix_list); 622 1.1.1.2 christos 623 1.1.1.2 christos /* set/show debuginfod urls */ 624 1.1.1.2 christos add_setshow_string_noescape_cmd ("urls", class_run, _("\ 625 1.1.1.2 christos Set the list of debuginfod server URLs."), _("\ 626 1.1.1.2 christos Show the list of debuginfod server URLs."), _("\ 627 1.1.1.2 christos Manage the space-separated list of debuginfod server URLs that GDB will query \ 628 1.1.1.2 christos when missing debuginfo, executables or source files.\nThe default value is \ 629 1.1.1.2 christos copied from the DEBUGINFOD_URLS environment variable."), 630 1.1.1.2 christos set_debuginfod_urls, 631 1.1.1.2 christos get_debuginfod_urls, 632 1.1.1.2 christos show_debuginfod_urls, 633 1.1.1.2 christos &set_debuginfod_prefix_list, 634 1.1.1.2 christos &show_debuginfod_prefix_list); 635 1.1.1.2 christos 636 1.1.1.2 christos /* set/show debuginfod verbose */ 637 1.1.1.2 christos add_setshow_zuinteger_cmd ("verbose", class_support, 638 1.1.1.2 christos &debuginfod_verbose, _("\ 639 1.1.1.2 christos Set verbosity of debuginfod output."), _("\ 640 1.1.1.2 christos Show debuginfod debugging."), _("\ 641 1.1.1.2 christos When set to a non-zero value, display verbose output for each debuginfod \ 642 1.1.1.2 christos query.\nTo disable, set to zero. Verbose output is displayed by default."), 643 1.1.1.2 christos nullptr, 644 1.1.1.2 christos show_debuginfod_verbose_command, 645 1.1.1.2 christos &set_debuginfod_prefix_list, 646 1.1.1.2 christos &show_debuginfod_prefix_list); 647 1.1.1.3 christos 648 1.1.1.3 christos /* maint set/show debuginfod. */ 649 1.1.1.3 christos add_setshow_prefix_cmd ("debuginfod", class_maintenance, 650 1.1.1.3 christos _("Set debuginfod specific variables."), 651 1.1.1.3 christos _("Show debuginfod specific variables."), 652 1.1.1.3 christos &maint_set_debuginfod_cmdlist, 653 1.1.1.3 christos &maint_show_debuginfod_cmdlist, 654 1.1.1.3 christos &maintenance_set_cmdlist, &maintenance_show_cmdlist); 655 1.1.1.3 christos 656 1.1.1.3 christos /* maint set/show debuginfod download-sections. */ 657 1.1.1.3 christos add_setshow_boolean_cmd ("download-sections", class_maintenance, _("\ 658 1.1.1.3 christos Set whether debuginfod may download individual ELF/DWARF sections."), _("\ 659 1.1.1.3 christos Show whether debuginfod may download individual ELF/DWARF sections."), _("\ 660 1.1.1.3 christos When enabled, debuginfod may attempt to download individual ELF/DWARF \ 661 1.1.1.3 christos sections from debug info files.\nIf disabled, only whole debug info files \ 662 1.1.1.3 christos may be downloaded."), 663 1.1.1.3 christos maint_set_debuginfod_download_sections, 664 1.1.1.3 christos maint_get_debuginfod_download_sections, 665 1.1.1.3 christos nullptr, 666 1.1.1.3 christos &maint_set_debuginfod_cmdlist, 667 1.1.1.3 christos &maint_show_debuginfod_cmdlist); 668 1.1.1.2 christos } 669