1351282Sdim//===-- linux.h -------------------------------------------------*- C++ -*-===//
2351282Sdim//
3351282Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4351282Sdim// See https://llvm.org/LICENSE.txt for license information.
5351282Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6351282Sdim//
7351282Sdim//===----------------------------------------------------------------------===//
8351282Sdim
9351282Sdim#ifndef SCUDO_LINUX_H_
10351282Sdim#define SCUDO_LINUX_H_
11351282Sdim
12351282Sdim#include "platform.h"
13351282Sdim
14351282Sdim#if SCUDO_LINUX
15351282Sdim
16351282Sdimnamespace scudo {
17351282Sdim
18351282Sdim// MapPlatformData is unused on Linux, define it as a minimally sized structure.
19351282Sdimstruct MapPlatformData {};
20351282Sdim
21351282Sdim#if SCUDO_ANDROID
22351282Sdim
23351282Sdim#if defined(__aarch64__)
24351282Sdim#define __get_tls()                                                            \
25351282Sdim  ({                                                                           \
26351282Sdim    void **__v;                                                                \
27351282Sdim    __asm__("mrs %0, tpidr_el0" : "=r"(__v));                                  \
28351282Sdim    __v;                                                                       \
29351282Sdim  })
30351282Sdim#elif defined(__arm__)
31351282Sdim#define __get_tls()                                                            \
32351282Sdim  ({                                                                           \
33351282Sdim    void **__v;                                                                \
34351282Sdim    __asm__("mrc p15, 0, %0, c13, c0, 3" : "=r"(__v));                         \
35351282Sdim    __v;                                                                       \
36351282Sdim  })
37351282Sdim#elif defined(__i386__)
38351282Sdim#define __get_tls()                                                            \
39351282Sdim  ({                                                                           \
40351282Sdim    void **__v;                                                                \
41351282Sdim    __asm__("movl %%gs:0, %0" : "=r"(__v));                                    \
42351282Sdim    __v;                                                                       \
43351282Sdim  })
44351282Sdim#elif defined(__x86_64__)
45351282Sdim#define __get_tls()                                                            \
46351282Sdim  ({                                                                           \
47351282Sdim    void **__v;                                                                \
48351282Sdim    __asm__("mov %%fs:0, %0" : "=r"(__v));                                     \
49351282Sdim    __v;                                                                       \
50351282Sdim  })
51351282Sdim#else
52351282Sdim#error "Unsupported architecture."
53351282Sdim#endif
54351282Sdim
55351282Sdim// The Android Bionic team has allocated a TLS slot for sanitizers starting
56351282Sdim// with Q, given that Android currently doesn't support ELF TLS. It is used to
57351282Sdim// store sanitizer thread specific data.
58360784Sdimstatic const int TLS_SLOT_SANITIZER = 6;
59351282Sdim
60351282SdimALWAYS_INLINE uptr *getAndroidTlsPtr() {
61351282Sdim  return reinterpret_cast<uptr *>(&__get_tls()[TLS_SLOT_SANITIZER]);
62351282Sdim}
63351282Sdim
64351282Sdim#endif // SCUDO_ANDROID
65351282Sdim
66351282Sdim} // namespace scudo
67351282Sdim
68351282Sdim#endif // SCUDO_LINUX
69351282Sdim
70351282Sdim#endif // SCUDO_LINUX_H_
71