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