(root)/
gcc-13.2.0/
libsanitizer/
sanitizer_common/
sanitizer_linux.h
       1  //===-- sanitizer_linux.h ---------------------------------------*- C++ -*-===//
       2  //
       3  // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
       4  // See https://llvm.org/LICENSE.txt for license information.
       5  // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
       6  //
       7  //===----------------------------------------------------------------------===//
       8  //
       9  // Linux-specific syscall wrappers and classes.
      10  //
      11  //===----------------------------------------------------------------------===//
      12  #ifndef SANITIZER_LINUX_H
      13  #define SANITIZER_LINUX_H
      14  
      15  #include "sanitizer_platform.h"
      16  #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD ||                \
      17      SANITIZER_SOLARIS
      18  #include "sanitizer_common.h"
      19  #include "sanitizer_internal_defs.h"
      20  #include "sanitizer_platform_limits_freebsd.h"
      21  #include "sanitizer_platform_limits_netbsd.h"
      22  #include "sanitizer_platform_limits_posix.h"
      23  #include "sanitizer_platform_limits_solaris.h"
      24  #include "sanitizer_posix.h"
      25  
      26  struct link_map;  // Opaque type returned by dlopen().
      27  struct utsname;
      28  
      29  namespace __sanitizer {
      30  // Dirent structure for getdents(). Note that this structure is different from
      31  // the one in <dirent.h>, which is used by readdir().
      32  struct linux_dirent;
      33  
      34  struct ProcSelfMapsBuff {
      35    char *data;
      36    uptr mmaped_size;
      37    uptr len;
      38  };
      39  
      40  struct MemoryMappingLayoutData {
      41    ProcSelfMapsBuff proc_self_maps;
      42    const char *current;
      43  };
      44  
      45  void ReadProcMaps(ProcSelfMapsBuff *proc_maps);
      46  
      47  // Syscall wrappers.
      48  uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count);
      49  uptr internal_sigaltstack(const void* ss, void* oss);
      50  uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,
      51      __sanitizer_sigset_t *oldset);
      52  
      53  void SetSigProcMask(__sanitizer_sigset_t *set, __sanitizer_sigset_t *oldset);
      54  struct ScopedBlockSignals {
      55    explicit ScopedBlockSignals(__sanitizer_sigset_t *copy);
      56    ~ScopedBlockSignals();
      57  
      58    ScopedBlockSignals &operator=(const ScopedBlockSignals &) = delete;
      59    ScopedBlockSignals(const ScopedBlockSignals &) = delete;
      60  
      61   private:
      62    __sanitizer_sigset_t saved_;
      63  };
      64  
      65  #  if SANITIZER_GLIBC
      66  uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp);
      67  #endif
      68  
      69  // Linux-only syscalls.
      70  #if SANITIZER_LINUX
      71  uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5);
      72  #    if defined(__x86_64__)
      73  uptr internal_arch_prctl(int option, uptr arg2);
      74  #    endif
      75  // Used only by sanitizer_stoptheworld. Signal handlers that are actually used
      76  // (like the process-wide error reporting SEGV handler) must use
      77  // internal_sigaction instead.
      78  int internal_sigaction_norestorer(int signum, const void *act, void *oldact);
      79  void internal_sigdelset(__sanitizer_sigset_t *set, int signum);
      80  #if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) || \
      81      defined(__powerpc64__) || defined(__s390__) || defined(__i386__) || \
      82      defined(__arm__) || SANITIZER_RISCV64
      83  uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
      84                      int *parent_tidptr, void *newtls, int *child_tidptr);
      85  #endif
      86  int internal_uname(struct utsname *buf);
      87  #elif SANITIZER_FREEBSD
      88  uptr internal_procctl(int type, int id, int cmd, void *data);
      89  void internal_sigdelset(__sanitizer_sigset_t *set, int signum);
      90  #elif SANITIZER_NETBSD
      91  void internal_sigdelset(__sanitizer_sigset_t *set, int signum);
      92  uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg);
      93  #endif  // SANITIZER_LINUX
      94  
      95  // This class reads thread IDs from /proc/<pid>/task using only syscalls.
      96  class ThreadLister {
      97   public:
      98    explicit ThreadLister(pid_t pid);
      99    ~ThreadLister();
     100    enum Result {
     101      Error,
     102      Incomplete,
     103      Ok,
     104    };
     105    Result ListThreads(InternalMmapVector<tid_t> *threads);
     106  
     107   private:
     108    bool IsAlive(int tid);
     109  
     110    pid_t pid_;
     111    int descriptor_ = -1;
     112    InternalMmapVector<char> buffer_;
     113  };
     114  
     115  // Exposed for testing.
     116  uptr ThreadDescriptorSize();
     117  uptr ThreadSelf();
     118  
     119  // Matches a library's file name against a base name (stripping path and version
     120  // information).
     121  bool LibraryNameIs(const char *full_name, const char *base_name);
     122  
     123  // Call cb for each region mapped by map.
     124  void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr));
     125  
     126  // Releases memory pages entirely within the [beg, end] address range.
     127  // The pages no longer count toward RSS; reads are guaranteed to return 0.
     128  // Requires (but does not verify!) that pages are MAP_PRIVATE.
     129  inline void ReleaseMemoryPagesToOSAndZeroFill(uptr beg, uptr end) {
     130    // man madvise on Linux promises zero-fill for anonymous private pages.
     131    // Testing shows the same behaviour for private (but not anonymous) mappings
     132    // of shm_open() files, as long as the underlying file is untouched.
     133    CHECK(SANITIZER_LINUX);
     134    ReleaseMemoryPagesToOS(beg, end);
     135  }
     136  
     137  #if SANITIZER_ANDROID
     138  
     139  #if defined(__aarch64__)
     140  # define __get_tls() \
     141      ({ void** __v; __asm__("mrs %0, tpidr_el0" : "=r"(__v)); __v; })
     142  #elif defined(__arm__)
     143  # define __get_tls() \
     144      ({ void** __v; __asm__("mrc p15, 0, %0, c13, c0, 3" : "=r"(__v)); __v; })
     145  #elif defined(__mips__)
     146  // On mips32r1, this goes via a kernel illegal instruction trap that's
     147  // optimized for v1.
     148  # define __get_tls() \
     149      ({ register void** __v asm("v1"); \
     150         __asm__(".set    push\n" \
     151                 ".set    mips32r2\n" \
     152                 "rdhwr   %0,$29\n" \
     153                 ".set    pop\n" : "=r"(__v)); \
     154         __v; })
     155  #elif defined(__i386__)
     156  # define __get_tls() \
     157      ({ void** __v; __asm__("movl %%gs:0, %0" : "=r"(__v)); __v; })
     158  #elif defined(__x86_64__)
     159  # define __get_tls() \
     160      ({ void** __v; __asm__("mov %%fs:0, %0" : "=r"(__v)); __v; })
     161  #else
     162  #error "Unsupported architecture."
     163  #endif
     164  
     165  // The Android Bionic team has allocated a TLS slot for sanitizers starting
     166  // with Q, given that Android currently doesn't support ELF TLS. It is used to
     167  // store sanitizer thread specific data.
     168  static const int TLS_SLOT_SANITIZER = 6;
     169  
     170  ALWAYS_INLINE uptr *get_android_tls_ptr() {
     171    return reinterpret_cast<uptr *>(&__get_tls()[TLS_SLOT_SANITIZER]);
     172  }
     173  
     174  #endif  // SANITIZER_ANDROID
     175  
     176  }  // namespace __sanitizer
     177  
     178  #endif
     179  #endif  // SANITIZER_LINUX_H