Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
a219e2fd9This file is pinned to the selected release. Download the original to open it in your design tool.
// Copyright 2024 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MUJOCO_INCLUDE_MJSAN_H_
#define MUJOCO_INCLUDE_MJSAN_H_
// Define ADDRESS_SANITIZER if implied by other macros.
#if !defined(ADDRESS_SANITIZER)
#if defined(__SANITIZE_ADDRESS__)
#define ADDRESS_SANITIZER
#elif defined(__has_feature)
#if __has_feature(address_sanitizer)
#define ADDRESS_SANITIZER
#endif
#endif
#endif
// Define mjUSEASAN if ADDRESS_SANITIZER is active and we are not on MSVC.
// MSVC asan (/fsanitize=address defines ADDRESS_SANITIZER via EnableASAN) cannot use the GCC/clang
// attribute+asm instrumentation below, so we exclude it.
#if defined(ADDRESS_SANITIZER) && !defined(_MSC_VER)
#define mjUSEASAN
#endif
// Include asan interface header, or provide stubs for poison/unpoison macros when not using asan.
#ifdef mjUSEASAN
#include <sanitizer/asan_interface.h>
#elif defined(_MSC_VER)
#define ASAN_POISON_MEMORY_REGION(addr, size)
#define ASAN_UNPOISON_MEMORY_REGION(addr, size)
#else
#define ASAN_POISON_MEMORY_REGION(addr, size) ((void)(addr), (void)(size))
#define ASAN_UNPOISON_MEMORY_REGION(addr, size) ((void)(addr), (void)(size))
#endif
// When built and run under address sanitizer (asan), mj_markStack and mj_freeStack are instrumented
// to detect leakage of mjData stack frames. When the compiler inlines several callees that call
// into mark/free into the same function, this instrumentation requires that the compiler retains
// separate mark/free calls for each original callee. The memory-clobbered asm blocks act as a
// barrier to prevent mark/free calls from being combined under optimization.
#ifdef mjUSEASAN
#ifdef __cplusplus
extern "C" {
#endif
void mj__markStack(mjData*) __attribute__((noinline));
static inline void mj_markStack(mjData* d) __attribute__((always_inline)) {
asm volatile("" ::: "memory");
mj__markStack(d);
asm volatile("" ::: "memory");
}
void mj__freeStack(mjData*) __attribute__((noinline));
static inline void mj_freeStack(mjData* d) __attribute__((always_inline)) {
asm volatile("" ::: "memory");
mj__freeStack(d);
asm volatile("" ::: "memory");
}
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // mjUSEASAN
#endif // MUJOCO_INCLUDE_MJSAN_H_