// 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 <cstdlib>
#include <cxxabi.h>
#include <unwind.h>
#include "dwarf_helper.h"
#include "helper_func_internal.h"

namespace __cxxabiv1 {

#ifdef __arm__
extern "C" enum type_match_result {
  ctm_failed = 0,
  ctm_succeeded = 1,
  ctm_succeeded_with_ptr_to_base = 2
};


extern "C" type_match_result __attribute__((visibility("default")))
__cxa_type_match(_Unwind_Exception* ucbp,
                 const __shim_type_info* rttip,
                 bool is_reference_type,
                 void** matched_object) {

  __cxa_exception* header = reinterpret_cast<__cxa_exception*>(ucbp+1)-1;
  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 __shim_type_info* catch_type = rttip;
  const __shim_type_info* thrown_type =
      static_cast<const __shim_type_info*>(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;
}
#endif  // __arm__

namespace {

void terminate_helper(std::terminate_handler t_handler) {
  try {
    t_handler();
    abort();
  } catch (...) {
    abort();
  }
}

void unexpected_helper(std::unexpected_handler u_handler) {
  u_handler();
  std::terminate();
}

}  // namespace

#ifdef __arm__
  extern "C" bool   __attribute__((visibility("default")))
  __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 __attribute__((visibility("default")))
  __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 {
      unexpected_helper(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 __shim_type_info* catch_type = reinterpret_cast<const __shim_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;
        const __shim_type_info* bad_excp =
            static_cast<const __shim_type_info*>(&typeid(std::bad_exception));
        if (catch_type->can_catch(bad_excp, 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();
      }

      terminate_helper(header->terminateHandler);
    }
  }
#else // ! __arm__
  extern "C" void __attribute__((visibility("default")))
  __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 unexpected_helper(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 {
      unexpected_helper(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) {
        terminate_helper(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!
        terminate_helper(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
    terminate_helper(t_handler);
  }
#endif // __arm__

} // namespace __cxxabiv1
