1419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// Copyright (C) 2012 The Android Open Source Project 2419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// All rights reserved. 3419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// 4419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// Redistribution and use in source and binary forms, with or without 5419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// modification, are permitted provided that the following conditions 6419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// are met: 7419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// 1. Redistributions of source code must retain the above copyright 8419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// notice, this list of conditions and the following disclaimer. 9419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// 2. Redistributions in binary form must reproduce the above copyright 10419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// notice, this list of conditions and the following disclaimer in the 11419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// documentation and/or other materials provided with the distribution. 12419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// 3. Neither the name of the project nor the names of its contributors 13419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// may be used to endorse or promote products derived from this software 14419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// without specific prior written permission. 15419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// 16419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 17419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 20419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// SUCH DAMAGE. 27419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu//===----------------------------------------------------------------------===// 28419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// The LLVM Compiler Infrastructure 29419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// 30419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// This file is dual licensed under the MIT and the University of Illinois Open 31419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// Source Licenses. See LICENSE.TXT for details. 32419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// 33419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// 34419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// This file implements the "Exception Handling APIs" 35419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// http://www.codesourcery.com/public/cxx-abi/abi-eh.html 36419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// http://www.intel.com/design/itanium/downloads/245358.htm 37419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu// 38419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu//===----------------------------------------------------------------------===// 39419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu/* 40419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * Copyright 2010-2011 PathScale, Inc. All rights reserved. 41419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * 42419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * Redistribution and use in source and binary forms, with or without 43419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * modification, are permitted provided that the following conditions are met: 44419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * 45419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * 1. Redistributions of source code must retain the above copyright notice, 46419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * this list of conditions and the following disclaimer. 47419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * 48419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * 2. Redistributions in binary form must reproduce the above copyright notice, 49419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * this list of conditions and the following disclaimer in the documentation 50419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * and/or other materials provided with the distribution. 51419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * 52419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS 53419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 54419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 55419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 56419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 57419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 58419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 59419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 60419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 61419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 62419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 63419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu */ 64419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 65419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 66fdf89810ae76eac8def019716322018499531410Albert J. Wong#include <cstdlib> 67419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu#include <unwind.h> 687a9c37698a1e2cdd865b5db7b14f9781cb696da6David 'Digit' Turner 697a9c37698a1e2cdd865b5db7b14f9781cb696da6David 'Digit' Turner#include "cxxabi_defines.h" 70419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu#include "dwarf_helper.h" 71419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu#include "helper_func_internal.h" 72419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 73419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gunamespace __cxxabiv1 { 74419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 75419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu#ifdef __arm__ 76fdf89810ae76eac8def019716322018499531410Albert J. Wongextern "C" enum type_match_result { 77fdf89810ae76eac8def019716322018499531410Albert J. Wong ctm_failed = 0, 78fdf89810ae76eac8def019716322018499531410Albert J. Wong ctm_succeeded = 1, 79fdf89810ae76eac8def019716322018499531410Albert J. Wong ctm_succeeded_with_ptr_to_base = 2 80fdf89810ae76eac8def019716322018499531410Albert J. Wong}; 81fdf89810ae76eac8def019716322018499531410Albert J. Wong 8286514519b937804844bd9809c6bb721fd201c0f4Andrew Hsieh 8386514519b937804844bd9809c6bb721fd201c0f4Andrew Hsiehextern "C" type_match_result __attribute__((visibility("default"))) 8486514519b937804844bd9809c6bb721fd201c0f4Andrew Hsieh__cxa_type_match(_Unwind_Exception* ucbp, 8586514519b937804844bd9809c6bb721fd201c0f4Andrew Hsieh const __shim_type_info* rttip, 8686514519b937804844bd9809c6bb721fd201c0f4Andrew Hsieh bool is_reference_type, 8786514519b937804844bd9809c6bb721fd201c0f4Andrew Hsieh void** matched_object) { 88fdf89810ae76eac8def019716322018499531410Albert J. Wong 89fdf89810ae76eac8def019716322018499531410Albert J. Wong __cxa_exception* header = reinterpret_cast<__cxa_exception*>(ucbp+1)-1; 90fdf89810ae76eac8def019716322018499531410Albert J. Wong type_match_result result = ctm_succeeded; 91fdf89810ae76eac8def019716322018499531410Albert J. Wong 92fdf89810ae76eac8def019716322018499531410Albert J. Wong void* adjustedPtr = header+1; 93fdf89810ae76eac8def019716322018499531410Albert J. Wong if (dynamic_cast<const __pointer_type_info*>(header->exceptionType)) { 94fdf89810ae76eac8def019716322018499531410Albert J. Wong adjustedPtr = *reinterpret_cast<void**>(adjustedPtr); 95fdf89810ae76eac8def019716322018499531410Albert J. Wong result = ctm_succeeded_with_ptr_to_base; 96fdf89810ae76eac8def019716322018499531410Albert J. Wong } 97419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 98fdf89810ae76eac8def019716322018499531410Albert J. Wong const __shim_type_info* catch_type = rttip; 99fdf89810ae76eac8def019716322018499531410Albert J. Wong const __shim_type_info* thrown_type = 100fdf89810ae76eac8def019716322018499531410Albert J. Wong static_cast<const __shim_type_info*>(header->exceptionType); 101fdf89810ae76eac8def019716322018499531410Albert J. Wong if (!catch_type || !thrown_type) { 102fdf89810ae76eac8def019716322018499531410Albert J. Wong return ctm_failed; 103fdf89810ae76eac8def019716322018499531410Albert J. Wong } 104419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 105fdf89810ae76eac8def019716322018499531410Albert J. Wong if (catch_type->can_catch(thrown_type, adjustedPtr)) { 106fdf89810ae76eac8def019716322018499531410Albert J. Wong *matched_object = adjustedPtr; 107fdf89810ae76eac8def019716322018499531410Albert J. Wong return result; 108fdf89810ae76eac8def019716322018499531410Albert J. Wong } 109419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 110fdf89810ae76eac8def019716322018499531410Albert J. Wong return ctm_failed; 111fdf89810ae76eac8def019716322018499531410Albert J. Wong} 112fdf89810ae76eac8def019716322018499531410Albert J. Wong#endif // __arm__ 113fdf89810ae76eac8def019716322018499531410Albert J. Wong 114fdf89810ae76eac8def019716322018499531410Albert J. Wongnamespace { 115fdf89810ae76eac8def019716322018499531410Albert J. Wong 116fdf89810ae76eac8def019716322018499531410Albert J. Wongvoid terminate_helper(std::terminate_handler t_handler) { 117fdf89810ae76eac8def019716322018499531410Albert J. Wong try { 118fdf89810ae76eac8def019716322018499531410Albert J. Wong t_handler(); 119fdf89810ae76eac8def019716322018499531410Albert J. Wong abort(); 120fdf89810ae76eac8def019716322018499531410Albert J. Wong } catch (...) { 121fdf89810ae76eac8def019716322018499531410Albert J. Wong abort(); 122419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 123fdf89810ae76eac8def019716322018499531410Albert J. Wong} 124419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 125fdf89810ae76eac8def019716322018499531410Albert J. Wongvoid unexpected_helper(std::unexpected_handler u_handler) { 126fdf89810ae76eac8def019716322018499531410Albert J. Wong u_handler(); 127fdf89810ae76eac8def019716322018499531410Albert J. Wong std::terminate(); 128fdf89810ae76eac8def019716322018499531410Albert J. Wong} 129fdf89810ae76eac8def019716322018499531410Albert J. Wong 130fdf89810ae76eac8def019716322018499531410Albert J. Wong} // namespace 131fdf89810ae76eac8def019716322018499531410Albert J. Wong 132fdf89810ae76eac8def019716322018499531410Albert J. Wong#ifdef __arm__ 13386514519b937804844bd9809c6bb721fd201c0f4Andrew Hsieh extern "C" bool __attribute__((visibility("default"))) 13486514519b937804844bd9809c6bb721fd201c0f4Andrew Hsieh __cxa_begin_cleanup(_Unwind_Exception* exc) { 135419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu __cxa_eh_globals *globals = __cxa_get_globals(); 136419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu __cxa_exception *header = reinterpret_cast<__cxa_exception*>(exc+1)-1; 137419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu bool native = header->unwindHeader.exception_class == __gxx_exception_class; 138419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 139419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu if (native) { 140419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu header->cleanupCount += 1; 141419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu if (header->cleanupCount == 1) { // First time 142419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu header->nextCleanup = globals->cleanupExceptions; 143419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu globals->cleanupExceptions = header; 144419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 145419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } else { 146419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu globals->cleanupExceptions = header; 147419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 148419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 149419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu return true; 150419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 151419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 152419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu extern "C" _Unwind_Exception * helper_end_cleanup() { 153419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu __cxa_eh_globals *globals = __cxa_get_globals(); 154419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu __cxa_exception* header = globals->cleanupExceptions; 155419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 156419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu if (!header) { 157419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu std::terminate(); 158419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 159419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 160419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu if (header->unwindHeader.exception_class == __gxx_exception_class) { 161419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu header->cleanupCount -= 1; 162419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu if (header->cleanupCount == 0) { // Last one 163419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu globals->cleanupExceptions = header->nextCleanup; 164419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu header->nextCleanup = NULL; 165419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 166419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } else { 167419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu globals->cleanupExceptions = NULL; 168419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 169419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 170419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu return &header->unwindHeader; 171419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 172419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 173419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu asm ( 174419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu ".pushsection .text.__cxa_end_cleanup \n" 175419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu ".global __cxa_end_cleanup \n" 176419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu ".type __cxa_end_cleanup, \"function\" \n" 177419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu "__cxa_end_cleanup: \n" 178419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu " push\t{r1, r2, r3, r4} \n" 179419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu " bl helper_end_cleanup \n" 180419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu " pop\t{r1, r2, r3, r4} \n" 181419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu " bl _Unwind_Resume \n" 182419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu " bl abort \n" 183419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu ".popsection \n" 184419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu ); 185419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 18686514519b937804844bd9809c6bb721fd201c0f4Andrew Hsieh extern "C" void __attribute__((visibility("default"))) 18786514519b937804844bd9809c6bb721fd201c0f4Andrew Hsieh __cxa_call_unexpected(void* arg) { 188419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(arg); 189419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu __cxa_exception* header = reinterpret_cast<__cxa_exception*>(unwind_exception+1)-1; 190419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu bool native_exception = unwind_exception->exception_class == __gxx_exception_class; 191419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 192419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu if (!native_exception) { 193419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu __cxa_begin_catch(unwind_exception); // unexpected is also a handler 194419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu try { 195419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu std::unexpected(); 196419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } catch (...) { 197419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu std::terminate(); 198419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 199419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 200419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu return; 201419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 202419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 203419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu // Cache previous data first since we will change contents below. 204419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu uint32_t count = unwind_exception->barrier_cache.bitpattern[1]; 205419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu uint32_t stride = unwind_exception->barrier_cache.bitpattern[3]; 206419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu uint32_t* list = reinterpret_cast<uint32_t*>( 207419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu unwind_exception->barrier_cache.bitpattern[4]); 208419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 209419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu __cxa_begin_catch(unwind_exception); // unexpected is also a handler 210419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu try { 211fdf89810ae76eac8def019716322018499531410Albert J. Wong unexpected_helper(header->unexpectedHandler); 212419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } catch (...) { 213419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu // A new exception thrown when calling unexpected. 214419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu bool allow_bad_exception = false; 215419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 216419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu for (uint32_t i = 0; i != count; ++i) { 217419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu uint32_t offset = reinterpret_cast<uint32_t>(&list[i * (stride >> 2)]); 218419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu offset = decodeRelocTarget2(offset); 219fdf89810ae76eac8def019716322018499531410Albert J. Wong const __shim_type_info* catch_type = reinterpret_cast<const __shim_type_info*>(offset); 220419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 221419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu __cxa_exception* new_header = __cxa_get_globals()->caughtExceptions; 222419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu void* adjustedPtr = new_header + 1; 223419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu if (__cxa_type_match(&new_header->unwindHeader, 224419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu catch_type, 225419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu false/* is_ref_type */, 226419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu &adjustedPtr) != ctm_failed) { 227419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu throw; 228419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 229419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 230419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu void* null_adjustedPtr = NULL; 231fdf89810ae76eac8def019716322018499531410Albert J. Wong const __shim_type_info* bad_excp = 232fdf89810ae76eac8def019716322018499531410Albert J. Wong static_cast<const __shim_type_info*>(&typeid(std::bad_exception)); 233fdf89810ae76eac8def019716322018499531410Albert J. Wong if (catch_type->can_catch(bad_excp, null_adjustedPtr)) { 234419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu allow_bad_exception = true; 235419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 236419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 237419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 238419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu // If no other ones match, throw bad_exception. 239419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu if (allow_bad_exception) { 240419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu __cxa_end_catch(); 241419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu __cxa_end_catch(); 242419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu throw std::bad_exception(); 243419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 244419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 245fdf89810ae76eac8def019716322018499531410Albert J. Wong terminate_helper(header->terminateHandler); 246419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 247419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 248419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu#else // ! __arm__ 24986514519b937804844bd9809c6bb721fd201c0f4Andrew Hsieh extern "C" void __attribute__((visibility("default"))) 25086514519b937804844bd9809c6bb721fd201c0f4Andrew Hsieh __cxa_call_unexpected(void* arg) { 251419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(arg); 252419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu if (unwind_exception == 0) { 253419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu call_terminate(unwind_exception); 254419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 255419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu __cxa_begin_catch(unwind_exception); // unexpected is also a handler 256419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 257419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu bool native_old_exception = unwind_exception->exception_class == __gxx_exception_class; 258419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu std::unexpected_handler u_handler; 259419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu std::terminate_handler t_handler; 260419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu __cxa_exception* old_exception_header = 0; 261419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu int64_t ttypeIndex; 262419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu const uint8_t* lsda; 263419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu if (native_old_exception) { 264419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu old_exception_header = reinterpret_cast<__cxa_exception*>(unwind_exception+1)-1; 265419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu t_handler = old_exception_header->terminateHandler; 266419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu u_handler = old_exception_header->unexpectedHandler; 267fdf89810ae76eac8def019716322018499531410Albert J. Wong // If unexpected_helper(u_handler) rethrows the same exception, 268419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu // these values get overwritten by the rethrow. So save them now: 269419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu ttypeIndex = old_exception_header->handlerSwitchValue; 270419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu lsda = old_exception_header->languageSpecificData; 271419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } else { 272419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu t_handler = std::get_terminate(); 273419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu u_handler = std::get_unexpected(); 274419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 275419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 276419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu try { 277fdf89810ae76eac8def019716322018499531410Albert J. Wong unexpected_helper(u_handler); 278419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } catch (...) { 279419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu // A new exception thrown when calling unexpected. 280419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 281419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu if (!native_old_exception) { 282419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu std::terminate(); 283419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 284419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu uint8_t lpStartEncoding = *lsda++; 285419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding); 286419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu uint8_t ttypeEncoding = *lsda++; 287419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu if (ttypeEncoding == DW_EH_PE_omit) { 288fdf89810ae76eac8def019716322018499531410Albert J. Wong terminate_helper(t_handler); 289419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 290419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu uintptr_t classInfoOffset = readULEB128(&lsda); 291419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu const uint8_t* classInfo = lsda + classInfoOffset; 292419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu __cxa_eh_globals* globals = __cxa_get_globals_fast(); 293419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu __cxa_exception* new_exception_header = globals->caughtExceptions; 294419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu if (new_exception_header == 0) { // This shouldn't be able to happen! 295fdf89810ae76eac8def019716322018499531410Albert J. Wong terminate_helper(t_handler); 296419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 297419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu bool native_new_exception = 298419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu new_exception_header->unwindHeader.exception_class == __gxx_exception_class; 299419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 300419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu if (native_new_exception && (new_exception_header != old_exception_header)) { 301419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu const std::type_info* excpType = new_exception_header->exceptionType; 302419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu if (!canExceptionSpecCatch(ttypeIndex, classInfo, ttypeEncoding, 303419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu excpType, new_exception_header+1, unwind_exception)) { 304419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu // We need to __cxa_end_catch, but for the old exception, 305419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu // not the new one. This is a little tricky ... 306419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu // Disguise new_exception_header as a rethrown exception, but 307419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu // don't actually rethrow it. This means you can temporarily 308419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu // end the catch clause enclosing new_exception_header without 309419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu // __cxa_end_catch destroying new_exception_header. 310419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu new_exception_header->handlerCount = -new_exception_header->handlerCount; 311419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu globals->uncaughtExceptions += 1; 312419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu __cxa_end_catch(); 313419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu __cxa_end_catch(); 314419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu __cxa_begin_catch(&new_exception_header->unwindHeader); 315419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu throw; 316419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 317419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 318419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 319419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu const std::type_info* excpType = &typeid(std::bad_exception); 320419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu if (!canExceptionSpecCatch(ttypeIndex, classInfo, ttypeEncoding, 321419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu excpType, NULL, unwind_exception)) { 322419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu __cxa_end_catch(); 323419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu __cxa_end_catch(); 324419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu throw std::bad_exception(); 325419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 326419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } // catch (...) 327419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 328419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu // Call terminate after unexpected normally done 329fdf89810ae76eac8def019716322018499531410Albert J. Wong terminate_helper(t_handler); 330419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu } 331419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu#endif // __arm__ 332419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu 333419afd910dc325e65df10b53e99e49c1eded6d26WenHan Gu} // namespace __cxxabiv1 334