]> Git Repo - binutils.git/blob - gdb/debuginfod-support.c
gdb: move go_language class declaration into header file
[binutils.git] / gdb / debuginfod-support.c
1 /* debuginfod utilities for GDB.
2    Copyright (C) 2020 Free Software Foundation, Inc.
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
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"
24 #include "gdbsupport/gdb_optional.h"
25
26 #ifndef HAVE_LIBDEBUGINFOD
27 scoped_fd
28 debuginfod_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
36 scoped_fd
37 debuginfod_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
47 struct user_data
48 {
49   user_data (const char *desc, const char *fname)
50     : desc (desc), fname (fname)
51   { }
52
53   const char * const desc;
54   const char * const fname;
55   gdb::optional<ui_out::progress_meter> meter;
56 };
57
58 /* Deleter for a debuginfod_client.  */
59
60 struct debuginfod_client_deleter
61 {
62   void operator() (debuginfod_client *c)
63   {
64     debuginfod_end (c);
65   }
66 };
67
68 using debuginfod_client_up
69   = std::unique_ptr<debuginfod_client, debuginfod_client_deleter>;
70
71 static int
72 progressfn (debuginfod_client *c, long cur, long total)
73 {
74   user_data *data = static_cast<user_data *> (debuginfod_get_user_data (c));
75
76   if (check_quit_flag ())
77     {
78       printf_filtered ("Cancelling download of %s %ps...\n",
79                        data->desc,
80                        styled_string (file_name_style.style (), data->fname));
81       return 1;
82     }
83
84   if (total == 0)
85     return 0;
86
87   if (!data->meter.has_value ())
88     {
89       float size_in_mb = 1.0f * total / (1024 * 1024);
90       string_file styled_filename (current_uiout->can_emit_style_escape ());
91       fprintf_styled (&styled_filename,
92                       file_name_style.style (),
93                       "%s",
94                       data->fname);
95       std::string message
96         = string_printf ("Downloading %.2f MB %s %s", size_in_mb, data->desc,
97                          styled_filename.c_str());
98       data->meter.emplace (current_uiout, message, 1);
99     }
100
101   current_uiout->progress ((double)cur / (double)total);
102
103   return 0;
104 }
105
106 static debuginfod_client_up
107 debuginfod_init ()
108 {
109   debuginfod_client_up c (debuginfod_begin ());
110
111   if (c != nullptr)
112     debuginfod_set_progressfn (c.get (), progressfn);
113
114   return c;
115 }
116
117 /* See debuginfod-support.h  */
118
119 scoped_fd
120 debuginfod_source_query (const unsigned char *build_id,
121                          int build_id_len,
122                          const char *srcpath,
123                          gdb::unique_xmalloc_ptr<char> *destname)
124 {
125   const char *urls_env_var = getenv (DEBUGINFOD_URLS_ENV_VAR);
126   if (urls_env_var == NULL || urls_env_var[0] == '\0')
127     return scoped_fd (-ENOSYS);
128
129   debuginfod_client_up c = debuginfod_init ();
130
131   if (c == nullptr)
132     return scoped_fd (-ENOMEM);
133
134   user_data data ("source file", srcpath);
135
136   debuginfod_set_user_data (c.get (), &data);
137   scoped_fd fd (debuginfod_find_source (c.get (),
138                                         build_id,
139                                         build_id_len,
140                                         srcpath,
141                                         nullptr));
142
143   /* TODO: Add 'set debug debuginfod' command to control when error messages are shown.  */
144   if (fd.get () < 0 && fd.get () != -ENOENT)
145     printf_filtered (_("Download failed: %s.  Continuing without source file %ps.\n"),
146                      safe_strerror (-fd.get ()),
147                      styled_string (file_name_style.style (),  srcpath));
148
149   if (fd.get () >= 0)
150     *destname = make_unique_xstrdup (srcpath);
151
152   return fd;
153 }
154
155 /* See debuginfod-support.h  */
156
157 scoped_fd
158 debuginfod_debuginfo_query (const unsigned char *build_id,
159                             int build_id_len,
160                             const char *filename,
161                             gdb::unique_xmalloc_ptr<char> *destname)
162 {
163   const char *urls_env_var = getenv (DEBUGINFOD_URLS_ENV_VAR);
164   if (urls_env_var == NULL || urls_env_var[0] == '\0')
165     return scoped_fd (-ENOSYS);
166
167   debuginfod_client_up c = debuginfod_init ();
168
169   if (c == nullptr)
170     return scoped_fd (-ENOMEM);
171
172   char *dname = nullptr;
173   user_data data ("separate debug info for", filename);
174
175   debuginfod_set_user_data (c.get (), &data);
176   scoped_fd fd (debuginfod_find_debuginfo (c.get (), build_id, build_id_len,
177                                            &dname));
178
179   if (fd.get () < 0 && fd.get () != -ENOENT)
180     printf_filtered (_("Download failed: %s.  Continuing without debug info for %ps.\n"),
181                      safe_strerror (-fd.get ()),
182                      styled_string (file_name_style.style (),  filename));
183
184   if (fd.get () >= 0)
185     destname->reset (dname);
186
187   return fd;
188 }
189 #endif
This page took 0.038943 seconds and 4 git commands to generate.