+__attribute__((always_inline, pure))
+static __inline__ uintptr_t
+_os_ptr_munge(uintptr_t ptr)
+{
+ return ptr ^ _os_ptr_munge_token();
+}
+#define _OS_PTR_MUNGE(_ptr) _os_ptr_munge((uintptr_t)(_ptr))
+#define _OS_PTR_UNMUNGE(_ptr) _os_ptr_munge((uintptr_t)(_ptr))
+
+#else // __ASSEMBLER__
+
+#define _OS_TSD_OFFSET(_key) \
+ ((__POINTER_WIDTH__/__CHAR_BIT__)*_key)
+
+#if defined(__i386__) || defined(__x86_64__)
+
+#define _OS_PTR_MUNGE(_reg) \
+ xor %gs:_OS_TSD_OFFSET(__TSD_PTR_MUNGE), _reg
+
+#define _OS_PTR_UNMUNGE(_reg) \
+ _OS_PTR_MUNGE(_reg)
+
+#elif defined(__arm__) || defined(__arm64__)
+
+#if defined(__arm__)
+
+#define _OS_PTR_MUNGE_TOKEN(_reg, _token) \
+ mrc p15, 0, _reg, c13, c0, 3; \
+ bic _reg, _reg, #3; \
+ ldr _token, [ _reg, #_OS_TSD_OFFSET(__TSD_PTR_MUNGE) ]
+
+#elif defined(__arm64__)
+
+#define _OS_PTR_MUNGE_TOKEN(_reg, _token) \
+ mrs _reg, TPIDRRO_EL0 %% \
+ and _reg, _reg, #~0x7 %% \
+ ldr _token, [ _reg, #_OS_TSD_OFFSET(__TSD_PTR_MUNGE) ]
+
+#endif // defined(__arm64__)
+
+#define _OS_PTR_MUNGE(_regdest, _regsrc, _token) \
+ eor _regdest, _regsrc, _token
+
+#define _OS_PTR_UNMUNGE(_regdest, _regsrc, _token) \
+ _OS_PTR_MUNGE(_regdest, _regsrc, _token)
+
+#endif // defined(__arm__) || defined(__arm64__)
+
+#endif // __ASSEMBLER__
+
+#endif // OS_TSD_H