llvm/compiler-rt/lib/ubsan/ubsan_type_hash_itanium.cpp

//===-- ubsan_type_hash_itanium.cpp ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Implementation of type hashing/lookup for Itanium C++ ABI.
//
//===----------------------------------------------------------------------===//

#include "sanitizer_common/sanitizer_platform.h"
#include "ubsan_platform.h"
#if CAN_SANITIZE_UB && !defined(_MSC_VER)
#include "ubsan_type_hash.h"

#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_ptrauth.h"
#include <stdint.h>

// The following are intended to be binary compatible with the definitions
// given in the Itanium ABI. We make no attempt to be ODR-compatible with
// those definitions, since existing ABI implementations aren't.

namespace std {
  class type_info {};
}

namespace __cxxabiv1 {

/// Type info for classes with no bases, and base class for type info for
/// classes with bases.
class __class_type_info : public std::type_info {};

/// Type info for classes with simple single public inheritance.
class __si_class_type_info : public __class_type_info {};

class __base_class_type_info {};

/// Type info for classes with multiple, virtual, or non-public inheritance.
class __vmi_class_type_info : public __class_type_info {};

}

abi;

usingnamespace__sanitizer;

// We implement a simple two-level cache for type-checking results. For each
// (vptr,type) pair, a hash is computed. This hash is assumed to be globally
// unique; if it collides, we will get false negatives, but:
//  * such a collision would have to occur on the *first* bad access,
//  * the probability of such a collision is low (and for a 64-bit target, is
//    negligible), and
//  * the vptr, and thus the hash, can be affected by ASLR, so multiple runs
//    give better coverage.
//
// The first caching layer is a small hash table with no chaining; buckets are
// reused as needed. The second caching layer is a large hash table with open
// chaining. We can freely evict from either layer since this is just a cache.
//
// FIXME: Make these hash table accesses thread-safe. The races here are benign:
//        assuming the unsequenced loads and stores don't misbehave too badly,
//        the worst case is false negatives or poor cache behavior, not false
//        positives or crashes.

/// Find a bucket to store the given hash value in.
static __ubsan::HashValue *getTypeCacheHashTableBucket(__ubsan::HashValue V) {}

/// \brief Determine whether \p Derived has a \p Base base class subobject at
/// offset \p Offset.
static bool isDerivedFromAtOffset(const abi::__class_type_info *Derived,
                                  const abi::__class_type_info *Base,
                                  sptr Offset) {}

/// \brief Find the derived-most dynamic base class of \p Derived at offset
/// \p Offset.
static const abi::__class_type_info *findBaseAtOffset(
    const abi::__class_type_info *Derived, sptr Offset) {}

namespace {

struct VtablePrefix {};
VtablePrefix *getVtablePrefix(void *Vtable) {}

}

bool __ubsan::checkDynamicType(void *Object, void *Type, HashValue Hash) {}

__ubsan::DynamicTypeInfo
__ubsan::getDynamicTypeInfoFromVtable(void *VtablePtr) {}

bool __ubsan::checkTypeInfoEquality(const void *TypeInfo1,
                                    const void *TypeInfo2) {}

#endif  // CAN_SANITIZE_UB && !SANITIZER_WINDOWS