]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/debuginfod-support.c
Automatic date update in version.in
[thirdparty/binutils-gdb.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
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)
31 {
32 return scoped_fd (-ENOSYS);
33 }
34
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)
40 {
41 return scoped_fd (-ENOSYS);
42 }
43 #else
44 #include <elfutils/debuginfod.h>
45
46 /* TODO: Use debuginfod API extensions instead of these globals. */
47 static std::string desc;
48 static std::string fname;
49 static bool has_printed;
50
51 static int
52 progressfn (debuginfod_client *c, long cur, long total)
53 {
54 if (check_quit_flag ())
55 {
56 printf_filtered ("Cancelling download of %s %ps...\n",
57 desc.c_str (),
58 styled_string (file_name_style.style (), fname.c_str ()));
59 return 1;
60 }
61
62 if (!has_printed && total != 0)
63 {
64 /* Print this message only once. */
65 has_printed = true;
66 printf_filtered ("Downloading %s %ps...\n",
67 desc.c_str (),
68 styled_string (file_name_style.style (), fname.c_str ()));
69 }
70
71 return 0;
72 }
73
74 static debuginfod_client *
75 debuginfod_init ()
76 {
77 debuginfod_client *c = debuginfod_begin ();
78
79 if (c != nullptr)
80 debuginfod_set_progressfn (c, progressfn);
81
82 return c;
83 }
84
85 /* See debuginfod-support.h */
86
87 scoped_fd
88 debuginfod_source_query (const unsigned char *build_id,
89 int build_id_len,
90 const char *srcpath,
91 gdb::unique_xmalloc_ptr<char> *destname)
92 {
93 if (getenv (DEBUGINFOD_URLS_ENV_VAR) == NULL)
94 return scoped_fd (-ENOSYS);
95
96 debuginfod_client *c = debuginfod_init ();
97
98 if (c == nullptr)
99 return scoped_fd (-ENOMEM);
100
101 desc = std::string ("source file");
102 fname = std::string (srcpath);
103 has_printed = false;
104
105 scoped_fd fd (debuginfod_find_source (c,
106 build_id,
107 build_id_len,
108 srcpath,
109 nullptr));
110
111 /* TODO: Add 'set debug debuginfod' command to control when error messages are shown. */
112 if (fd.get () < 0 && fd.get () != -ENOENT)
113 printf_filtered (_("Download failed: %s. Continuing without source file %ps.\n"),
114 safe_strerror (-fd.get ()),
115 styled_string (file_name_style.style (), srcpath));
116 else
117 destname->reset (xstrdup (srcpath));
118
119 debuginfod_end (c);
120 return fd;
121 }
122
123 /* See debuginfod-support.h */
124
125 scoped_fd
126 debuginfod_debuginfo_query (const unsigned char *build_id,
127 int build_id_len,
128 const char *filename,
129 gdb::unique_xmalloc_ptr<char> *destname)
130 {
131 if (getenv (DEBUGINFOD_URLS_ENV_VAR) == NULL)
132 return scoped_fd (-ENOSYS);
133
134 debuginfod_client *c = debuginfod_init ();
135
136 if (c == nullptr)
137 return scoped_fd (-ENOMEM);
138
139 desc = std::string ("separate debug info for");
140 fname = std::string (filename);
141 has_printed = false;
142 char *dname = nullptr;
143
144 scoped_fd fd (debuginfod_find_debuginfo (c, build_id, build_id_len, &dname));
145
146 if (fd.get () < 0 && fd.get () != -ENOENT)
147 printf_filtered (_("Download failed: %s. Continuing without debug info for %ps.\n"),
148 safe_strerror (-fd.get ()),
149 styled_string (file_name_style.style (), filename));
150
151 destname->reset (dname);
152 debuginfod_end (c);
153 return fd;
154 }
155 #endif