Home | History | Annotate | Download | only in ubsan
      1 //===-- ubsan_handlers_cxx.cc ---------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // Error logging entry points for the UBSan runtime, which are only used for C++
     11 // compilations. This file is permitted to use language features which require
     12 // linking against a C++ ABI library.
     13 //
     14 //===----------------------------------------------------------------------===//
     15 
     16 #include "ubsan_handlers_cxx.h"
     17 #include "ubsan_diag.h"
     18 #include "ubsan_type_hash.h"
     19 
     20 #include "sanitizer_common/sanitizer_common.h"
     21 
     22 using namespace __sanitizer;
     23 using namespace __ubsan;
     24 
     25 namespace __ubsan {
     26   extern const char *TypeCheckKinds[];
     27 }
     28 
     29 static void HandleDynamicTypeCacheMiss(
     30     DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash,
     31     bool Abort) {
     32   if (checkDynamicType((void*)Pointer, Data->TypeInfo, Hash))
     33     // Just a cache miss. The type matches after all.
     34     return;
     35 
     36   SourceLocation Loc = Data->Loc.acquire();
     37   if (Loc.isDisabled())
     38     return;
     39 
     40   Diag(Loc, DL_Error,
     41        "%0 address %1 which does not point to an object of type %2")
     42     << TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer << Data->Type;
     43 
     44   // If possible, say what type it actually points to.
     45   DynamicTypeInfo DTI = getDynamicTypeInfo((void*)Pointer);
     46   if (!DTI.isValid())
     47     Diag(Pointer, DL_Note, "object has invalid vptr")
     48       << MangledName(DTI.getMostDerivedTypeName())
     49       << Range(Pointer, Pointer + sizeof(uptr), "invalid vptr");
     50   else if (!DTI.getOffset())
     51     Diag(Pointer, DL_Note, "object is of type %0")
     52       << MangledName(DTI.getMostDerivedTypeName())
     53       << Range(Pointer, Pointer + sizeof(uptr), "vptr for %0");
     54   else
     55     // FIXME: Find the type at the specified offset, and include that
     56     //        in the note.
     57     Diag(Pointer - DTI.getOffset(), DL_Note,
     58          "object is base class subobject at offset %0 within object of type %1")
     59       << DTI.getOffset() << MangledName(DTI.getMostDerivedTypeName())
     60       << MangledName(DTI.getSubobjectTypeName())
     61       << Range(Pointer, Pointer + sizeof(uptr), "vptr for %2 base class of %1");
     62 
     63   if (Abort)
     64     Die();
     65 }
     66 
     67 void __ubsan::__ubsan_handle_dynamic_type_cache_miss(
     68     DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash) {
     69   HandleDynamicTypeCacheMiss(Data, Pointer, Hash, false);
     70 }
     71 void __ubsan::__ubsan_handle_dynamic_type_cache_miss_abort(
     72     DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash) {
     73   HandleDynamicTypeCacheMiss(Data, Pointer, Hash, true);
     74 }
     75