~ubuntu-branches/ubuntu/vivid/emscripten/vivid-proposed

« back to all changes in this revision

Viewing changes to system/lib/libcxxabi/src/Unwind/UnwindLevel1.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2014-01-19 14:12:40 UTC
  • mfrom: (4.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20140119141240-nfiw0p8033oitpfz
Tags: 1.9.0~20140119~7dc8c2f-1
* New snapshot release (Closes: #733714)
* Provide sources for javascript and flash. Done in orig-tar.sh
  Available in third_party/websockify/include/web-socket-js/src/
  (Closes: #735903)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//===------------------------- UnwindLevel1.c -----------------------------===//
 
2
//
 
3
//                     The LLVM Compiler Infrastructure
 
4
//
 
5
// This file is dual licensed under the MIT and the University of Illinois Open
 
6
// Source Licenses. See LICENSE.TXT for details.
 
7
//
 
8
//
 
9
// Implements C++ ABI Exception Handling Level 1 as documented at:
 
10
//      http://mentorembedded.github.io/cxx-abi/abi-eh.html
 
11
// using libunwind
 
12
//
 
13
//===----------------------------------------------------------------------===//
 
14
 
 
15
#include <stdint.h>
 
16
#include <stdbool.h>
 
17
#include <stdlib.h>
 
18
#include <stdio.h>
 
19
#include <string.h>
 
20
 
 
21
#include "libunwind.h"
 
22
#include "unwind.h"
 
23
#include "config.h"
 
24
 
 
25
#if _LIBUNWIND_BUILD_ZERO_COST_APIS
 
26
 
 
27
static _Unwind_Reason_Code
 
28
unwind_phase1(unw_context_t *uc, struct _Unwind_Exception *exception_object) {
 
29
  unw_cursor_t cursor1;
 
30
  unw_init_local(&cursor1, uc);
 
31
 
 
32
  // Walk each frame looking for a place to stop.
 
33
  for (bool handlerNotFound = true; handlerNotFound;) {
 
34
 
 
35
    // Ask libuwind to get next frame (skip over first which is
 
36
    // _Unwind_RaiseException).
 
37
    int stepResult = unw_step(&cursor1);
 
38
    if (stepResult == 0) {
 
39
      _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step() reached "
 
40
                            "bottom => _URC_END_OF_STACK\n",
 
41
                            exception_object);
 
42
      return _URC_END_OF_STACK;
 
43
    } else if (stepResult < 0) {
 
44
      _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step failed => "
 
45
                            "_URC_FATAL_PHASE1_ERROR\n",
 
46
                            exception_object);
 
47
      return _URC_FATAL_PHASE1_ERROR;
 
48
    }
 
49
 
 
50
    // See if frame has code to run (has personality routine).
 
51
    unw_proc_info_t frameInfo;
 
52
    unw_word_t sp;
 
53
    if (unw_get_proc_info(&cursor1, &frameInfo) != UNW_ESUCCESS) {
 
54
      _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_get_proc_info "
 
55
                            "failed => _URC_FATAL_PHASE1_ERROR\n",
 
56
                            exception_object);
 
57
      return _URC_FATAL_PHASE1_ERROR;
 
58
    }
 
59
 
 
60
    // When tracing, print state information.
 
61
    if (_LIBUNWIND_TRACING_UNWINDING) {
 
62
      char functionName[512];
 
63
      unw_word_t offset;
 
64
      if ((unw_get_proc_name(&cursor1, functionName, 512, &offset) !=
 
65
           UNW_ESUCCESS) || (frameInfo.start_ip + offset > frameInfo.end_ip))
 
66
        strcpy(functionName, ".anonymous.");
 
67
      unw_word_t pc;
 
68
      unw_get_reg(&cursor1, UNW_REG_IP, &pc);
 
69
      _LIBUNWIND_TRACE_UNWINDING(
 
70
          "unwind_phase1(ex_ojb=%p): pc=0x%llX, start_ip=0x%llX, func=%s, "
 
71
          "lsda=0x%llX, personality=0x%llX\n",
 
72
          exception_object, pc, frameInfo.start_ip, functionName,
 
73
          frameInfo.lsda, frameInfo.handler);
 
74
    }
 
75
 
 
76
    // If there is a personality routine, ask it if it will want to stop at
 
77
    // this frame.
 
78
    if (frameInfo.handler != 0) {
 
79
      __personality_routine p =
 
80
          (__personality_routine)(long)(frameInfo.handler);
 
81
      _LIBUNWIND_TRACE_UNWINDING(
 
82
          "unwind_phase1(ex_ojb=%p): calling personality function %p\n",
 
83
          exception_object, p);
 
84
      _Unwind_Reason_Code personalityResult =
 
85
          (*p)(1, _UA_SEARCH_PHASE, exception_object->exception_class,
 
86
               exception_object, (struct _Unwind_Context *)(&cursor1));
 
87
      switch (personalityResult) {
 
88
      case _URC_HANDLER_FOUND:
 
89
        // found a catch clause or locals that need destructing in this frame
 
90
        // stop search and remember stack pointer at the frame
 
91
        handlerNotFound = false;
 
92
        unw_get_reg(&cursor1, UNW_REG_SP, &sp);
 
93
        exception_object->private_2 = (uintptr_t)sp;
 
94
        _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): "
 
95
                                   "_URC_HANDLER_FOUND \n",
 
96
                                   exception_object);
 
97
        return _URC_NO_REASON;
 
98
 
 
99
      case _URC_CONTINUE_UNWIND:
 
100
        _LIBUNWIND_TRACE_UNWINDING(
 
101
            "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND\n",
 
102
            exception_object);
 
103
        // continue unwinding
 
104
        break;
 
105
 
 
106
      default:
 
107
        // something went wrong
 
108
        _LIBUNWIND_TRACE_UNWINDING(
 
109
            "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR\n",
 
110
            exception_object);
 
111
        return _URC_FATAL_PHASE1_ERROR;
 
112
      }
 
113
    }
 
114
  }
 
115
  return _URC_NO_REASON;
 
116
}
 
117
 
 
118
 
 
119
static _Unwind_Reason_Code
 
120
unwind_phase2(unw_context_t *uc, struct _Unwind_Exception *exception_object) {
 
121
  unw_cursor_t cursor2;
 
122
  unw_init_local(&cursor2, uc);
 
123
 
 
124
  _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)\n", exception_object);
 
125
 
 
126
  // Walk each frame until we reach where search phase said to stop.
 
127
  while (true) {
 
128
 
 
129
    // Ask libuwind to get next frame (skip over first which is
 
130
    // _Unwind_RaiseException).
 
131
    int stepResult = unw_step(&cursor2);
 
132
    if (stepResult == 0) {
 
133
      _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step() reached "
 
134
                            "bottom => _URC_END_OF_STACK\n",
 
135
                            exception_object);
 
136
      return _URC_END_OF_STACK;
 
137
    } else if (stepResult < 0) {
 
138
      _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step failed => "
 
139
                            "_URC_FATAL_PHASE1_ERROR\n",
 
140
                            exception_object);
 
141
      return _URC_FATAL_PHASE2_ERROR;
 
142
    }
 
143
 
 
144
    // Get info about this frame.
 
145
    unw_word_t sp;
 
146
    unw_proc_info_t frameInfo;
 
147
    unw_get_reg(&cursor2, UNW_REG_SP, &sp);
 
148
    if (unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) {
 
149
      _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_get_proc_info "
 
150
                            "failed => _URC_FATAL_PHASE1_ERROR\n",
 
151
                            exception_object);
 
152
      return _URC_FATAL_PHASE2_ERROR;
 
153
    }
 
154
 
 
155
    // When tracing, print state information.
 
156
    if (_LIBUNWIND_TRACING_UNWINDING) {
 
157
      char functionName[512];
 
158
      unw_word_t offset;
 
159
      if ((unw_get_proc_name(&cursor2, functionName, 512, &offset) !=
 
160
           UNW_ESUCCESS) || (frameInfo.start_ip + offset > frameInfo.end_ip))
 
161
        strcpy(functionName, ".anonymous.");
 
162
      _LIBUNWIND_TRACE_UNWINDING(
 
163
          "unwind_phase2(ex_ojb=%p): start_ip=0x%llX, func=%s, sp=0x%llX, "
 
164
          "lsda=0x%llX, personality=0x%llX\n",
 
165
          exception_object, frameInfo.start_ip, functionName, sp,
 
166
          frameInfo.lsda, frameInfo.handler);
 
167
    }
 
168
 
 
169
    // If there is a personality routine, tell it we are unwinding.
 
170
    if (frameInfo.handler != 0) {
 
171
      __personality_routine p =
 
172
          (__personality_routine)(long)(frameInfo.handler);
 
173
      _Unwind_Action action = _UA_CLEANUP_PHASE;
 
174
      if (sp == exception_object->private_2) {
 
175
        // Tell personality this was the frame it marked in phase 1.
 
176
        action = (_Unwind_Action)(_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME);
 
177
      }
 
178
       _Unwind_Reason_Code personalityResult =
 
179
          (*p)(1, action, exception_object->exception_class, exception_object,
 
180
               (struct _Unwind_Context *)(&cursor2));
 
181
      switch (personalityResult) {
 
182
      case _URC_CONTINUE_UNWIND:
 
183
        // Continue unwinding
 
184
        _LIBUNWIND_TRACE_UNWINDING(
 
185
            "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND\n",
 
186
            exception_object);
 
187
        if (sp == exception_object->private_2) {
 
188
          // Phase 1 said we would stop at this frame, but we did not...
 
189
          _LIBUNWIND_ABORT("during phase1 personality function said it would "
 
190
                           "stop here, but now if phase2 it did not stop here");
 
191
        }
 
192
        break;
 
193
      case _URC_INSTALL_CONTEXT:
 
194
        _LIBUNWIND_TRACE_UNWINDING(
 
195
            "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT\n",
 
196
            exception_object);
 
197
        // Personality routine says to transfer control to landing pad.
 
198
        // We may get control back if landing pad calls _Unwind_Resume().
 
199
        if (_LIBUNWIND_TRACING_UNWINDING) {
 
200
          unw_word_t pc;
 
201
          unw_get_reg(&cursor2, UNW_REG_IP, &pc);
 
202
          unw_get_reg(&cursor2, UNW_REG_SP, &sp);
 
203
          _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering  "
 
204
                                     "user code with ip=0x%llX, sp=0x%llX\n",
 
205
                                    exception_object, pc, sp);
 
206
        }
 
207
        unw_resume(&cursor2);
 
208
        // unw_resume() only returns if there was an error.
 
209
        return _URC_FATAL_PHASE2_ERROR;
 
210
      default:
 
211
        // Personality routine returned an unknown result code.
 
212
        _LIBUNWIND_DEBUG_LOG("personality function returned unknown result %d",
 
213
                      personalityResult);
 
214
        return _URC_FATAL_PHASE2_ERROR;
 
215
      }
 
216
    }
 
217
  }
 
218
 
 
219
  // Clean up phase did not resume at the frame that the search phase
 
220
  // said it would...
 
221
  return _URC_FATAL_PHASE2_ERROR;
 
222
}
 
223
 
 
224
static _Unwind_Reason_Code
 
225
unwind_phase2_forced(unw_context_t *uc,
 
226
                     struct _Unwind_Exception *exception_object,
 
227
                     _Unwind_Stop_Fn stop, void *stop_parameter) {
 
228
  unw_cursor_t cursor2;
 
229
  unw_init_local(&cursor2, uc);
 
230
 
 
231
  // Walk each frame until we reach where search phase said to stop
 
232
  while (unw_step(&cursor2) > 0) {
 
233
 
 
234
    // Update info about this frame.
 
235
    unw_proc_info_t frameInfo;
 
236
    if (unw_get_proc_info(&cursor2, &frameInfo) != UNW_ESUCCESS) {
 
237
      _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): unw_step "
 
238
                                 "failed => _URC_END_OF_STACK\n",
 
239
                                 exception_object);
 
240
      return _URC_FATAL_PHASE1_ERROR;
 
241
    }
 
242
 
 
243
    // When tracing, print state information.
 
244
    if (_LIBUNWIND_TRACING_UNWINDING) {
 
245
      char functionName[512];
 
246
      unw_word_t offset;
 
247
      if ((unw_get_proc_name(&cursor2, functionName, 512, &offset) !=
 
248
           UNW_ESUCCESS) || (frameInfo.start_ip + offset > frameInfo.end_ip))
 
249
        strcpy(functionName, ".anonymous.");
 
250
      _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p):  "
 
251
                                 "start_ip=0x%llX, func=%s, lsda=0x%llX, "
 
252
                                 " personality=0x%llX\n",
 
253
                                 exception_object, frameInfo.start_ip,
 
254
                                 functionName, frameInfo.lsda,
 
255
                                 frameInfo.handler);
 
256
    }
 
257
 
 
258
    // Call stop function at each frame.
 
259
    _Unwind_Action action =
 
260
        (_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE);
 
261
    _Unwind_Reason_Code stopResult =
 
262
        (*stop)(1, action, exception_object->exception_class, exception_object,
 
263
                (struct _Unwind_Context *)(&cursor2), stop_parameter);
 
264
    _LIBUNWIND_TRACE_UNWINDING(
 
265
        "unwind_phase2_forced(ex_ojb=%p): stop function returned %d\n",
 
266
        exception_object, stopResult);
 
267
    if (stopResult != _URC_NO_REASON) {
 
268
      _LIBUNWIND_TRACE_UNWINDING(
 
269
          "unwind_phase2_forced(ex_ojb=%p): stopped by stop function\n",
 
270
          exception_object);
 
271
      return _URC_FATAL_PHASE2_ERROR;
 
272
    }
 
273
 
 
274
    // If there is a personality routine, tell it we are unwinding.
 
275
    if (frameInfo.handler != 0) {
 
276
      __personality_routine p =
 
277
          (__personality_routine)(long)(frameInfo.handler);
 
278
      _LIBUNWIND_TRACE_UNWINDING(
 
279
          "unwind_phase2_forced(ex_ojb=%p): calling personality function %p\n",
 
280
          exception_object, p);
 
281
      _Unwind_Reason_Code personalityResult =
 
282
          (*p)(1, action, exception_object->exception_class, exception_object,
 
283
               (struct _Unwind_Context *)(&cursor2));
 
284
      switch (personalityResult) {
 
285
      case _URC_CONTINUE_UNWIND:
 
286
        _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
 
287
                                "personality  returned _URC_CONTINUE_UNWIND\n",
 
288
                                 exception_object);
 
289
        // Destructors called, continue unwinding
 
290
        break;
 
291
      case _URC_INSTALL_CONTEXT:
 
292
        _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
 
293
                                  "personality returned _URC_INSTALL_CONTEXT\n",
 
294
                                   exception_object);
 
295
        // We may get control back if landing pad calls _Unwind_Resume().
 
296
        unw_resume(&cursor2);
 
297
        break;
 
298
      default:
 
299
        // Personality routine returned an unknown result code.
 
300
        _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
 
301
                                   "personality returned %d, "
 
302
                                   "_URC_FATAL_PHASE2_ERROR\n",
 
303
                                   exception_object, personalityResult);
 
304
        return _URC_FATAL_PHASE2_ERROR;
 
305
      }
 
306
    }
 
307
  }
 
308
 
 
309
  // Call stop function one last time and tell it we've reached the end
 
310
  // of the stack.
 
311
  _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): calling stop "
 
312
                        "function with _UA_END_OF_STACK\n",
 
313
                        exception_object);
 
314
  _Unwind_Action lastAction =
 
315
      (_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE | _UA_END_OF_STACK);
 
316
  (*stop)(1, lastAction, exception_object->exception_class, exception_object,
 
317
          (struct _Unwind_Context *)(&cursor2), stop_parameter);
 
318
 
 
319
  // Clean up phase did not resume at the frame that the search phase said it
 
320
  // would.
 
321
  return _URC_FATAL_PHASE2_ERROR;
 
322
}
 
323
 
 
324
 
 
325
/// Called by __cxa_throw.  Only returns if there is a fatal error.
 
326
_LIBUNWIND_EXPORT _Unwind_Reason_Code
 
327
_Unwind_RaiseException(struct _Unwind_Exception *exception_object) {
 
328
  _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)\n",
 
329
                             exception_object);
 
330
  unw_context_t uc;
 
331
  unw_getcontext(&uc);
 
332
 
 
333
  // Mark that this is a non-forced unwind, so _Unwind_Resume()
 
334
  // can do the right thing.
 
335
  exception_object->private_1 = 0;
 
336
  exception_object->private_2 = 0;
 
337
 
 
338
  // phase 1: the search phase
 
339
  _Unwind_Reason_Code phase1 = unwind_phase1(&uc, exception_object);
 
340
  if (phase1 != _URC_NO_REASON)
 
341
    return phase1;
 
342
 
 
343
  // phase 2: the clean up phase
 
344
  return unwind_phase2(&uc, exception_object);
 
345
}
 
346
 
 
347
 
 
348
 
 
349
/// When _Unwind_RaiseException() is in phase2, it hands control
 
350
/// to the personality function at each frame.  The personality
 
351
/// may force a jump to a landing pad in that function, the landing
 
352
/// pad code may then call _Unwind_Resume() to continue with the
 
353
/// unwinding.  Note: the call to _Unwind_Resume() is from compiler
 
354
/// geneated user code.  All other _Unwind_* routines are called
 
355
/// by the C++ runtime __cxa_* routines.
 
356
///
 
357
/// Note: re-throwing an exception (as opposed to continuing the unwind)
 
358
/// is implemented by having the code call __cxa_rethrow() which
 
359
/// in turn calls _Unwind_Resume_or_Rethrow().
 
360
_LIBUNWIND_EXPORT void
 
361
_Unwind_Resume(struct _Unwind_Exception *exception_object) {
 
362
  _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)\n", exception_object);
 
363
  unw_context_t uc;
 
364
  unw_getcontext(&uc);
 
365
 
 
366
  if (exception_object->private_1 != 0)
 
367
    unwind_phase2_forced(&uc, exception_object,
 
368
                         (_Unwind_Stop_Fn) exception_object->private_1,
 
369
                         (void *)exception_object->private_2);
 
370
  else
 
371
    unwind_phase2(&uc, exception_object);
 
372
 
 
373
  // Clients assume _Unwind_Resume() does not return, so all we can do is abort.
 
374
  _LIBUNWIND_ABORT("_Unwind_Resume() can't return");
 
375
}
 
376
 
 
377
 
 
378
 
 
379
/// Not used by C++.
 
380
/// Unwinds stack, calling "stop" function at each frame.
 
381
/// Could be used to implement longjmp().
 
382
_LIBUNWIND_EXPORT _Unwind_Reason_Code
 
383
_Unwind_ForcedUnwind(struct _Unwind_Exception *exception_object,
 
384
                     _Unwind_Stop_Fn stop, void *stop_parameter) {
 
385
  _LIBUNWIND_TRACE_API("_Unwind_ForcedUnwind(ex_obj=%p, stop=%p)\n",
 
386
                  exception_object, stop);
 
387
  unw_context_t uc;
 
388
  unw_getcontext(&uc);
 
389
 
 
390
  // Mark that this is a forced unwind, so _Unwind_Resume() can do
 
391
  // the right thing.
 
392
  exception_object->private_1 = (uintptr_t) stop;
 
393
  exception_object->private_2 = (uintptr_t) stop_parameter;
 
394
 
 
395
  // do it
 
396
  return unwind_phase2_forced(&uc, exception_object, stop, stop_parameter);
 
397
}
 
398
 
 
399
 
 
400
/// Called by personality handler during phase 2 to get LSDA for current frame.
 
401
_LIBUNWIND_EXPORT uintptr_t
 
402
_Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
 
403
  unw_cursor_t *cursor = (unw_cursor_t *)context;
 
404
  unw_proc_info_t frameInfo;
 
405
  uintptr_t result = 0;
 
406
  if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
 
407
    result = (uintptr_t)frameInfo.lsda;
 
408
  _LIBUNWIND_TRACE_API("_Unwind_GetLanguageSpecificData(context=%p)"
 
409
                             "=> 0x%lX\n", context, result);
 
410
  if (result != 0) {
 
411
    if (*((uint8_t *)result) != 0xFF)
 
412
      _LIBUNWIND_DEBUG_LOG("lsda at 0x%lX does not start with 0xFF\n", result);
 
413
  }
 
414
  return result;
 
415
}
 
416
 
 
417
 
 
418
 
 
419
/// Called by personality handler during phase 2 to get register values.
 
420
_LIBUNWIND_EXPORT uintptr_t _Unwind_GetGR(struct _Unwind_Context *context,
 
421
                                          int index) {
 
422
  unw_cursor_t *cursor = (unw_cursor_t *)context;
 
423
  unw_word_t result;
 
424
  unw_get_reg(cursor, index, &result);
 
425
  _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d) => 0x%llX\n",
 
426
    context,
 
427
                  index, (uint64_t) result);
 
428
  return (uintptr_t)result;
 
429
}
 
430
 
 
431
 
 
432
 
 
433
/// Called by personality handler during phase 2 to alter register values.
 
434
_LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index,
 
435
                                     uintptr_t new_value) {
 
436
  _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, "
 
437
                             "value=0x%0llX)\n", context,
 
438
                             index, (uint64_t) new_value);
 
439
  unw_cursor_t *cursor = (unw_cursor_t *)context;
 
440
  unw_set_reg(cursor, index, new_value);
 
441
}
 
442
 
 
443
 
 
444
 
 
445
/// Called by personality handler during phase 2 to get instruction pointer.
 
446
_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
 
447
  unw_cursor_t *cursor = (unw_cursor_t *)context;
 
448
  unw_word_t result;
 
449
  unw_get_reg(cursor, UNW_REG_IP, &result);
 
450
  _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%llX\n", context,
 
451
                             (uint64_t) result);
 
452
  return (uintptr_t)result;
 
453
}
 
454
 
 
455
 
 
456
 
 
457
/// Called by personality handler during phase 2 to alter instruction pointer,
 
458
/// such as setting where the landing pad is, so _Unwind_Resume() will
 
459
/// start executing in the landing pad.
 
460
_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context,
 
461
                                     uintptr_t new_value) {
 
462
  _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0llX)\n",
 
463
                             context, (uint64_t) new_value);
 
464
  unw_cursor_t *cursor = (unw_cursor_t *)context;
 
465
  unw_set_reg(cursor, UNW_REG_IP, new_value);
 
466
}
 
467
 
 
468
 
 
469
/// Called by personality handler during phase 2 to find the start of the
 
470
/// function.
 
471
_LIBUNWIND_EXPORT uintptr_t
 
472
_Unwind_GetRegionStart(struct _Unwind_Context *context) {
 
473
  unw_cursor_t *cursor = (unw_cursor_t *)context;
 
474
  unw_proc_info_t frameInfo;
 
475
  uintptr_t result = 0;
 
476
  if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
 
477
    result = (uintptr_t)frameInfo.start_ip;
 
478
  _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%lX\n",
 
479
                             context, result);
 
480
  return result;
 
481
}
 
482
 
 
483
 
 
484
/// Called by personality handler during phase 2 if a foreign exception
 
485
// is caught.
 
486
_LIBUNWIND_EXPORT void
 
487
_Unwind_DeleteException(struct _Unwind_Exception *exception_object) {
 
488
  _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)\n",
 
489
                              exception_object);
 
490
  if (exception_object->exception_cleanup != NULL)
 
491
    (*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT,
 
492
                                           exception_object);
 
493
}
 
494
 
 
495
#endif // _LIBUNWIND_BUILD_ZERO_COST_APIS