ubsan_handlers_cxx.cc 2.9 KB

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