6a417412f4198f9b01df90d35dc47cf43df644b5
[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 <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.  */
126 #define GDB_XCPT_TRY 2
127
128 /* Specify this mode to build with TRY/CATCH mapped directly to raw
129    try/catch.  GDB won't work correctly, but building that way catches
130    code tryin to break/continue out of the try block, along with
131    spurious code between the TRY and the CATCH block.  */
132 #define GDB_XCPT_RAW_TRY 3
133
134 #ifdef __cplusplus
135 # define GDB_XCPT GDB_XCPT_TRY
136 #else
137 # define GDB_XCPT GDB_XCPT_SJMP
138 #endif
139
140 /* Functions to drive the exceptions state machine.  Though declared
141    here by necessity, these functions should be considered internal to
142    the exceptions subsystem and not used other than via the TRY/CATCH
143    macros defined below.  */
144
145 #if GDB_XCPT == GDB_XCPT_SJMP
146 extern jmp_buf *exceptions_state_mc_init (void);
147 extern int exceptions_state_mc_action_iter (void);
148 extern int exceptions_state_mc_action_iter_1 (void);
149 extern int exceptions_state_mc_catch (struct gdb_exception *, int);
150 #else
151 extern void *exception_try_scope_entry (void);
152 extern void exception_try_scope_exit (void *saved_state);
153 extern void exception_rethrow (void);
154 #endif
155
156 /* Macro to wrap up standard try/catch behavior.
157
158    The double loop lets us correctly handle code "break"ing out of the
159    try catch block.  (It works as the "break" only exits the inner
160    "while" loop, the outer for loop detects this handling it
161    correctly.)  Of course "return" and "goto" are not so lucky.
162
163    For instance:
164
165    *INDENT-OFF*
166
167    TRY
168      {
169      }
170    CATCH (e, RETURN_MASK_ERROR)
171      {
172        switch (e.reason)
173          {
174            case RETURN_ERROR: ...
175          }
176      }
177    END_CATCH
178
179   */
180
181 #if GDB_XCPT == GDB_XCPT_SJMP
182
183 #define TRY \
184      { \
185        jmp_buf *buf = \
186          exceptions_state_mc_init (); \
187        setjmp (*buf); \
188      } \
189      while (exceptions_state_mc_action_iter ()) \
190        while (exceptions_state_mc_action_iter_1 ())
191
192 #define CATCH(EXCEPTION, MASK)                          \
193   {                                                     \
194     struct gdb_exception EXCEPTION;                             \
195     if (exceptions_state_mc_catch (&(EXCEPTION), MASK))
196
197 #define END_CATCH                               \
198   }
199
200 #endif /* GDB_XCPT_SJMP */
201
202 #if GDB_XCPT == GDB_XCPT_TRY || GDB_XCPT == GDB_XCPT_RAW_TRY
203
204 /* Prevent error/quit during TRY from calling cleanups established
205    prior to here.  This pops out the scope in either case of normal
206    exit or exception exit.  */
207 struct exception_try_scope
208 {
209   exception_try_scope ()
210   {
211     saved_state = exception_try_scope_entry ();
212   }
213   ~exception_try_scope ()
214   {
215     exception_try_scope_exit (saved_state);
216   }
217
218   void *saved_state;
219 };
220
221 #if GDB_XCPT == GDB_XCPT_TRY
222
223 /* We still need to wrap TRY/CATCH in C++ so that cleanups and C++
224    exceptions can coexist.  The TRY blocked is wrapped in a
225    do/while(0) so that break/continue within the block works the same
226    as in C.  */
227 #define TRY                                                             \
228   try                                                                   \
229     {                                                                   \
230       exception_try_scope exception_try_scope_instance;                 \
231       do                                                                \
232         {
233
234 #define CATCH(EXCEPTION, MASK)                                          \
235         } while (0);                                                    \
236     }                                                                   \
237   catch (struct gdb_exception ## _ ## MASK &EXCEPTION)
238
239 #define END_CATCH                               \
240   catch (...)                                   \
241   {                                             \
242     exception_rethrow ();                       \
243   }
244
245 #else
246
247 #define TRY try
248 #define CATCH(EXCEPTION, MASK) \
249   catch (struct gdb_exception ## _ ## MASK &EXCEPTION)
250 #define END_CATCH
251
252 #endif
253
254 /* The exception types client code may catch.  They're just shims
255    around gdb_exception that add nothing but type info.  Which is used
256    is selected depending on the MASK argument passed to CATCH.  */
257
258 struct gdb_exception_RETURN_MASK_ALL : public gdb_exception
259 {
260 };
261
262 struct gdb_exception_RETURN_MASK_ERROR : public gdb_exception_RETURN_MASK_ALL
263 {
264 };
265
266 struct gdb_exception_RETURN_MASK_QUIT : public gdb_exception_RETURN_MASK_ALL
267 {
268 };
269
270 #endif /* GDB_XCPT_TRY || GDB_XCPT_RAW_TRY */
271
272 /* *INDENT-ON* */
273
274 /* Throw an exception (as described by "struct gdb_exception").  Will
275    execute a LONG JUMP to the inner most containing exception handler
276    established using catch_exceptions() (or similar).
277
278    Code normally throws an exception using error() et.al.  For various
279    reaons, GDB also contains code that throws an exception directly.
280    For instance, the remote*.c targets contain CNTRL-C signal handlers
281    that propogate the QUIT event up the exception chain.  ``This could
282    be a good thing or a dangerous thing.'' -- the Existential
283    Wombat.  */
284
285 extern void throw_exception (struct gdb_exception exception)
286      ATTRIBUTE_NORETURN;
287 extern void throw_verror (enum errors, const char *fmt, va_list ap)
288      ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 0);
289 extern void throw_vquit (const char *fmt, va_list ap)
290      ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 0);
291 extern void throw_error (enum errors error, const char *fmt, ...)
292      ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 3);
293 extern void throw_quit (const char *fmt, ...)
294      ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 2);
295
296 /* A pre-defined non-exception.  */
297 extern const struct gdb_exception exception_none;
298
299 #endif /* COMMON_EXCEPTIONS_H */