File indexing completed on 2026-07-13 08:34:20
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef UPB_PORT_SANITIZERS_H_
0009 #define UPB_PORT_SANITIZERS_H_
0010
0011 #include <stddef.h>
0012 #include <stdint.h>
0013 #include <stdio.h>
0014
0015
0016 #include "upb/port/def.inc"
0017
0018
0019 #if UPB_HWASAN
0020 #include <sanitizer/hwasan_interface.h>
0021 #endif
0022
0023 #ifdef __cplusplus
0024 extern "C" {
0025 #endif
0026
0027
0028 typedef struct {
0029 uint8_t state;
0030 } upb_Xsan;
0031
0032 UPB_INLINE uint8_t _upb_Xsan_NextTag(upb_Xsan *xsan) {
0033 #if UPB_HWASAN
0034 xsan->state++;
0035 if (xsan->state <= UPB_HWASAN_POISON_TAG) {
0036 xsan->state = UPB_HWASAN_POISON_TAG + 1;
0037 }
0038 return xsan->state;
0039 #else
0040 return 0;
0041 #endif
0042 }
0043
0044 enum {
0045 #if UPB_ASAN
0046 UPB_PRIVATE(kUpb_Asan_GuardSize) = 32,
0047 #else
0048 UPB_PRIVATE(kUpb_Asan_GuardSize) = 0,
0049 #endif
0050 };
0051
0052 UPB_INLINE uint8_t UPB_PRIVATE(_upb_Xsan_GetTag)(const void *addr) {
0053 #if UPB_HWASAN
0054 return __hwasan_get_tag_from_pointer(addr);
0055 #else
0056 return 0;
0057 #endif
0058 }
0059
0060 UPB_INLINE void UPB_PRIVATE(upb_Xsan_Init)(upb_Xsan *xsan) {
0061 #if UPB_HWASAN || UPB_TSAN
0062 xsan->state = 0;
0063 #endif
0064 }
0065
0066
0067
0068 UPB_INLINE void UPB_PRIVATE(upb_Xsan_PoisonRegion)(const void *addr,
0069 size_t size) {
0070 #if UPB_ASAN
0071 void __asan_poison_memory_region(void const volatile *addr, size_t size);
0072 __asan_poison_memory_region(addr, size);
0073 #elif UPB_HWASAN
0074 __hwasan_tag_memory(addr, UPB_HWASAN_POISON_TAG, UPB_ALIGN_MALLOC(size));
0075 #endif
0076 }
0077
0078 UPB_INLINE void *UPB_PRIVATE(_upb_Xsan_UnpoisonRegion)(void *addr, size_t size,
0079 uint8_t tag) {
0080 #if UPB_ASAN
0081 UPB_UNUSED(tag);
0082 void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
0083 __asan_unpoison_memory_region(addr, size);
0084 return addr;
0085 #elif UPB_HWASAN
0086 __hwasan_tag_memory(addr, tag, UPB_ALIGN_MALLOC(size));
0087 return __hwasan_tag_pointer(addr, tag);
0088 #else
0089 UPB_UNUSED(size);
0090 UPB_UNUSED(tag);
0091
0092
0093
0094
0095
0096
0097
0098 UPB_ASSUME(addr);
0099 return addr;
0100 #endif
0101 }
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112 UPB_INLINE void *UPB_PRIVATE(upb_Xsan_NewUnpoisonedRegion)(upb_Xsan *xsan,
0113 void *addr,
0114 size_t size) {
0115 return UPB_PRIVATE(_upb_Xsan_UnpoisonRegion)(addr, size,
0116 _upb_Xsan_NextTag(xsan));
0117 }
0118
0119
0120
0121
0122
0123
0124
0125 UPB_INLINE void *UPB_PRIVATE(upb_Xsan_ResizeUnpoisonedRegion)(void *tagged_addr,
0126 size_t old_size,
0127 size_t new_size) {
0128 UPB_PRIVATE(upb_Xsan_PoisonRegion)(tagged_addr, old_size);
0129 return UPB_PRIVATE(_upb_Xsan_UnpoisonRegion)(
0130 tagged_addr, new_size, UPB_PRIVATE(_upb_Xsan_GetTag)(tagged_addr));
0131 }
0132
0133
0134
0135 UPB_INLINE bool UPB_PRIVATE(upb_Xsan_PtrEq)(const void *a, const void *b) {
0136 #if UPB_HWASAN
0137 return __hwasan_tag_pointer(a, 0) == __hwasan_tag_pointer(b, 0);
0138 #else
0139 return a == b;
0140 #endif
0141 }
0142
0143
0144
0145
0146
0147
0148 UPB_INLINE void UPB_PRIVATE(upb_Xsan_AccessReadOnly)(upb_Xsan *xsan) {
0149 #if UPB_TSAN
0150
0151 __asm__ volatile("" ::"r"(xsan->state));
0152 #endif
0153 }
0154
0155 UPB_INLINE void UPB_PRIVATE(upb_Xsan_AccessReadWrite)(upb_Xsan *xsan) {
0156 #if UPB_TSAN
0157
0158 __asm__ volatile("" : "+r"(xsan->state));
0159 #endif
0160 }
0161
0162 #ifdef __cplusplus
0163 }
0164 #endif
0165
0166 #include "upb/port/undef.inc"
0167
0168 #endif