// Copyright (C) 2012 The Android Open Source Project
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
// 3. Neither the name of the project nor the names of its contributors
//    may be used to endorse or promote products derived from this software
//    without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//===----------------------------------------------------------------------===//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//
//  This file implements the "Exception Handling APIs"
//  http://www.codesourcery.com/public/cxx-abi/abi-eh.html
//  http://www.intel.com/design/itanium/downloads/245358.htm
//
//===----------------------------------------------------------------------===//
/*
 * Copyright 2010-2011 PathScale, Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


#include <cxxabi.h>
#include <unwind.h>
#include "dwarf_helper.h"
#include "helper_func_internal.h"

namespace __cxxabiv1 {

#ifdef __arm__
  extern "C" __cxa_type_match_result __cxa_type_match(_Unwind_Exception* ucbp,
                                                      const std::type_info* rttip,
                                                      bool is_reference_type,
                                                      void** matched_object) {
    __cxa_exception* header = reinterpret_cast<__cxa_exception*>(ucbp+1)-1;
    __cxa_type_match_result result = ctm_succeeded;

    void* adjustedPtr = header+1;
    if (dynamic_cast<const __pointer_type_info*>(header->exceptionType)) {
      adjustedPtr = *reinterpret_cast<void**>(adjustedPtr);
      result = ctm_succeeded_with_ptr_to_base;
    }

    const std::type_info* catch_type = rttip;
    const std::type_info* thrown_type = header->exceptionType;
    if (!catch_type || !thrown_type) {
      return ctm_failed;
    }

    if (catch_type->can_catch(thrown_type, adjustedPtr)) {
      *matched_object = adjustedPtr;
      return result;
    }

    return ctm_failed;
  }

  extern "C" bool __cxa_begin_cleanup(_Unwind_Exception* exc) {
    __cxa_eh_globals *globals = __cxa_get_globals();
    __cxa_exception *header = reinterpret_cast<__cxa_exception*>(exc+1)-1;
    bool native = header->unwindHeader.exception_class == __gxx_exception_class;

    if (native) {
      header->cleanupCount += 1;
      if (header->cleanupCount == 1) {  // First time
        header->nextCleanup = globals->cleanupExceptions;
        globals->cleanupExceptions = header;
      }
    } else {
      globals->cleanupExceptions = header;
    }

    return true;
  }

  extern "C" _Unwind_Exception * helper_end_cleanup() {
    __cxa_eh_globals *globals = __cxa_get_globals();
    __cxa_exception* header = globals->cleanupExceptions;

    if (!header) {
      std::terminate();
    }

    if (header->unwindHeader.exception_class == __gxx_exception_class) {
      header->cleanupCount -= 1;
      if (header->cleanupCount == 0) {  // Last one
        globals->cleanupExceptions = header->nextCleanup;
        header->nextCleanup = NULL;
      }
    } else {
      globals->cleanupExceptions = NULL;
    }

    return &header->unwindHeader;
  }

  asm (
  ".pushsection .text.__cxa_end_cleanup    \n"
  ".global __cxa_end_cleanup               \n"
  ".type __cxa_end_cleanup, \"function\"   \n"
  "__cxa_end_cleanup:                      \n"
  " push\t{r1, r2, r3, r4}                 \n"
  " bl helper_end_cleanup                  \n"
  " pop\t{r1, r2, r3, r4}                  \n"
  " bl _Unwind_Resume                      \n"
  " bl abort                               \n"
  ".popsection                             \n"
  );

  extern "C" void __cxa_call_unexpected(void* arg) {
    _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(arg);
    __cxa_exception* header = reinterpret_cast<__cxa_exception*>(unwind_exception+1)-1;
    bool native_exception = unwind_exception->exception_class == __gxx_exception_class;

    if (!native_exception) {
      __cxa_begin_catch(unwind_exception);    // unexpected is also a handler
      try {
        std::unexpected();
      } catch (...) {
        std::terminate();
      }

      return;
    }

    // Cache previous data first since we will change contents below.
    uint32_t count = unwind_exception->barrier_cache.bitpattern[1];
    uint32_t stride = unwind_exception->barrier_cache.bitpattern[3];
    uint32_t* list = reinterpret_cast<uint32_t*>(
                            unwind_exception->barrier_cache.bitpattern[4]);

    __cxa_begin_catch(unwind_exception);    // unexpected is also a handler
    try {
      std::__unexpected(header->unexpectedHandler);
    } catch (...) {
      // A new exception thrown when calling unexpected.
      bool allow_bad_exception = false;

      for (uint32_t i = 0; i != count; ++i) {
        uint32_t offset = reinterpret_cast<uint32_t>(&list[i * (stride >> 2)]);
        offset = decodeRelocTarget2(offset);
        const std::type_info* catch_type = reinterpret_cast<const std::type_info*>(offset);

        __cxa_exception* new_header = __cxa_get_globals()->caughtExceptions;
        void* adjustedPtr = new_header + 1;
        if (__cxa_type_match(&new_header->unwindHeader,
                             catch_type,
                             false/* is_ref_type */,
                             &adjustedPtr) != ctm_failed) {
          throw;
        }

        void* null_adjustedPtr = NULL;
        if (catch_type->can_catch(&typeid(std::bad_exception), null_adjustedPtr)) {
          allow_bad_exception = true;
        }
      }

      // If no other ones match, throw bad_exception.
      if (allow_bad_exception) {
        __cxa_end_catch();
        __cxa_end_catch();
        throw std::bad_exception();
      }

      std::__terminate(header->terminateHandler);
    }
  }
#else // ! __arm__
  extern "C" void __cxa_call_unexpected(void* arg) {
    _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(arg);
    if (unwind_exception == 0) {
      call_terminate(unwind_exception);
    }
    __cxa_begin_catch(unwind_exception);    // unexpected is also a handler

    bool native_old_exception = unwind_exception->exception_class == __gxx_exception_class;
    std::unexpected_handler u_handler;
    std::terminate_handler t_handler;
    __cxa_exception* old_exception_header = 0;
    int64_t ttypeIndex;
    const uint8_t* lsda;
    if (native_old_exception) {
      old_exception_header = reinterpret_cast<__cxa_exception*>(unwind_exception+1)-1;
      t_handler = old_exception_header->terminateHandler;
      u_handler = old_exception_header->unexpectedHandler;
      // If std::__unexpected(u_handler) rethrows the same exception,
      //   these values get overwritten by the rethrow.  So save them now:
      ttypeIndex = old_exception_header->handlerSwitchValue;
      lsda = old_exception_header->languageSpecificData;
    } else {
      t_handler = std::get_terminate();
      u_handler = std::get_unexpected();
    }

    try {
      std::__unexpected(u_handler);
    } catch (...) {
      // A new exception thrown when calling unexpected.

      if (!native_old_exception) {
        std::terminate();
      }
      uint8_t lpStartEncoding = *lsda++;
      const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding);
      uint8_t ttypeEncoding = *lsda++;
      if (ttypeEncoding == DW_EH_PE_omit) {
        std::__terminate(t_handler);
      }
      uintptr_t classInfoOffset = readULEB128(&lsda);
      const uint8_t* classInfo = lsda + classInfoOffset;
      __cxa_eh_globals* globals = __cxa_get_globals_fast();
      __cxa_exception* new_exception_header = globals->caughtExceptions;
      if (new_exception_header == 0) {  // This shouldn't be able to happen!
        std::__terminate(t_handler);
      }
      bool native_new_exception =
        new_exception_header->unwindHeader.exception_class == __gxx_exception_class;

      if (native_new_exception && (new_exception_header != old_exception_header)) {
        const std::type_info* excpType = new_exception_header->exceptionType;
        if (!canExceptionSpecCatch(ttypeIndex, classInfo, ttypeEncoding,
                                   excpType, new_exception_header+1, unwind_exception)) {
          // We need to __cxa_end_catch, but for the old exception,
          //   not the new one.  This is a little tricky ...
          // Disguise new_exception_header as a rethrown exception, but
          //   don't actually rethrow it.  This means you can temporarily
          //   end the catch clause enclosing new_exception_header without
          //   __cxa_end_catch destroying new_exception_header.
          new_exception_header->handlerCount = -new_exception_header->handlerCount;
          globals->uncaughtExceptions += 1;
          __cxa_end_catch();
          __cxa_end_catch();
          __cxa_begin_catch(&new_exception_header->unwindHeader);
          throw;
        }
      }

      const std::type_info* excpType = &typeid(std::bad_exception);
      if (!canExceptionSpecCatch(ttypeIndex, classInfo, ttypeEncoding,
                                 excpType, NULL, unwind_exception)) {
        __cxa_end_catch();
        __cxa_end_catch();
        throw std::bad_exception();
      }
    } // catch (...)

    // Call terminate after unexpected normally done
    std::__terminate(t_handler);
  }
#endif // __arm__

} // namespace __cxxabiv1
