change and rename gmp_string_asprintf to return an std::string
[binutils-gdb.git] / gdb / debuginfod-support.c
blobe21b2f40caee107c802b997d10da749d1d9be431
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/>. */
19 #include "defs.h"
20 #include <errno.h>
21 #include "cli/cli-style.h"
22 #include "gdbsupport/scoped_fd.h"
23 #include "debuginfod-support.h"
25 #ifndef HAVE_LIBDEBUGINFOD
26 scoped_fd
27 debuginfod_source_query (const unsigned char *build_id,
28 int build_id_len,
29 const char *srcpath,
30 gdb::unique_xmalloc_ptr<char> *destname)
32 return scoped_fd (-ENOSYS);
35 scoped_fd
36 debuginfod_debuginfo_query (const unsigned char *build_id,
37 int build_id_len,
38 const char *filename,
39 gdb::unique_xmalloc_ptr<char> *destname)
41 return scoped_fd (-ENOSYS);
43 #else
44 #include <elfutils/debuginfod.h>
46 struct user_data
48 user_data (const char *desc, const char *fname)
49 : desc (desc), fname (fname), has_printed (false)
50 { }
52 const char * const desc;
53 const char * const fname;
54 bool has_printed;
57 /* Deleter for a debuginfod_client. */
59 struct debuginfod_client_deleter
61 void operator() (debuginfod_client *c)
63 debuginfod_end (c);
67 using debuginfod_client_up
68 = std::unique_ptr<debuginfod_client, debuginfod_client_deleter>;
70 static int
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",
78 data->desc,
79 styled_string (file_name_style.style (), data->fname));
80 return 1;
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",
88 data->desc,
89 styled_string (file_name_style.style (), data->fname));
92 return 0;
95 static debuginfod_client_up
96 debuginfod_init ()
98 debuginfod_client_up c (debuginfod_begin ());
100 if (c != nullptr)
101 debuginfod_set_progressfn (c.get (), progressfn);
103 return c;
106 /* See debuginfod-support.h */
108 scoped_fd
109 debuginfod_source_query (const unsigned char *build_id,
110 int build_id_len,
111 const char *srcpath,
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 ();
120 if (c == nullptr)
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 (),
127 build_id,
128 build_id_len,
129 srcpath,
130 nullptr));
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));
138 if (fd.get () >= 0)
139 *destname = make_unique_xstrdup (srcpath);
141 return fd;
144 /* See debuginfod-support.h */
146 scoped_fd
147 debuginfod_debuginfo_query (const unsigned char *build_id,
148 int build_id_len,
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 ();
158 if (c == nullptr)
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,
166 &dname));
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));
173 if (fd.get () >= 0)
174 destname->reset (dname);
176 return fd;
178 #endif