Automatic Copyright Year update after running gdb/copyright.py
[deliverable/binutils-gdb.git] / gdb / debuginfod-support.c
CommitLineData
0d79cdc4 1/* debuginfod utilities for GDB.
88b9d363 2 Copyright (C) 2020-2022 Free Software Foundation, Inc.
0d79cdc4
AM
3
4 This file is part of GDB.
5
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.
10
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.
15
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/>. */
18
0d79cdc4 19#include "defs.h"
a84bb2a0 20#include <errno.h>
0d79cdc4
AM
21#include "cli/cli-style.h"
22#include "gdbsupport/scoped_fd.h"
23#include "debuginfod-support.h"
d6f26c9d 24#include "gdbsupport/gdb_optional.h"
0d79cdc4
AM
25
26#ifndef HAVE_LIBDEBUGINFOD
27scoped_fd
28debuginfod_source_query (const unsigned char *build_id,
29 int build_id_len,
30 const char *srcpath,
31 gdb::unique_xmalloc_ptr<char> *destname)
32{
33 return scoped_fd (-ENOSYS);
34}
35
36scoped_fd
37debuginfod_debuginfo_query (const unsigned char *build_id,
38 int build_id_len,
39 const char *filename,
40 gdb::unique_xmalloc_ptr<char> *destname)
41{
42 return scoped_fd (-ENOSYS);
43}
44#else
45#include <elfutils/debuginfod.h>
46
002a3166
AM
47struct user_data
48{
49 user_data (const char *desc, const char *fname)
d6f26c9d 50 : desc (desc), fname (fname)
002a3166
AM
51 { }
52
53 const char * const desc;
54 const char * const fname;
d6f26c9d 55 gdb::optional<ui_out::progress_meter> meter;
002a3166 56};
0d79cdc4 57
d2b31b67
SM
58/* Deleter for a debuginfod_client. */
59
60struct debuginfod_client_deleter
61{
62 void operator() (debuginfod_client *c)
63 {
64 debuginfod_end (c);
65 }
66};
67
68using debuginfod_client_up
69 = std::unique_ptr<debuginfod_client, debuginfod_client_deleter>;
70
0d79cdc4
AM
71static int
72progressfn (debuginfod_client *c, long cur, long total)
73{
002a3166 74 user_data *data = static_cast<user_data *> (debuginfod_get_user_data (c));
1d1669e4 75 gdb_assert (data != nullptr);
002a3166 76
0d79cdc4
AM
77 if (check_quit_flag ())
78 {
79 printf_filtered ("Cancelling download of %s %ps...\n",
002a3166
AM
80 data->desc,
81 styled_string (file_name_style.style (), data->fname));
0d79cdc4
AM
82 return 1;
83 }
84
d6f26c9d
ML
85 if (total == 0)
86 return 0;
87
88 if (!data->meter.has_value ())
0d79cdc4 89 {
d6f26c9d
ML
90 float size_in_mb = 1.0f * total / (1024 * 1024);
91 string_file styled_filename (current_uiout->can_emit_style_escape ());
92 fprintf_styled (&styled_filename,
93 file_name_style.style (),
94 "%s",
95 data->fname);
96 std::string message
97 = string_printf ("Downloading %.2f MB %s %s", size_in_mb, data->desc,
98 styled_filename.c_str());
99 data->meter.emplace (current_uiout, message, 1);
0d79cdc4
AM
100 }
101
d6f26c9d
ML
102 current_uiout->progress ((double)cur / (double)total);
103
0d79cdc4
AM
104 return 0;
105}
106
1d1669e4
AM
107static debuginfod_client *
108get_debuginfod_client ()
0d79cdc4 109{
1d1669e4 110 static debuginfod_client_up global_client;
0d79cdc4 111
1d1669e4
AM
112 if (global_client == nullptr)
113 {
114 global_client.reset (debuginfod_begin ());
115
116 if (global_client != nullptr)
117 debuginfod_set_progressfn (global_client.get (), progressfn);
118 }
0d79cdc4 119
1d1669e4 120 return global_client.get ();
0d79cdc4
AM
121}
122
123/* See debuginfod-support.h */
124
125scoped_fd
126debuginfod_source_query (const unsigned char *build_id,
127 int build_id_len,
128 const char *srcpath,
129 gdb::unique_xmalloc_ptr<char> *destname)
130{
c44191f8
TV
131 const char *urls_env_var = getenv (DEBUGINFOD_URLS_ENV_VAR);
132 if (urls_env_var == NULL || urls_env_var[0] == '\0')
0d79cdc4
AM
133 return scoped_fd (-ENOSYS);
134
1d1669e4 135 debuginfod_client *c = get_debuginfod_client ();
0d79cdc4
AM
136
137 if (c == nullptr)
138 return scoped_fd (-ENOMEM);
139
002a3166 140 user_data data ("source file", srcpath);
0d79cdc4 141
1d1669e4
AM
142 debuginfod_set_user_data (c, &data);
143 scoped_fd fd (debuginfod_find_source (c,
0d79cdc4
AM
144 build_id,
145 build_id_len,
146 srcpath,
147 nullptr));
1d1669e4 148 debuginfod_set_user_data (c, nullptr);
0d79cdc4
AM
149
150 /* TODO: Add 'set debug debuginfod' command to control when error messages are shown. */
151 if (fd.get () < 0 && fd.get () != -ENOENT)
152 printf_filtered (_("Download failed: %s. Continuing without source file %ps.\n"),
153 safe_strerror (-fd.get ()),
154 styled_string (file_name_style.style (), srcpath));
d6ab69dd
TV
155
156 if (fd.get () >= 0)
3246bd8e 157 *destname = make_unique_xstrdup (srcpath);
0d79cdc4 158
0d79cdc4
AM
159 return fd;
160}
161
162/* See debuginfod-support.h */
163
164scoped_fd
165debuginfod_debuginfo_query (const unsigned char *build_id,
166 int build_id_len,
167 const char *filename,
168 gdb::unique_xmalloc_ptr<char> *destname)
169{
c44191f8
TV
170 const char *urls_env_var = getenv (DEBUGINFOD_URLS_ENV_VAR);
171 if (urls_env_var == NULL || urls_env_var[0] == '\0')
0d79cdc4
AM
172 return scoped_fd (-ENOSYS);
173
1d1669e4 174 debuginfod_client *c = get_debuginfod_client ();
0d79cdc4
AM
175
176 if (c == nullptr)
177 return scoped_fd (-ENOMEM);
178
0d79cdc4 179 char *dname = nullptr;
002a3166 180 user_data data ("separate debug info for", filename);
0d79cdc4 181
1d1669e4
AM
182 debuginfod_set_user_data (c, &data);
183 scoped_fd fd (debuginfod_find_debuginfo (c, build_id, build_id_len,
d2b31b67 184 &dname));
1d1669e4 185 debuginfod_set_user_data (c, nullptr);
0d79cdc4
AM
186
187 if (fd.get () < 0 && fd.get () != -ENOENT)
188 printf_filtered (_("Download failed: %s. Continuing without debug info for %ps.\n"),
189 safe_strerror (-fd.get ()),
190 styled_string (file_name_style.style (), filename));
191
d6ab69dd
TV
192 if (fd.get () >= 0)
193 destname->reset (dname);
d2b31b67 194
0d79cdc4
AM
195 return fd;
196}
197#endif
This page took 0.167944 seconds and 4 git commands to generate.