1eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith//===-- ubsan_handlers_cxx.cc ---------------------------------------------===//
2eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith//
3eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith//                     The LLVM Compiler Infrastructure
4eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith//
5eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith// This file is distributed under the University of Illinois Open Source
6eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith// License. See LICENSE.TXT for details.
7eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith//
8eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith//===----------------------------------------------------------------------===//
9eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith//
10eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith// Error logging entry points for the UBSan runtime, which are only used for C++
11eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith// compilations. This file is permitted to use language features which require
12eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith// linking against a C++ ABI library.
13eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith//
14eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith//===----------------------------------------------------------------------===//
15eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith
16eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith#include "ubsan_handlers_cxx.h"
17eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith#include "ubsan_diag.h"
18eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith#include "ubsan_type_hash.h"
19eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith
20eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith#include "sanitizer_common/sanitizer_common.h"
21eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith
22eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smithusing namespace __sanitizer;
23eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smithusing namespace __ubsan;
24eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith
25eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smithnamespace __ubsan {
26eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith  extern const char *TypeCheckKinds[];
27eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith}
28eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith
29a82a5d360b19080f2b1beae374c12d4f26146450Will Dietzstatic void HandleDynamicTypeCacheMiss(
3025ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith    DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash,
3125ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith    bool Abort) {
32eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith  if (checkDynamicType((void*)Pointer, Data->TypeInfo, Hash))
33eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith    // Just a cache miss. The type matches after all.
34eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith    return;
35eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith
362af552f98f980178db37eed28a609b6bf55f6df8Will Dietz  SourceLocation Loc = Data->Loc.acquire();
372af552f98f980178db37eed28a609b6bf55f6df8Will Dietz  if (Loc.isDisabled())
382af552f98f980178db37eed28a609b6bf55f6df8Will Dietz    return;
392af552f98f980178db37eed28a609b6bf55f6df8Will Dietz
402af552f98f980178db37eed28a609b6bf55f6df8Will Dietz  Diag(Loc, DL_Error,
4125ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith       "%0 address %1 which does not point to an object of type %2")
42eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith    << TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer << Data->Type;
4325ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith
4425ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith  // If possible, say what type it actually points to.
4525ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith  DynamicTypeInfo DTI = getDynamicTypeInfo((void*)Pointer);
4625ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith  if (!DTI.isValid())
4725ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith    Diag(Pointer, DL_Note, "object has invalid vptr")
480ad23f7f860e27b8b9a889be665cfaea830503ceRichard Smith      << MangledName(DTI.getMostDerivedTypeName())
4925ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith      << Range(Pointer, Pointer + sizeof(uptr), "invalid vptr");
5025ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith  else if (!DTI.getOffset())
5125ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith    Diag(Pointer, DL_Note, "object is of type %0")
520ad23f7f860e27b8b9a889be665cfaea830503ceRichard Smith      << MangledName(DTI.getMostDerivedTypeName())
5325ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith      << Range(Pointer, Pointer + sizeof(uptr), "vptr for %0");
5425ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith  else
550ad23f7f860e27b8b9a889be665cfaea830503ceRichard Smith    // FIXME: Find the type at the specified offset, and include that
560ad23f7f860e27b8b9a889be665cfaea830503ceRichard Smith    //        in the note.
5725ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith    Diag(Pointer - DTI.getOffset(), DL_Note,
5825ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith         "object is base class subobject at offset %0 within object of type %1")
590ad23f7f860e27b8b9a889be665cfaea830503ceRichard Smith      << DTI.getOffset() << MangledName(DTI.getMostDerivedTypeName())
600ad23f7f860e27b8b9a889be665cfaea830503ceRichard Smith      << MangledName(DTI.getSubobjectTypeName())
610ad23f7f860e27b8b9a889be665cfaea830503ceRichard Smith      << Range(Pointer, Pointer + sizeof(uptr), "vptr for %2 base class of %1");
6225ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith
6325ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith  if (Abort)
64a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz    Die();
65a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz}
66a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz
67a82a5d360b19080f2b1beae374c12d4f26146450Will Dietzvoid __ubsan::__ubsan_handle_dynamic_type_cache_miss(
6825ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith    DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash) {
69a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz  HandleDynamicTypeCacheMiss(Data, Pointer, Hash, false);
70a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz}
71a82a5d360b19080f2b1beae374c12d4f26146450Will Dietzvoid __ubsan::__ubsan_handle_dynamic_type_cache_miss_abort(
7225ee97fe8ada76755c8bd1087fac9cc3cd03b28cRichard Smith    DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash) {
73a82a5d360b19080f2b1beae374c12d4f26146450Will Dietz  HandleDynamicTypeCacheMiss(Data, Pointer, Hash, true);
74eda8bd0fc07df35c9ad7de5b698bb717b063e7afRichard Smith}
75