Eliminate prepare_to_throw_exception
[external/binutils.git] / gdb / common / common-exceptions.h
1 /* Exception (throw catch) mechanism, for GDB, the GNU debugger.
2
3    Copyright (C) 1986-2016 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 #ifndef COMMON_EXCEPTIONS_H
21 #define COMMON_EXCEPTIONS_H
22
23 #include "gdb_setjmp.h"
24
25 /* Reasons for calling throw_exceptions().  NOTE: all reason values
26    must be less than zero.  enum value 0 is reserved for internal use
27    as the return value from an initial setjmp().  The function
28    catch_exceptions() reserves values >= 0 as legal results from its
29    wrapped function.  */
30
31 enum return_reason
32   {
33     /* User interrupt.  */
34     RETURN_QUIT = -2,
35     /* Any other error.  */
36     RETURN_ERROR
37   };
38
39 #define RETURN_MASK(reason)     (1 << (int)(-reason))
40
41 typedef enum
42 {
43   RETURN_MASK_QUIT = RETURN_MASK (RETURN_QUIT),
44   RETURN_MASK_ERROR = RETURN_MASK (RETURN_ERROR),
45   RETURN_MASK_ALL = (RETURN_MASK_QUIT | RETURN_MASK_ERROR)
46 } return_mask;
47
48 /* Describe all exceptions.  */
49
50 enum errors {
51   GDB_NO_ERROR,
52
53   /* Any generic error, the corresponding text is in
54      exception.message.  */
55   GENERIC_ERROR,
56
57   /* Something requested was not found.  */
58   NOT_FOUND_ERROR,
59
60   /* Thread library lacks support necessary for finding thread local
61      storage.  */
62   TLS_NO_LIBRARY_SUPPORT_ERROR,
63
64   /* Load module not found while attempting to find thread local storage.  */
65   TLS_LOAD_MODULE_NOT_FOUND_ERROR,
66
67   /* Thread local storage has not been allocated yet.  */
68   TLS_NOT_ALLOCATED_YET_ERROR,
69
70   /* Something else went wrong while attempting to find thread local
71      storage.  The ``struct gdb_exception'' message field provides
72      more detail.  */
73   TLS_GENERIC_ERROR,
74
75   /* Problem parsing an XML document.  */
76   XML_PARSE_ERROR,
77
78   /* Error accessing memory.  */
79   MEMORY_ERROR,
80
81   /* Value not available.  E.g., a register was not collected in a
82      traceframe.  */
83   NOT_AVAILABLE_ERROR,
84
85   /* Value was optimized out.  Note: if the value was a register, this
86      means the register was not saved in the frame.  */
87   OPTIMIZED_OUT_ERROR,
88
89   /* DW_OP_GNU_entry_value resolving failed.  */
90   NO_ENTRY_VALUE_ERROR,
91
92   /* Target throwing an error has been closed.  Current command should be
93      aborted as the inferior state is no longer valid.  */
94   TARGET_CLOSE_ERROR,
95
96   /* An undefined command was executed.  */
97   UNDEFINED_COMMAND_ERROR,
98
99   /* Requested feature, method, mechanism, etc. is not supported.  */
100   NOT_SUPPORTED_ERROR,
101
102   /* The number of candidates generated during line completion has
103      reached the user's specified limit.  This isn't an error, this exception
104      is used to halt searching for more completions, but for consistency
105      "_ERROR" is appended to the name.  */
106   MAX_COMPLETIONS_REACHED_ERROR,
107
108   /* Add more errors here.  */
109   NR_ERRORS
110 };
111
112 struct gdb_exception
113 {
114   enum return_reason reason;
115   enum errors error;
116   const char *message;
117 };
118
119 /* The different exception mechanisms that TRY/CATCH can map to.  */
120
121 /* Make GDB exceptions use setjmp/longjmp behind the scenes.  This is
122    the only mode supported when GDB is built as a C program.  */
123 #define GDB_XCPT_SJMP 1
124
125 /* Make GDB exceptions use try/catch behind the scenes.  Can't be made
126    the default until we stop throwing exceptions from signal
127    handlers.  */
128 #define GDB_XCPT_TRY 2
129
130 /* Specify this mode to build with TRY/CATCH mapped directly to raw
131    try/catch.  GDB won't work correctly, but building that way catches
132    code tryin to break/continue out of the try block, along with
133    spurious code between the TRY and the CATCH block.  */
134 #define GDB_XCPT_RAW_TRY 3
135
136 /* Always use setjmp/longmp, even in C++ mode.  */
137 #define GDB_XCPT GDB_XCPT_SJMP
138
139 /* Functions to drive the exceptions state machine.  Though declared
140    here by necessity, these functions should be considered internal to
141    the exceptions subsystem and not used other than via the TRY/CATCH
142    macros defined below.  */
143
144 #if GDB_XCPT == GDB_XCPT_SJMP
145 extern SIGJMP_BUF *exceptions_state_mc_init (void);
146 extern int exceptions_state_mc_action_iter (void);
147 extern int exceptions_state_mc_action_iter_1 (void);
148 extern int exceptions_state_mc_catch (struct gdb_exception *, int);
149 #else
150 extern void *exception_try_scope_entry (void);
151 extern void exception_try_scope_exit (void *saved_state);
152 extern void exception_rethrow (void);
153 #endif
154
155 /* Macro to wrap up standard try/catch behavior.
156
157    The double loop lets us correctly handle code "break"ing out of the
158    try catch block.  (It works as the "break" only exits the inner
159    "while" loop, the outer for loop detects this handling it
160    correctly.)  Of course "return" and "goto" are not so lucky.
161
162    For instance:
163
164    *INDENT-OFF*
165
166    TRY
167      {
168      }
169    CATCH (e, RETURN_MASK_ERROR)
170      {
171        switch (e.reason)
172          {
173            case RETURN_ERROR: ...
174          }
175      }
176    END_CATCH
177
178   */
179
180 #if GDB_XCPT == GDB_XCPT_SJMP
181
182 #define TRY \
183      { \
184        SIGJMP_BUF *buf = \
185          exceptions_state_mc_init (); \
186        SIGSETJMP (*buf); \
187      } \
188      while (exceptions_state_mc_action_iter ()) \
189        while (exceptions_state_mc_action_iter_1 ())
190
191 #define CATCH(EXCEPTION, MASK)                          \
192   {                                                     \
193     struct gdb_exception EXCEPTION;                             \
194     if (exceptions_state_mc_catch (&(EXCEPTION), MASK))
195
196 #define END_CATCH                               \
197   }
198
199 #endif /* GDB_XCPT_SJMP */
200
201 #if GDB_XCPT == GDB_XCPT_TRY || GDB_XCPT == GDB_XCPT_RAW_TRY
202
203 /* Prevent error/quit during TRY from calling cleanups established
204    prior to here.  This pops out the scope in either case of normal
205    exit or exception exit.  */
206 struct exception_try_scope
207 {
208   exception_try_scope ()
209   {
210     saved_state = exception_try_scope_entry ();
211   }
212   ~exception_try_scope ()
213   {
214     exception_try_scope_exit (saved_state);
215   }
216
217   void *saved_state;
218 };
219
220 #if GDB_XCPT == GDB_XCPT_TRY
221
222 /* We still need to wrap TRY/CATCH in C++ so that cleanups and C++
223    exceptions can coexist.  The TRY blocked is wrapped in a
224    do/while(0) so that break/continue within the block works the same
225    as in C.  */
226 #define TRY                                                             \
227   try                                                                   \
228     {                                                                   \
229       exception_try_scope exception_try_scope_instance;                 \
230       do                                                                \
231         {
232
233 #define CATCH(EXCEPTION, MASK)                                          \
234         } while (0);                                                    \
235     }                                                                   \
236   catch (struct gdb_exception ## _ ## MASK &EXCEPTION)
237
238 #define END_CATCH                               \
239   catch (...)                                   \
240   {                                             \
241     exception_rethrow ();                       \
242   }
243
244 #else
245
246 #define TRY try
247 #define CATCH(EXCEPTION, MASK) \
248   catch (struct gdb_exception ## _ ## MASK &EXCEPTION)
249 #define END_CATCH
250
251 #endif
252
253 /* The exception types client code may catch.  They're just shims
254    around gdb_exception that add nothing but type info.  Which is used
255    is selected depending on the MASK argument passed to CATCH.  */
256
257 struct gdb_exception_RETURN_MASK_ALL : public gdb_exception
258 {
259 };
260
261 struct gdb_exception_RETURN_MASK_ERROR : public gdb_exception_RETURN_MASK_ALL
262 {
263 };
264
265 struct gdb_exception_RETURN_MASK_QUIT : public gdb_exception_RETURN_MASK_ALL
266 {
267 };
268
269 #endif /* GDB_XCPT_TRY || GDB_XCPT_RAW_TRY */
270
271 /* *INDENT-ON* */
272
273 /* Throw an exception (as described by "struct gdb_exception").  Will
274    execute a LONG JUMP to the inner most containing exception handler
275    established using catch_exceptions() (or similar).
276
277    Code normally throws an exception using error() et.al.  For various
278    reaons, GDB also contains code that throws an exception directly.
279    For instance, the remote*.c targets contain CNTRL-C signal handlers
280    that propogate the QUIT event up the exception chain.  ``This could
281    be a good thing or a dangerous thing.'' -- the Existential
282    Wombat.  */
283
284 extern void throw_exception (struct gdb_exception exception)
285      ATTRIBUTE_NORETURN;
286 extern void throw_verror (enum errors, const char *fmt, va_list ap)
287      ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 0);
288 extern void throw_vquit (const char *fmt, va_list ap)
289      ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 0);
290 extern void throw_error (enum errors error, const char *fmt, ...)
291      ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 3);
292 extern void throw_quit (const char *fmt, ...)
293      ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 2);
294
295 /* A pre-defined non-exception.  */
296 extern const struct gdb_exception exception_none;
297
298 #endif /* COMMON_EXCEPTIONS_H */