gdb/riscv: Use legacy register numbers in default target description
[external/binutils.git] / gdb / common / common-exceptions.c
1 /* Exception (throw catch) mechanism, for GDB, the GNU debugger.
2
3    Copyright (C) 1986-2019 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
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.
11
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.
16
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/>.  */
19
20 #include "common-defs.h"
21 #include "common-exceptions.h"
22
23 const struct gdb_exception exception_none = { (enum return_reason) 0, GDB_NO_ERROR, NULL };
24
25 /* Possible catcher states.  */
26 enum catcher_state {
27   /* Initial state, a new catcher has just been created.  */
28   CATCHER_CREATED,
29   /* The catch code is running.  */
30   CATCHER_RUNNING,
31   CATCHER_RUNNING_1,
32   /* The catch code threw an exception.  */
33   CATCHER_ABORTING
34 };
35
36 /* Possible catcher actions.  */
37 enum catcher_action {
38   CATCH_ITER,
39   CATCH_ITER_1,
40   CATCH_THROWING
41 };
42
43 struct catcher
44 {
45   enum catcher_state state;
46   /* Jump buffer pointing back at the exception handler.  */
47   jmp_buf buf;
48   /* Status buffer belonging to the exception handler.  */
49   struct gdb_exception exception;
50   struct cleanup *saved_cleanup_chain;
51   /* Back link.  */
52   struct catcher *prev;
53 };
54
55 /* Where to go for throw_exception().  */
56 static struct catcher *current_catcher;
57
58 #if GDB_XCPT == GDB_XCPT_SJMP
59
60 /* Return length of current_catcher list.  */
61
62 static int
63 catcher_list_size (void)
64 {
65   int size;
66   struct catcher *catcher;
67
68   for (size = 0, catcher = current_catcher;
69        catcher != NULL;
70        catcher = catcher->prev)
71     ++size;
72
73   return size;
74 }
75
76 #endif
77
78 jmp_buf *
79 exceptions_state_mc_init (void)
80 {
81   struct catcher *new_catcher = XCNEW (struct catcher);
82
83   /* Start with no exception.  */
84   new_catcher->exception = exception_none;
85
86   /* Prevent error/quit during FUNC from calling cleanups established
87      prior to here.  */
88   new_catcher->saved_cleanup_chain = save_cleanups ();
89
90   /* Push this new catcher on the top.  */
91   new_catcher->prev = current_catcher;
92   current_catcher = new_catcher;
93   new_catcher->state = CATCHER_CREATED;
94
95   return &new_catcher->buf;
96 }
97
98 static void
99 catcher_pop (void)
100 {
101   struct catcher *old_catcher = current_catcher;
102
103   current_catcher = old_catcher->prev;
104
105   /* Restore the cleanup chain, the error/quit messages, and the uiout
106      builder, to their original states.  */
107
108   restore_cleanups (old_catcher->saved_cleanup_chain);
109
110   xfree (old_catcher);
111 }
112
113 /* Catcher state machine.  Returns non-zero if the m/c should be run
114    again, zero if it should abort.  */
115
116 static int
117 exceptions_state_mc (enum catcher_action action)
118 {
119   switch (current_catcher->state)
120     {
121     case CATCHER_CREATED:
122       switch (action)
123         {
124         case CATCH_ITER:
125           /* Allow the code to run the catcher.  */
126           current_catcher->state = CATCHER_RUNNING;
127           return 1;
128         default:
129           internal_error (__FILE__, __LINE__, _("bad state"));
130         }
131     case CATCHER_RUNNING:
132       switch (action)
133         {
134         case CATCH_ITER:
135           /* No error/quit has occured.  */
136           return 0;
137         case CATCH_ITER_1:
138           current_catcher->state = CATCHER_RUNNING_1;
139           return 1;
140         case CATCH_THROWING:
141           current_catcher->state = CATCHER_ABORTING;
142           /* See also throw_exception.  */
143           return 1;
144         default:
145           internal_error (__FILE__, __LINE__, _("bad switch"));
146         }
147     case CATCHER_RUNNING_1:
148       switch (action)
149         {
150         case CATCH_ITER:
151           /* The did a "break" from the inner while loop.  */
152           return 0;
153         case CATCH_ITER_1:
154           current_catcher->state = CATCHER_RUNNING;
155           return 0;
156         case CATCH_THROWING:
157           current_catcher->state = CATCHER_ABORTING;
158           /* See also throw_exception.  */
159           return 1;
160         default:
161           internal_error (__FILE__, __LINE__, _("bad switch"));
162         }
163     case CATCHER_ABORTING:
164       switch (action)
165         {
166         case CATCH_ITER:
167           {
168             /* Exit normally if this catcher can handle this
169                exception.  The caller analyses the func return
170                values.  */
171             return 0;
172           }
173         default:
174           internal_error (__FILE__, __LINE__, _("bad state"));
175         }
176     default:
177       internal_error (__FILE__, __LINE__, _("bad switch"));
178     }
179 }
180
181 int
182 exceptions_state_mc_catch (struct gdb_exception *exception,
183                            int mask)
184 {
185   *exception = current_catcher->exception;
186   catcher_pop ();
187
188   if (exception->reason < 0)
189     {
190       if (mask & RETURN_MASK (exception->reason))
191         {
192           /* Exit normally and let the caller handle the
193              exception.  */
194           return 1;
195         }
196
197       /* The caller didn't request that the event be caught, relay the
198          event to the next exception_catch/CATCH_SJLJ.  */
199       throw_exception_sjlj (*exception);
200     }
201
202   /* No exception was thrown.  */
203   return 0;
204 }
205
206 int
207 exceptions_state_mc_action_iter (void)
208 {
209   return exceptions_state_mc (CATCH_ITER);
210 }
211
212 int
213 exceptions_state_mc_action_iter_1 (void)
214 {
215   return exceptions_state_mc (CATCH_ITER_1);
216 }
217
218 #if GDB_XCPT != GDB_XCPT_SJMP
219
220 /* How many nested TRY blocks we have.  See exception_messages and
221    throw_it.  */
222
223 static int try_scope_depth;
224
225 /* Called on entry to a TRY scope.  */
226
227 void *
228 exception_try_scope_entry (void)
229 {
230   ++try_scope_depth;
231   return (void *) save_cleanups ();
232 }
233
234 /* Called on exit of a TRY scope, either normal exit or exception
235    exit.  */
236
237 void
238 exception_try_scope_exit (void *saved_state)
239 {
240   restore_cleanups ((struct cleanup *) saved_state);
241   --try_scope_depth;
242 }
243
244 /* Called by the default catch block.  IOW, we'll get here before
245    jumping out to the next outermost scope an exception if a GDB
246    exception is not caught.  */
247
248 void
249 exception_rethrow (void)
250 {
251   /* Run this scope's cleanups before re-throwing to the next
252      outermost scope.  */
253   do_cleanups (all_cleanups ());
254   throw;
255 }
256
257 /* Copy the 'gdb_exception' portion of FROM to TO.  */
258
259 static void
260 gdb_exception_sliced_copy (struct gdb_exception *to, const struct gdb_exception *from)
261 {
262   *to = *from;
263 }
264
265 #endif /* !GDB_XCPT_SJMP */
266
267 /* Return EXCEPTION to the nearest containing CATCH_SJLJ block.  */
268
269 void
270 throw_exception_sjlj (struct gdb_exception exception)
271 {
272   do_cleanups (all_cleanups ());
273
274   /* Jump to the nearest CATCH_SJLJ block, communicating REASON to
275      that call via setjmp's return value.  Note that REASON can't be
276      zero, by definition in common-exceptions.h.  */
277   exceptions_state_mc (CATCH_THROWING);
278   current_catcher->exception = exception;
279   longjmp (current_catcher->buf, exception.reason);
280 }
281
282 #if GDB_XCPT != GDB_XCPT_SJMP
283
284 /* Implementation of throw_exception that uses C++ try/catch.  */
285
286 static ATTRIBUTE_NORETURN void
287 throw_exception_cxx (struct gdb_exception exception)
288 {
289   do_cleanups (all_cleanups ());
290
291   if (exception.reason == RETURN_QUIT)
292     {
293       gdb_exception_RETURN_MASK_QUIT ex;
294
295       gdb_exception_sliced_copy (&ex, &exception);
296       throw ex;
297     }
298   else if (exception.reason == RETURN_ERROR)
299     {
300       gdb_exception_RETURN_MASK_ERROR ex;
301
302       gdb_exception_sliced_copy (&ex, &exception);
303       throw ex;
304     }
305   else
306     gdb_assert_not_reached ("invalid return reason");
307 }
308
309 #endif
310
311 void
312 throw_exception (struct gdb_exception exception)
313 {
314 #if GDB_XCPT == GDB_XCPT_SJMP
315   throw_exception_sjlj (exception);
316 #else
317   throw_exception_cxx (exception);
318 #endif
319 }
320
321 /* A stack of exception messages.
322    This is needed to handle nested calls to throw_it: we don't want to
323    xfree space for a message before it's used.
324    This can happen if we throw an exception during a cleanup:
325    An outer TRY_CATCH may have an exception message it wants to print,
326    but while doing cleanups further calls to throw_it are made.
327
328    This is indexed by the size of the current_catcher list.
329    It is a dynamically allocated array so that we don't care how deeply
330    GDB nests its TRY_CATCHs.  */
331 static char **exception_messages;
332
333 /* The number of currently allocated entries in exception_messages.  */
334 static int exception_messages_size;
335
336 static void ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 0)
337 throw_it (enum return_reason reason, enum errors error, const char *fmt,
338           va_list ap)
339 {
340   struct gdb_exception e;
341   char *new_message;
342 #if GDB_XCPT == GDB_XCPT_SJMP
343   int depth = catcher_list_size ();
344 #else
345   int depth = try_scope_depth;
346 #endif
347
348   gdb_assert (depth > 0);
349
350   /* Note: The new message may use an old message's text.  */
351   new_message = xstrvprintf (fmt, ap);
352
353   if (depth > exception_messages_size)
354     {
355       int old_size = exception_messages_size;
356
357       exception_messages_size = depth + 10;
358       exception_messages = XRESIZEVEC (char *, exception_messages,
359                                        exception_messages_size);
360       memset (exception_messages + old_size, 0,
361               (exception_messages_size - old_size) * sizeof (char *));
362     }
363
364   xfree (exception_messages[depth - 1]);
365   exception_messages[depth - 1] = new_message;
366
367   /* Create the exception.  */
368   e.reason = reason;
369   e.error = error;
370   e.message = new_message;
371
372   /* Throw the exception.  */
373   throw_exception (e);
374 }
375
376 void
377 throw_verror (enum errors error, const char *fmt, va_list ap)
378 {
379   throw_it (RETURN_ERROR, error, fmt, ap);
380 }
381
382 void
383 throw_vquit (const char *fmt, va_list ap)
384 {
385   throw_it (RETURN_QUIT, GDB_NO_ERROR, fmt, ap);
386 }
387
388 void
389 throw_error (enum errors error, const char *fmt, ...)
390 {
391   va_list args;
392
393   va_start (args, fmt);
394   throw_verror (error, fmt, args);
395   va_end (args);
396 }
397
398 void
399 throw_quit (const char *fmt, ...)
400 {
401   va_list args;
402
403   va_start (args, fmt);
404   throw_vquit (fmt, args);
405   va_end (args);
406 }