// 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
//
//===----------------------------------------------------------------------===//

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

#include <android/log.h>
#include <dlfcn.h>
#include <stdio.h>

namespace __cxxabiv1 {

  const __shim_type_info* getTypePtr(uint64_t ttypeIndex,
                                     const uint8_t* classInfo,
                                     uint8_t ttypeEncoding,
                                     _Unwind_Exception* unwind_exception);

  void call_terminate(_Unwind_Exception* unwind_exception) {
    __cxa_begin_catch(unwind_exception);  // terminate is also a handler
    std::terminate();
  }

  // Boring stuff which has lots of encode/decode details
  void scanEHTable(ScanResultInternal& results,
                   _Unwind_Action actions,
                   bool native_exception,
                   _Unwind_Exception* unwind_exception,
                   _Unwind_Context* context) {
    // Initialize results to found nothing but an error
    results.ttypeIndex = 0;
    results.actionRecord = 0;
    results.languageSpecificData = 0;
    results.landingPad = 0;
    results.adjustedPtr = 0;
    results.reason = _URC_FATAL_PHASE1_ERROR;

    // Check for consistent actions
    if (actions & _UA_SEARCH_PHASE) {
      if (actions & (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME | _UA_FORCE_UNWIND)) {
        results.reason = _URC_FATAL_PHASE1_ERROR;
        return;
      }
    } else if (actions & _UA_CLEANUP_PHASE) {
      if ((actions & _UA_HANDLER_FRAME) && (actions & _UA_FORCE_UNWIND)) {
        results.reason = _URC_FATAL_PHASE2_ERROR;
        return;
      }
    } else {
      results.reason = _URC_FATAL_PHASE1_ERROR;
      return;
    }


    // Start scan by getting exception table address
    const uint8_t* lsda = (const uint8_t*)_Unwind_GetLanguageSpecificData(context);
    if (lsda == 0) {
      // No exception table
      results.reason = _URC_CONTINUE_UNWIND;
      return;
    }
    results.languageSpecificData = lsda;
    uintptr_t ip = _Unwind_GetIP(context) - 1;
    uintptr_t funcStart = _Unwind_GetRegionStart(context);
    uintptr_t ipOffset = ip - funcStart;
    const uint8_t* classInfo = NULL;
    uint8_t lpStartEncoding = *lsda++;
    const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding);
    if (lpStart == 0) {
      lpStart = (const uint8_t*)funcStart;
    }
    uint8_t ttypeEncoding = *lsda++;
    if (ttypeEncoding != DW_EH_PE_omit) {
      uintptr_t classInfoOffset = readULEB128(&lsda);
      classInfo = lsda + classInfoOffset;
    }
    uint8_t callSiteEncoding = *lsda++;
    uint32_t callSiteTableLength = static_cast<uint32_t>(readULEB128(&lsda));
    const uint8_t* callSiteTableStart = lsda;
    const uint8_t* callSiteTableEnd = callSiteTableStart + callSiteTableLength;
    const uint8_t* actionTableStart = callSiteTableEnd;
    const uint8_t* callSitePtr = callSiteTableStart;


    while (callSitePtr < callSiteTableEnd) {
      uintptr_t start = readEncodedPointer(&callSitePtr, callSiteEncoding);
      uintptr_t length = readEncodedPointer(&callSitePtr, callSiteEncoding);
      uintptr_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding);
      uintptr_t actionEntry = readULEB128(&callSitePtr);
      if ((start <= ipOffset) && (ipOffset < (start + length))) {
        if (landingPad == 0) {
          // No handler here
          results.reason = _URC_CONTINUE_UNWIND;
          return;
        }

        landingPad = (uintptr_t)lpStart + landingPad;
        if (actionEntry == 0) {
          if ((actions & _UA_CLEANUP_PHASE) && !(actions & _UA_HANDLER_FRAME))
          {
            results.ttypeIndex = 0;
            results.landingPad = landingPad;
            results.reason = _URC_HANDLER_FOUND;
            return;
          }
          // No handler here
          results.reason = _URC_CONTINUE_UNWIND;
          return;
        }

        const uint8_t* action = actionTableStart + (actionEntry - 1);
        while (true) {
          const uint8_t* actionRecord = action;
          int64_t ttypeIndex = readSLEB128(&action);
          if (ttypeIndex > 0) {
            // Found a catch, does it actually catch?
            // First check for catch (...)
            const __shim_type_info* catchType =
              getTypePtr(static_cast<uint64_t>(ttypeIndex),
                         classInfo, ttypeEncoding, unwind_exception);
            if (catchType == 0) {
              // Found catch (...) catches everything, including foreign exceptions
              if ((actions & _UA_SEARCH_PHASE) || (actions & _UA_HANDLER_FRAME))
              {
                // Save state and return _URC_HANDLER_FOUND
                results.ttypeIndex = ttypeIndex;
                results.actionRecord = actionRecord;
                results.landingPad = landingPad;
                results.adjustedPtr = unwind_exception+1;
                results.reason = _URC_HANDLER_FOUND;
                return;
              }
              else if (!(actions & _UA_FORCE_UNWIND))
              {
                // It looks like the exception table has changed
                //    on us.  Likely stack corruption!
                call_terminate(unwind_exception);
              }
            } else if (native_exception) {
              __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
              void* adjustedPtr = unwind_exception+1;
              const __shim_type_info* excpType =
                  static_cast<const __shim_type_info*>(exception_header->exceptionType);
              if (adjustedPtr == 0 || excpType == 0) {
                // Such a disaster! What's wrong?
                call_terminate(unwind_exception);
              }

              // Only derefence once, so put ouside the recursive search below
              if (dynamic_cast<const __pointer_type_info*>(excpType)) {
                adjustedPtr = *static_cast<void**>(adjustedPtr);
              }

              // Let's play!
              if (catchType->can_catch(excpType, adjustedPtr)) {
                if (actions & _UA_SEARCH_PHASE) {
                  // Cache it.
                  results.ttypeIndex = ttypeIndex;
                  results.actionRecord = actionRecord;
                  results.landingPad = landingPad;
                  results.adjustedPtr = adjustedPtr;
                  results.reason = _URC_HANDLER_FOUND;
                  return;
                } else if (!(actions & _UA_FORCE_UNWIND)) {
                  // It looks like the exception table has changed
                  //    on us.  Likely stack corruption!
                  call_terminate(unwind_exception);
                }
              } // catchType->can_catch
            } // if (catchType == 0)
          } else if (ttypeIndex < 0) {
            // Found an exception spec.
            if (native_exception) {
              __cxa_exception* header = reinterpret_cast<__cxa_exception*>(unwind_exception+1)-1;
              void* adjustedPtr = unwind_exception+1;
              const std::type_info* excpType = header->exceptionType;
              if (adjustedPtr == 0 || excpType == 0) {
                // Such a disaster! What's wrong?
                call_terminate(unwind_exception);
              }

              // Let's play!
              if (canExceptionSpecCatch(ttypeIndex, classInfo,
                                        ttypeEncoding, excpType,
                                        adjustedPtr, unwind_exception)) {
                if (actions & _UA_SEARCH_PHASE) {
                  // Cache it.
                  results.ttypeIndex = ttypeIndex;
                  results.actionRecord = actionRecord;
                  results.landingPad = landingPad;
                  results.adjustedPtr = adjustedPtr;
                  results.reason = _URC_HANDLER_FOUND;
                  return;
                } else if (!(actions & _UA_FORCE_UNWIND)) {
                  // It looks like the exception table has changed
                  //    on us.  Likely stack corruption!
                  call_terminate(unwind_exception);
                }
              }
            } else {  // ! native_exception
              // foreign exception must be caught by exception spec
              if ((actions & _UA_SEARCH_PHASE) || (actions & _UA_HANDLER_FRAME)) {
                results.ttypeIndex = ttypeIndex;
                results.actionRecord = actionRecord;
                results.landingPad = landingPad;
                results.adjustedPtr = unwind_exception+1;
                results.reason = _URC_HANDLER_FOUND;
                return;
              }
              else if (!(actions & _UA_FORCE_UNWIND)) {
                // It looks like the exception table has changed
                //    on us.  Likely stack corruption!
                call_terminate(unwind_exception);
              }
            }
          } else {  // ttypeIndex == 0
            // Found a cleanup, or nothing
            if ((actions & _UA_CLEANUP_PHASE) && !(actions & _UA_HANDLER_FRAME)) {
              results.ttypeIndex = ttypeIndex;
              results.actionRecord = actionRecord;
              results.landingPad = landingPad;
              results.adjustedPtr = unwind_exception+1;
              results.reason = _URC_HANDLER_FOUND;
              return;
            }
          }


          const uint8_t* temp = action;
          int64_t actionOffset = readSLEB128(&temp);
          if (actionOffset == 0) {
            // End of action list, no matching handler or cleanup found
            results.reason = _URC_CONTINUE_UNWIND;
            return;
          }

          // Go to next action
          action += actionOffset;
        }
      } else if (ipOffset < start) {
        // There is no call site for this ip
        call_terminate(unwind_exception);
      }
    } // while (callSitePtr < callSiteTableEnd)

    call_terminate(unwind_exception);
  }

  /*
   * Below is target-dependent part
   */

#ifdef __arm__

  /* Decode an R_ARM_TARGET2 relocation.  */
  uint32_t decodeRelocTarget2 (uint32_t ptr) {
    uint32_t tmp;

    tmp = *reinterpret_cast<uint32_t*>(ptr);
    if (!tmp) {
      return 0;
    }

    tmp += ptr;
    tmp = *reinterpret_cast<uint32_t*>(tmp);
    return tmp;
  }

  const __shim_type_info* getTypePtr(uint64_t ttypeIndex,
                                     const uint8_t* classInfo,
                                     uint8_t ttypeEncoding,
                                     _Unwind_Exception* unwind_exception) {
    if (classInfo == 0) { // eh table corrupted!
      call_terminate(unwind_exception);
    }
    const uint8_t* ptr = classInfo - ttypeIndex * 4;
    return (const __shim_type_info*)decodeRelocTarget2((uint32_t)ptr);
  }

  bool canExceptionSpecCatch(int64_t specIndex,
                             const uint8_t* classInfo,
                             uint8_t ttypeEncoding,
                             const std::type_info* excpType,
                             void* adjustedPtr,
                             _Unwind_Exception* unwind_exception) {
    if (classInfo == 0) { // eh table corrupted!
      call_terminate(unwind_exception);
    }

    specIndex = -specIndex;
    specIndex -= 1;
    const uint32_t* temp = reinterpret_cast<const uint32_t*>(classInfo) + specIndex;

    while (true) {
      uint32_t ttypeIndex = *temp;
      if (ttypeIndex == 0) {
        break;
      }
      ttypeIndex = decodeRelocTarget2((uint32_t)temp);
      temp += 1;
      const __shim_type_info* catchType = (const __shim_type_info*) ttypeIndex;
      void* tempPtr = adjustedPtr;
      if (catchType->can_catch(
              static_cast<const __shim_type_info*>(excpType), tempPtr)) {
        return false;
      }
    } // while
    return true;
  }

  // lower-level runtime library API function that unwinds the frame
  extern "C" bool __gnu_unwind_frame(_Unwind_Exception*, _Unwind_Context*);

  void setRegisters(_Unwind_Exception* unwind_exception,
                    _Unwind_Context* context,
                    const ScanResultInternal& results) {
    _Unwind_SetGR(context, 0, reinterpret_cast<uintptr_t>(unwind_exception));
    _Unwind_SetGR(context, 1, static_cast<uintptr_t>(results.ttypeIndex));
    _Unwind_SetIP(context, results.landingPad);
  }

  _Unwind_Reason_Code continueUnwinding(_Unwind_Exception *ex,
                                        _Unwind_Context *context) {
    if (__gnu_unwind_frame(ex, context) != _URC_OK) {
      return _URC_FAILURE;
    }
    return _URC_CONTINUE_UNWIND;
  }

  void saveDataToBarrierCache(_Unwind_Exception* exc,
                              _Unwind_Context* ctx,
                              const ScanResultInternal& results) {
    exc->barrier_cache.sp = _Unwind_GetGR(ctx, UNWIND_STACK_REG);
    exc->barrier_cache.bitpattern[0] = (uint32_t)results.adjustedPtr;
    exc->barrier_cache.bitpattern[1] = (uint32_t)results.ttypeIndex;
    exc->barrier_cache.bitpattern[3] = (uint32_t)results.landingPad;
  }

  void loadDataFromBarrierCache(_Unwind_Exception* exc,
                                ScanResultInternal& results) {
    results.adjustedPtr = (void*) exc->barrier_cache.bitpattern[0];
    results.ttypeIndex = (int64_t) exc->barrier_cache.bitpattern[1];
    results.landingPad = (uintptr_t) exc->barrier_cache.bitpattern[3];
  }

  void prepareBeginCleanup(_Unwind_Exception* exc) {
    __cxa_begin_cleanup(exc);
  }

  void saveUnexpectedDataToBarrierCache(_Unwind_Exception* exc,
                                        _Unwind_Context* ctx,
                                        const ScanResultInternal& results) {
    prepareBeginCleanup(exc);

    const uint8_t* lsda = (const uint8_t*)_Unwind_GetLanguageSpecificData(ctx);
    const uint8_t* classInfo = NULL;
    uint8_t lpStartEncoding = *lsda++;
    const uint8_t* lpStart = (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding);
    uintptr_t funcStart = _Unwind_GetRegionStart(ctx);
    if (lpStart == 0) {
      lpStart = (const uint8_t*)funcStart;
    }
    uint8_t ttypeEncoding = *lsda++;
    if (ttypeEncoding != DW_EH_PE_omit) {
      uintptr_t classInfoOffset = readULEB128(&lsda);
      classInfo = lsda + classInfoOffset;
    }

    const uint32_t* e = (const uint32_t*) classInfo - results.ttypeIndex - 1;
    uint32_t n = 0;
    while (e[n] != 0) {
      ++n;
    }

    exc->barrier_cache.bitpattern[1] = n;
    exc->barrier_cache.bitpattern[3] = 4;
    exc->barrier_cache.bitpattern[4] = (uint32_t)e;
  }

#else // ! __arm__

  const __shim_type_info* getTypePtr(uint64_t ttypeIndex,
                                     const uint8_t* classInfo,
                                     uint8_t ttypeEncoding,
                                     _Unwind_Exception* unwind_exception) {
    if (classInfo == 0) { // eh table corrupted!
      call_terminate(unwind_exception);
    }

    switch (ttypeEncoding & 0x0F) {
    case DW_EH_PE_absptr:
      ttypeIndex *= sizeof(void*);
      break;
    case DW_EH_PE_udata2:
    case DW_EH_PE_sdata2:
      ttypeIndex *= 2;
      break;
    case DW_EH_PE_udata4:
    case DW_EH_PE_sdata4:
      ttypeIndex *= 4;
      break;
    case DW_EH_PE_udata8:
    case DW_EH_PE_sdata8:
      ttypeIndex *= 8;
      break;
    default:
      // this should not happen.
      call_terminate(unwind_exception);
    }
    classInfo -= ttypeIndex;
    return (const __shim_type_info*)readEncodedPointer(&classInfo, ttypeEncoding);
  }

  bool canExceptionSpecCatch(int64_t specIndex,
                             const uint8_t* classInfo,
                             uint8_t ttypeEncoding,
                             const std::type_info* excpType,
                             void* adjustedPtr,
                             _Unwind_Exception* unwind_exception) {
    if (classInfo == 0) { // eh table corrupted!
      call_terminate(unwind_exception);
    }

    specIndex = -specIndex;
    specIndex -= 1;
    const uint8_t* temp = classInfo + specIndex;

    while (true) {
      uint64_t ttypeIndex = readULEB128(&temp);
      if (ttypeIndex == 0) {
        break;
      }
      const __shim_type_info* catchType = getTypePtr(ttypeIndex,
                                                     classInfo,
                                                     ttypeEncoding,
                                                     unwind_exception);
      void* tempPtr = adjustedPtr;
      if (catchType->can_catch(
              static_cast<const __shim_type_info*>(excpType), tempPtr)) {
        return false;
      }
    } // while
    return true;
  }

  void setRegisters(_Unwind_Exception* unwind_exception,
                    _Unwind_Context* context,
                    const ScanResultInternal& results) {
    _Unwind_SetGR(context, __builtin_eh_return_data_regno(0),
                  reinterpret_cast<uintptr_t>(unwind_exception));
    _Unwind_SetGR(context, __builtin_eh_return_data_regno(1),
                  static_cast<uintptr_t>(results.ttypeIndex));
    _Unwind_SetIP(context, results.landingPad);
  }

  _Unwind_Reason_Code continueUnwinding(_Unwind_Exception *ex,
                                        _Unwind_Context *context) {
    return _URC_CONTINUE_UNWIND;
  }

  // Do nothing, only for API compatibility
  // We don't use C++ polymorphism since we hope no virtual table cost.
  void saveDataToBarrierCache(_Unwind_Exception* exc,
                              _Unwind_Context* ctx,
                              const ScanResultInternal& results) {}

  void loadDataFromBarrierCache(_Unwind_Exception* exc,
                                ScanResultInternal& results) {}

  void prepareBeginCleanup(_Unwind_Exception* exc) {}

  void saveUnexpectedDataToBarrierCache(_Unwind_Exception* exc,
                                        _Unwind_Context* ctx,
                                        const ScanResultInternal& results) {}

#endif // __arm__

  void fatalError(const char* message) {

    // Note: Printing to stderr is only useful when running an executable
    // from a shell, e.g. when using 'adb shell'. For regular
    // applications, stderr is redirected to /dev/null by default.
    fprintf(stderr, "PANIC:GAbi++:%s\n", message);

    // Always print the message to the log, when possible. Use
    // dlopen()/dlsym() to avoid adding an explicit dependency
    // to -llog in GAbi++ for this sole feature.
    //
    // An explicit dependency to -ldl can be avoided because these
    // functions are implemented directly by the dynamic linker.
    // That is, except when this code is linked into a static
    // executable. In this case, adding -ldl to the final link command
    // will be necessary, but the dlopen() will always return NULL.
    //
    // There is unfortunately no way to detect where this code is going
    // to be used at compile time, but static executables are strongly
    // discouraged on the platform because they can't implement ASLR.
    //
    typedef void (*logfunc_t)(int, const char*, const char*);
    logfunc_t logger = NULL;

    // Note that this should always succeed in a regular application,
    // because the library is already loaded into the process' address
    // space by Zygote before forking the application process.
    // This will fail in static executables, because the static
    // version of -ldl only contains empty stubs.
    void* liblog = dlopen("liblog.so", RTLD_NOW);

    if (liblog != NULL) {
      logger = reinterpret_cast<logfunc_t>(dlsym(liblog, "__android_log_print"));
      if (logger != NULL) {
        (*logger)(ANDROID_LOG_FATAL, "GAbi++", message);
      }
      dlclose(liblog);
    }

    std::terminate();
  }

} // namespace __cxxabiv1
