1*0b57cec5SDimitry Andric //===-- linux.h -------------------------------------------------*- C++ -*-===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #ifndef SCUDO_LINUX_H_ 10*0b57cec5SDimitry Andric #define SCUDO_LINUX_H_ 11*0b57cec5SDimitry Andric 12*0b57cec5SDimitry Andric #include "platform.h" 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric #if SCUDO_LINUX 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric namespace scudo { 17*0b57cec5SDimitry Andric 18*0b57cec5SDimitry Andric // MapPlatformData is unused on Linux, define it as a minimally sized structure. 19*0b57cec5SDimitry Andric struct MapPlatformData {}; 20*0b57cec5SDimitry Andric 21*0b57cec5SDimitry Andric #if SCUDO_ANDROID 22*0b57cec5SDimitry Andric 23*0b57cec5SDimitry Andric #if defined(__aarch64__) 24*0b57cec5SDimitry Andric #define __get_tls() \ 25*0b57cec5SDimitry Andric ({ \ 26*0b57cec5SDimitry Andric void **__v; \ 27*0b57cec5SDimitry Andric __asm__("mrs %0, tpidr_el0" : "=r"(__v)); \ 28*0b57cec5SDimitry Andric __v; \ 29*0b57cec5SDimitry Andric }) 30*0b57cec5SDimitry Andric #elif defined(__arm__) 31*0b57cec5SDimitry Andric #define __get_tls() \ 32*0b57cec5SDimitry Andric ({ \ 33*0b57cec5SDimitry Andric void **__v; \ 34*0b57cec5SDimitry Andric __asm__("mrc p15, 0, %0, c13, c0, 3" : "=r"(__v)); \ 35*0b57cec5SDimitry Andric __v; \ 36*0b57cec5SDimitry Andric }) 37*0b57cec5SDimitry Andric #elif defined(__i386__) 38*0b57cec5SDimitry Andric #define __get_tls() \ 39*0b57cec5SDimitry Andric ({ \ 40*0b57cec5SDimitry Andric void **__v; \ 41*0b57cec5SDimitry Andric __asm__("movl %%gs:0, %0" : "=r"(__v)); \ 42*0b57cec5SDimitry Andric __v; \ 43*0b57cec5SDimitry Andric }) 44*0b57cec5SDimitry Andric #elif defined(__x86_64__) 45*0b57cec5SDimitry Andric #define __get_tls() \ 46*0b57cec5SDimitry Andric ({ \ 47*0b57cec5SDimitry Andric void **__v; \ 48*0b57cec5SDimitry Andric __asm__("mov %%fs:0, %0" : "=r"(__v)); \ 49*0b57cec5SDimitry Andric __v; \ 50*0b57cec5SDimitry Andric }) 51*0b57cec5SDimitry Andric #else 52*0b57cec5SDimitry Andric #error "Unsupported architecture." 53*0b57cec5SDimitry Andric #endif 54*0b57cec5SDimitry Andric 55*0b57cec5SDimitry Andric // The Android Bionic team has allocated a TLS slot for sanitizers starting 56*0b57cec5SDimitry Andric // with Q, given that Android currently doesn't support ELF TLS. It is used to 57*0b57cec5SDimitry Andric // store sanitizer thread specific data. 58*0b57cec5SDimitry Andric static const int TLS_SLOT_SANITIZER = 8; // TODO(kostyak): 6 for Q!! 59*0b57cec5SDimitry Andric 60*0b57cec5SDimitry Andric ALWAYS_INLINE uptr *getAndroidTlsPtr() { 61*0b57cec5SDimitry Andric return reinterpret_cast<uptr *>(&__get_tls()[TLS_SLOT_SANITIZER]); 62*0b57cec5SDimitry Andric } 63*0b57cec5SDimitry Andric 64*0b57cec5SDimitry Andric #endif // SCUDO_ANDROID 65*0b57cec5SDimitry Andric 66*0b57cec5SDimitry Andric } // namespace scudo 67*0b57cec5SDimitry Andric 68*0b57cec5SDimitry Andric #endif // SCUDO_LINUX 69*0b57cec5SDimitry Andric 70*0b57cec5SDimitry Andric #endif // SCUDO_LINUX_H_ 71