1 | //===-- ubsan_type_hash_win.cpp -------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // Implementation of type hashing/lookup for Microsoft C++ ABI. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "sanitizer_common/sanitizer_platform.h" |
14 | #include "ubsan_platform.h" |
15 | #if CAN_SANITIZE_UB && defined(_MSC_VER) |
16 | #include "ubsan_type_hash.h" |
17 | |
18 | #include "sanitizer_common/sanitizer_common.h" |
19 | |
20 | #include <typeinfo> |
21 | |
22 | struct CompleteObjectLocator { |
23 | int is_image_relative; |
24 | int offset_to_top; |
25 | int vfptr_offset; |
26 | int rtti_addr; |
27 | int chd_addr; |
28 | int obj_locator_addr; |
29 | }; |
30 | |
31 | struct CompleteObjectLocatorAbs { |
32 | int is_image_relative; |
33 | int offset_to_top; |
34 | int vfptr_offset; |
35 | std::type_info *rtti_addr; |
36 | void *chd_addr; |
37 | CompleteObjectLocator *obj_locator_addr; |
38 | }; |
39 | |
40 | bool __ubsan::checkDynamicType(void *Object, void *Type, HashValue Hash) { |
41 | // FIXME: Implement. |
42 | return false; |
43 | } |
44 | |
45 | __ubsan::DynamicTypeInfo |
46 | __ubsan::getDynamicTypeInfoFromVtable(void *VtablePtr) { |
47 | // The virtual table may not have a complete object locator if the object |
48 | // was compiled without RTTI (i.e. we might be reading from some other global |
49 | // laid out before the virtual table), so we need to carefully validate each |
50 | // pointer dereference and perform sanity checks. |
51 | CompleteObjectLocator **obj_locator_ptr = |
52 | ((CompleteObjectLocator**)VtablePtr)-1; |
53 | if (!IsAccessibleMemoryRange((uptr)obj_locator_ptr, sizeof(void*))) |
54 | return DynamicTypeInfo(0, 0, 0); |
55 | |
56 | CompleteObjectLocator *obj_locator = *obj_locator_ptr; |
57 | if (!IsAccessibleMemoryRange((uptr)obj_locator, |
58 | sizeof(CompleteObjectLocator))) |
59 | return DynamicTypeInfo(0, 0, 0); |
60 | |
61 | std::type_info *tinfo; |
62 | if (obj_locator->is_image_relative == 1) { |
63 | char *image_base = ((char *)obj_locator) - obj_locator->obj_locator_addr; |
64 | tinfo = (std::type_info *)(image_base + obj_locator->rtti_addr); |
65 | } else if (obj_locator->is_image_relative == 0) |
66 | tinfo = ((CompleteObjectLocatorAbs *)obj_locator)->rtti_addr; |
67 | else |
68 | // Probably not a complete object locator. |
69 | return DynamicTypeInfo(0, 0, 0); |
70 | |
71 | if (!IsAccessibleMemoryRange((uptr)tinfo, sizeof(std::type_info))) |
72 | return DynamicTypeInfo(0, 0, 0); |
73 | |
74 | // Okay, this is probably a std::type_info. Request its name. |
75 | // FIXME: Implement a base class search like we do for Itanium. |
76 | return DynamicTypeInfo(tinfo->name(), obj_locator->offset_to_top, |
77 | "<unknown>" ); |
78 | } |
79 | |
80 | bool __ubsan::checkTypeInfoEquality(const void *, const void *) { |
81 | return false; |
82 | } |
83 | |
84 | #endif // CAN_SANITIZE_UB && SANITIZER_WINDOWS |
85 | |