arm, objdump: print obsolote warning when 26-bit set in instructions
[binutils-gdb.git] / gdb / mingw-hdep.c
blob53815b2f683ed8da16b0eb080c04c528a79bf7e1
1 /* Host support routines for MinGW, for GDB, the GNU debugger.
3 Copyright (C) 2006-2024 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 #include "main.h"
21 #include "serial.h"
22 #include "gdbsupport/event-loop.h"
23 #include "gdbsupport/gdb_select.h"
24 #include "inferior.h"
26 #include <windows.h>
27 #include <signal.h>
29 /* Return an absolute file name of the running GDB, if possible, or
30 ARGV0 if not. The return value is in malloc'ed storage. */
32 char *
33 windows_get_absolute_argv0 (const char *argv0)
35 char full_name[PATH_MAX];
37 if (GetModuleFileName (NULL, full_name, PATH_MAX))
38 return xstrdup (full_name);
39 return xstrdup (argv0);
42 /* Wrapper for select. On Windows systems, where the select interface
43 only works for sockets, this uses the GDB serial abstraction to
44 handle sockets, consoles, pipes, and serial ports.
46 The arguments to this function are the same as the traditional
47 arguments to select on POSIX platforms. */
49 int
50 gdb_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
51 struct timeval *timeout)
53 static HANDLE never_handle;
54 HANDLE handles[MAXIMUM_WAIT_OBJECTS];
55 HANDLE h;
56 DWORD event;
57 DWORD num_handles;
58 /* SCBS contains serial control objects corresponding to file
59 descriptors in READFDS and WRITEFDS. */
60 struct serial *scbs[MAXIMUM_WAIT_OBJECTS];
61 /* The number of valid entries in SCBS. */
62 size_t num_scbs;
63 int fd;
64 int num_ready;
65 size_t indx;
67 if (n == 0)
69 /* The MS API says that the first argument to
70 WaitForMultipleObjects cannot be zero. That's why we just
71 use a regular Sleep here. */
72 if (timeout != NULL)
73 Sleep (timeout->tv_sec * 1000 + timeout->tv_usec / 1000);
75 return 0;
78 num_ready = 0;
79 num_handles = 0;
80 num_scbs = 0;
81 for (fd = 0; fd < n; ++fd)
83 HANDLE read = NULL, except = NULL;
84 struct serial *scb;
86 /* There is no support yet for WRITEFDS. At present, this isn't
87 used by GDB -- but we do not want to silently ignore WRITEFDS
88 if something starts using it. */
89 gdb_assert (!writefds || !FD_ISSET (fd, writefds));
91 if ((!readfds || !FD_ISSET (fd, readfds))
92 && (!exceptfds || !FD_ISSET (fd, exceptfds)))
93 continue;
95 scb = serial_for_fd (fd);
96 if (scb)
98 serial_wait_handle (scb, &read, &except);
99 scbs[num_scbs++] = scb;
102 if (read == NULL)
103 read = (HANDLE) _get_osfhandle (fd);
104 if (except == NULL)
106 if (!never_handle)
107 never_handle = CreateEvent (0, FALSE, FALSE, 0);
109 except = never_handle;
112 if (readfds && FD_ISSET (fd, readfds))
114 gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
115 handles[num_handles++] = read;
118 if (exceptfds && FD_ISSET (fd, exceptfds))
120 gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
121 handles[num_handles++] = except;
125 gdb_assert (num_handles <= MAXIMUM_WAIT_OBJECTS);
127 event = WaitForMultipleObjects (num_handles,
128 handles,
129 FALSE,
130 timeout
131 ? (timeout->tv_sec * 1000
132 + timeout->tv_usec / 1000)
133 : INFINITE);
134 /* EVENT can only be a value in the WAIT_ABANDONED_0 range if the
135 HANDLES included an abandoned mutex. Since GDB doesn't use
136 mutexes, that should never occur. */
137 gdb_assert (!(WAIT_ABANDONED_0 <= event
138 && event < WAIT_ABANDONED_0 + num_handles));
139 /* We no longer need the helper threads to check for activity. */
140 for (indx = 0; indx < num_scbs; ++indx)
141 serial_done_wait_handle (scbs[indx]);
142 if (event == WAIT_FAILED)
143 return -1;
144 if (event == WAIT_TIMEOUT)
145 return 0;
146 /* Run through the READFDS, clearing bits corresponding to descriptors
147 for which input is unavailable. */
148 h = handles[event - WAIT_OBJECT_0];
149 for (fd = 0, indx = 0; fd < n; ++fd)
151 HANDLE fd_h;
153 if ((!readfds || !FD_ISSET (fd, readfds))
154 && (!exceptfds || !FD_ISSET (fd, exceptfds)))
155 continue;
157 if (readfds && FD_ISSET (fd, readfds))
159 fd_h = handles[indx++];
160 /* This handle might be ready, even though it wasn't the handle
161 returned by WaitForMultipleObjects. */
162 if (fd_h != h && WaitForSingleObject (fd_h, 0) != WAIT_OBJECT_0)
163 FD_CLR (fd, readfds);
164 else
165 num_ready++;
168 if (exceptfds && FD_ISSET (fd, exceptfds))
170 fd_h = handles[indx++];
171 /* This handle might be ready, even though it wasn't the handle
172 returned by WaitForMultipleObjects. */
173 if (fd_h != h && WaitForSingleObject (fd_h, 0) != WAIT_OBJECT_0)
174 FD_CLR (fd, exceptfds);
175 else
176 num_ready++;
180 return num_ready;
183 /* Map COLOR's RGB triplet, with 8 bits per component, into 16 Windows
184 console colors, where each component has just 1 bit, plus a single
185 intensity bit which affects all 3 components. */
186 static int
187 rgb_to_16colors (const ui_file_style::color &color)
189 uint8_t rgb[3];
190 color.get_rgb (rgb);
192 int retval = 0;
193 for (int i = 0; i < 3; i++)
195 /* Subdivide 256 possible values of each RGB component into 3
196 regions: no color, normal color, bright color. 256 / 3 = 85,
197 but ui-style.c follows xterm and uses 92 for R and G
198 components of the bright-blue color, so we bias the divisor a
199 bit to have the bright colors between 9 and 15 identical to
200 what ui-style.c expects. */
201 int bits = rgb[i] / 93;
202 retval |= ((bits > 0) << (2 - i)) | ((bits > 1) << 3);
205 return retval;
208 /* Zero if not yet initialized, 1 if stdout is a console device, else -1. */
209 static int mingw_console_initialized;
211 /* Handle to stdout . */
212 static HANDLE hstdout = INVALID_HANDLE_VALUE;
214 /* Text attribute to use for normal text (the "none" pseudo-color). */
215 static SHORT norm_attr;
217 /* The most recently applied style. */
218 static ui_file_style last_style;
220 /* Alternative for the libc 'fputs' which handles embedded SGR
221 sequences in support of styling. */
224 gdb_console_fputs (const char *linebuf, FILE *fstream)
226 if (!mingw_console_initialized)
228 hstdout = (HANDLE)_get_osfhandle (fileno (fstream));
229 DWORD cmode;
230 CONSOLE_SCREEN_BUFFER_INFO csbi;
232 if (hstdout != INVALID_HANDLE_VALUE
233 && GetConsoleMode (hstdout, &cmode) != 0
234 && GetConsoleScreenBufferInfo (hstdout, &csbi))
236 norm_attr = csbi.wAttributes;
237 mingw_console_initialized = 1;
239 else if (hstdout != INVALID_HANDLE_VALUE)
240 mingw_console_initialized = -1; /* valid, but not a console device */
242 /* If our stdout is not a console device, let the default 'fputs'
243 handle the task. */
244 if (mingw_console_initialized <= 0)
245 return 0;
247 /* Mapping between 8 ANSI colors and Windows console attributes. */
248 static int fg_color[] = {
249 0, /* black */
250 FOREGROUND_RED, /* red */
251 FOREGROUND_GREEN, /* green */
252 FOREGROUND_GREEN | FOREGROUND_RED, /* yellow */
253 FOREGROUND_BLUE, /* blue */
254 FOREGROUND_BLUE | FOREGROUND_RED, /* magenta */
255 FOREGROUND_BLUE | FOREGROUND_GREEN, /* cyan */
256 FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE /* gray */
258 static int bg_color[] = {
259 0, /* black */
260 BACKGROUND_RED, /* red */
261 BACKGROUND_GREEN, /* green */
262 BACKGROUND_GREEN | BACKGROUND_RED, /* yellow */
263 BACKGROUND_BLUE, /* blue */
264 BACKGROUND_BLUE | BACKGROUND_RED, /* magenta */
265 BACKGROUND_BLUE | BACKGROUND_GREEN, /* cyan */
266 BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE /* gray */
269 ui_file_style style = last_style;
270 unsigned char c;
271 size_t n_read;
273 for ( ; (c = *linebuf) != 0; linebuf += n_read)
275 if (c == '\033')
277 fflush (fstream);
278 bool parsed = style.parse (linebuf, &n_read);
279 if (n_read <= 0) /* should never happen */
280 n_read = 1;
281 if (!parsed)
283 /* This means we silently swallow SGR sequences we
284 cannot parse. */
285 continue;
287 /* Colors. */
288 const ui_file_style::color &fg = style.get_foreground ();
289 const ui_file_style::color &bg = style.get_background ();
290 int fgcolor, bgcolor, bright, inverse;
291 if (fg.is_none ())
292 fgcolor = norm_attr & 15;
293 else if (fg.is_basic ())
294 fgcolor = fg_color[fg.get_value () & 15];
295 else
296 fgcolor = rgb_to_16colors (fg);
297 if (bg.is_none ())
298 bgcolor = norm_attr & (15 << 4);
299 else if (bg.is_basic ())
300 bgcolor = bg_color[bg.get_value () & 15];
301 else
302 bgcolor = rgb_to_16colors (bg) << 4;
304 /* Intensity. */
305 switch (style.get_intensity ())
307 case ui_file_style::NORMAL:
308 case ui_file_style::DIM:
309 bright = 0;
310 break;
311 case ui_file_style::BOLD:
312 bright = 1;
313 break;
314 default:
315 gdb_assert_not_reached ("invalid intensity");
318 /* Inverse video. */
319 if (style.is_reverse ())
320 inverse = 1;
321 else
322 inverse = 0;
324 /* Construct the attribute. */
325 if (inverse)
327 int t = fgcolor;
328 fgcolor = (bgcolor >> 4);
329 bgcolor = (t << 4);
331 if (bright)
332 fgcolor |= FOREGROUND_INTENSITY;
334 SHORT attr = (bgcolor & (15 << 4)) | (fgcolor & 15);
336 /* Apply the attribute. */
337 SetConsoleTextAttribute (hstdout, attr);
339 else
341 /* When we are about to write newline, we need to clear to
342 EOL with the normal attribute, to avoid spilling the
343 colors to the next screen line. We assume here that no
344 non-default attribute extends beyond the newline. */
345 if (c == '\n')
347 DWORD nchars;
348 COORD start_pos;
349 DWORD written;
350 CONSOLE_SCREEN_BUFFER_INFO csbi;
352 fflush (fstream);
353 GetConsoleScreenBufferInfo (hstdout, &csbi);
355 if (csbi.wAttributes != norm_attr)
357 start_pos = csbi.dwCursorPosition;
358 nchars = csbi.dwSize.X - start_pos.X;
360 FillConsoleOutputAttribute (hstdout, norm_attr, nchars,
361 start_pos, &written);
362 FillConsoleOutputCharacter (hstdout, ' ', nchars,
363 start_pos, &written);
366 fputc (c, fstream);
367 n_read = 1;
371 last_style = style;
372 return 1;
375 /* See inferior.h. */
377 tribool
378 sharing_input_terminal (int pid)
380 std::vector<DWORD> results (10);
381 DWORD len = 0;
382 while (true)
384 len = GetConsoleProcessList (results.data (), results.size ());
385 /* Note that LEN == 0 is a failure, but we can treat it the same
386 as a "no". */
387 if (len <= results.size ())
388 break;
390 results.resize (len);
392 /* In case the vector was too big. */
393 results.resize (len);
394 if (std::find (results.begin (), results.end (), pid) != results.end ())
396 /* The pid is in the list sharing the console, so don't
397 interrupt the inferior -- it will get the signal itself. */
398 return TRIBOOL_TRUE;
401 return TRIBOOL_FALSE;
404 /* Current C-c handler. */
405 static c_c_handler_ftype *current_handler;
407 /* The Windows callback that forwards requests to the C-c handler. */
408 static BOOL WINAPI
409 ctrl_c_handler (DWORD event_type)
411 if (event_type == CTRL_BREAK_EVENT || event_type == CTRL_C_EVENT)
413 if (current_handler != SIG_IGN)
414 current_handler (SIGINT);
416 else
417 return FALSE;
418 return TRUE;
421 /* See inferior.h. */
423 c_c_handler_ftype *
424 install_sigint_handler (c_c_handler_ftype *fn)
426 /* We want to make sure the gdb handler always comes first, so that
427 gdb gets to handle the C-c. This is why the handler is always
428 removed and reinstalled here. Note that trying to remove the
429 function without installing it first will cause a crash. */
430 static bool installed = false;
431 if (installed)
432 SetConsoleCtrlHandler (ctrl_c_handler, FALSE);
433 SetConsoleCtrlHandler (ctrl_c_handler, TRUE);
434 installed = true;
436 c_c_handler_ftype *result = current_handler;
437 current_handler = fn;
438 return result;