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