//===-- ubsan_handlers_cxx.cc ---------------------------------------------===//
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Error logging entry points for the UBSan runtime, which are only used for C++
// compilations. This file is permitted to use language features which require
// linking against a C++ ABI library.
//
//===----------------------------------------------------------------------===//

#include "ubsan_platform.h"
#if CAN_SANITIZE_UB
#include "ubsan_handlers.h"
#include "ubsan_handlers_cxx.h"
#include "ubsan_diag.h"
#include "ubsan_type_hash.h"

#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_suppressions.h"

using namespace __sanitizer;
using namespace __ubsan;

namespace __ubsan {
  extern const char *TypeCheckKinds[];
}

// Returns true if UBSan has printed an error report.
static bool HandleDynamicTypeCacheMiss(
    DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash,
    ReportOptions Opts) {
  if (checkDynamicType((void*)Pointer, Data->TypeInfo, Hash))
    // Just a cache miss. The type matches after all.
    return false;

  // Check if error report should be suppressed.
  DynamicTypeInfo DTI = getDynamicTypeInfoFromObject((void*)Pointer);
  if (DTI.isValid() && IsVptrCheckSuppressed(DTI.getMostDerivedTypeName()))
    return false;

  SourceLocation Loc = Data->Loc.acquire();
  ErrorType ET = ErrorType::DynamicTypeMismatch;
  if (ignoreReport(Loc, Opts, ET))
    return false;

  ScopedReport R(Opts, Loc, ET);

  Diag(Loc, DL_Error,
       "%0 address %1 which does not point to an object of type %2")
    << TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer << Data->Type;

  // If possible, say what type it actually points to.
  if (!DTI.isValid()) {
    if (DTI.getOffset() < -VptrMaxOffsetToTop || DTI.getOffset() > VptrMaxOffsetToTop) {
      Diag(Pointer, DL_Note, "object has a possibly invalid vptr: abs(offset to top) too big")
          << TypeName(DTI.getMostDerivedTypeName())
          << Range(Pointer, Pointer + sizeof(uptr), "possibly invalid vptr");
    } else {
      Diag(Pointer, DL_Note, "object has invalid vptr")
          << TypeName(DTI.getMostDerivedTypeName())
          << Range(Pointer, Pointer + sizeof(uptr), "invalid vptr");
    }
  } else if (!DTI.getOffset())
    Diag(Pointer, DL_Note, "object is of type %0")
        << TypeName(DTI.getMostDerivedTypeName())
        << Range(Pointer, Pointer + sizeof(uptr), "vptr for %0");
  else
    // FIXME: Find the type at the specified offset, and include that
    //        in the note.
    Diag(Pointer - DTI.getOffset(), DL_Note,
         "object is base class subobject at offset %0 within object of type %1")
        << DTI.getOffset() << TypeName(DTI.getMostDerivedTypeName())
        << TypeName(DTI.getSubobjectTypeName())
        << Range(Pointer, Pointer + sizeof(uptr),
                 "vptr for %2 base class of %1");
  return true;
}

void __ubsan::__ubsan_handle_dynamic_type_cache_miss(
    DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash) {
  GET_REPORT_OPTIONS(false);
  HandleDynamicTypeCacheMiss(Data, Pointer, Hash, Opts);
}
void __ubsan::__ubsan_handle_dynamic_type_cache_miss_abort(
    DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash) {
  // Note: -fsanitize=vptr is always recoverable.
  GET_REPORT_OPTIONS(false);
  if (HandleDynamicTypeCacheMiss(Data, Pointer, Hash, Opts))
    Die();
}

namespace __ubsan {
void __ubsan_handle_cfi_bad_type(CFICheckFailData *Data, ValueHandle Vtable,
                                 bool ValidVtable, ReportOptions Opts) {
  SourceLocation Loc = Data->Loc.acquire();
  ErrorType ET = ErrorType::CFIBadType;

  if (ignoreReport(Loc, Opts, ET))
    return;

  ScopedReport R(Opts, Loc, ET);
  DynamicTypeInfo DTI = ValidVtable
                            ? getDynamicTypeInfoFromVtable((void *)Vtable)
                            : DynamicTypeInfo(0, 0, 0);

  const char *CheckKindStr;
  switch (Data->CheckKind) {
  case CFITCK_VCall:
    CheckKindStr = "virtual call";
    break;
  case CFITCK_NVCall:
    CheckKindStr = "non-virtual call";
    break;
  case CFITCK_DerivedCast:
    CheckKindStr = "base-to-derived cast";
    break;
  case CFITCK_UnrelatedCast:
    CheckKindStr = "cast to unrelated type";
    break;
  case CFITCK_ICall:
  default:
    Die();
  }

  Diag(Loc, DL_Error, "control flow integrity check for type %0 failed during "
                      "%1 (vtable address %2)")
      << Data->Type << CheckKindStr << (void *)Vtable;

  // If possible, say what type it actually points to.
  if (!DTI.isValid()) {
    const char *module = Symbolizer::GetOrInit()->GetModuleNameForPc(Vtable);
    if (module)
      Diag(Vtable, DL_Note, "invalid vtable in module %0") << module;
    else
      Diag(Vtable, DL_Note, "invalid vtable");
  } else {
    Diag(Vtable, DL_Note, "vtable is of type %0")
        << TypeName(DTI.getMostDerivedTypeName());
  }
}
}  // namespace __ubsan

#endif // CAN_SANITIZE_UB
