// 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 __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 __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 {
      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 __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
