xref: /openbsd-src/gnu/llvm/compiler-rt/lib/safestack/safestack_platform.h (revision 810390e339a5425391477d5d41c78d7cab2424ac)
13cab2bb3Spatrick //===-- safestack_platform.h ----------------------------------------------===//
23cab2bb3Spatrick //
33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information.
53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63cab2bb3Spatrick //
73cab2bb3Spatrick //===----------------------------------------------------------------------===//
83cab2bb3Spatrick //
93cab2bb3Spatrick // This file implements platform specific parts of SafeStack runtime.
103cab2bb3Spatrick //
113cab2bb3Spatrick //===----------------------------------------------------------------------===//
123cab2bb3Spatrick 
133cab2bb3Spatrick #ifndef SAFESTACK_PLATFORM_H
143cab2bb3Spatrick #define SAFESTACK_PLATFORM_H
153cab2bb3Spatrick 
163cab2bb3Spatrick #include "safestack_util.h"
173cab2bb3Spatrick #include "sanitizer_common/sanitizer_platform.h"
183cab2bb3Spatrick 
193cab2bb3Spatrick #include <dlfcn.h>
203cab2bb3Spatrick #include <stdint.h>
213cab2bb3Spatrick #include <stdio.h>
223cab2bb3Spatrick #include <stdlib.h>
233cab2bb3Spatrick #include <sys/mman.h>
243cab2bb3Spatrick #include <sys/syscall.h>
253cab2bb3Spatrick #include <sys/types.h>
263cab2bb3Spatrick #include <unistd.h>
273cab2bb3Spatrick 
283cab2bb3Spatrick #if !(SANITIZER_NETBSD || SANITIZER_FREEBSD || SANITIZER_LINUX)
293cab2bb3Spatrick #error "Support for your platform has not been implemented"
303cab2bb3Spatrick #endif
313cab2bb3Spatrick 
323cab2bb3Spatrick #if SANITIZER_NETBSD
333cab2bb3Spatrick #include <lwp.h>
343cab2bb3Spatrick 
353cab2bb3Spatrick extern "C" void *__mmap(void *, size_t, int, int, int, int, off_t);
363cab2bb3Spatrick #endif
373cab2bb3Spatrick 
383cab2bb3Spatrick #if SANITIZER_FREEBSD
393cab2bb3Spatrick #include <sys/thr.h>
403cab2bb3Spatrick #endif
413cab2bb3Spatrick 
423cab2bb3Spatrick namespace safestack {
433cab2bb3Spatrick 
443cab2bb3Spatrick #if SANITIZER_NETBSD
GetRealLibcAddress(const char * symbol)453cab2bb3Spatrick static void *GetRealLibcAddress(const char *symbol) {
463cab2bb3Spatrick   void *real = dlsym(RTLD_NEXT, symbol);
473cab2bb3Spatrick   if (!real)
483cab2bb3Spatrick     real = dlsym(RTLD_DEFAULT, symbol);
493cab2bb3Spatrick   if (!real) {
503cab2bb3Spatrick     fprintf(stderr, "safestack GetRealLibcAddress failed for symbol=%s",
513cab2bb3Spatrick             symbol);
523cab2bb3Spatrick     abort();
533cab2bb3Spatrick   }
543cab2bb3Spatrick   return real;
553cab2bb3Spatrick }
563cab2bb3Spatrick 
573cab2bb3Spatrick #define _REAL(func, ...) real##_##func(__VA_ARGS__)
583cab2bb3Spatrick #define DEFINE__REAL(ret_type, func, ...)                              \
593cab2bb3Spatrick   static ret_type (*real_##func)(__VA_ARGS__) = NULL;                  \
603cab2bb3Spatrick   if (!real_##func) {                                                  \
613cab2bb3Spatrick     real_##func = (ret_type(*)(__VA_ARGS__))GetRealLibcAddress(#func); \
623cab2bb3Spatrick   }                                                                    \
633cab2bb3Spatrick   SFS_CHECK(real_##func);
643cab2bb3Spatrick #endif
653cab2bb3Spatrick 
663cab2bb3Spatrick using ThreadId = uint64_t;
673cab2bb3Spatrick 
GetTid()683cab2bb3Spatrick inline ThreadId GetTid() {
693cab2bb3Spatrick #if SANITIZER_NETBSD
703cab2bb3Spatrick   DEFINE__REAL(int, _lwp_self);
713cab2bb3Spatrick   return _REAL(_lwp_self);
723cab2bb3Spatrick #elif SANITIZER_FREEBSD
733cab2bb3Spatrick   long Tid;
743cab2bb3Spatrick   thr_self(&Tid);
753cab2bb3Spatrick   return Tid;
763cab2bb3Spatrick #else
773cab2bb3Spatrick   return syscall(SYS_gettid);
783cab2bb3Spatrick #endif
793cab2bb3Spatrick }
803cab2bb3Spatrick 
TgKill(pid_t pid,ThreadId tid,int sig)813cab2bb3Spatrick inline int TgKill(pid_t pid, ThreadId tid, int sig) {
823cab2bb3Spatrick #if SANITIZER_NETBSD
833cab2bb3Spatrick   DEFINE__REAL(int, _lwp_kill, int a, int b);
843cab2bb3Spatrick   (void)pid;
853cab2bb3Spatrick   return _REAL(_lwp_kill, tid, sig);
863cab2bb3Spatrick #elif SANITIZER_FREEBSD
873cab2bb3Spatrick   return syscall(SYS_thr_kill2, pid, tid, sig);
883cab2bb3Spatrick #else
893cab2bb3Spatrick   return syscall(SYS_tgkill, pid, tid, sig);
903cab2bb3Spatrick #endif
913cab2bb3Spatrick }
923cab2bb3Spatrick 
Mmap(void * addr,size_t length,int prot,int flags,int fd,off_t offset)933cab2bb3Spatrick inline void *Mmap(void *addr, size_t length, int prot, int flags, int fd,
943cab2bb3Spatrick                   off_t offset) {
953cab2bb3Spatrick #if SANITIZER_NETBSD
963cab2bb3Spatrick   return __mmap(addr, length, prot, flags, fd, 0, offset);
97*810390e3Srobert #elif SANITIZER_FREEBSD && (defined(__aarch64__) || defined(__x86_64__))
983cab2bb3Spatrick   return (void *)__syscall(SYS_mmap, addr, length, prot, flags, fd, offset);
993cab2bb3Spatrick #else
1003cab2bb3Spatrick   return (void *)syscall(SYS_mmap, addr, length, prot, flags, fd, offset);
1013cab2bb3Spatrick #endif
1023cab2bb3Spatrick }
1033cab2bb3Spatrick 
Munmap(void * addr,size_t length)1043cab2bb3Spatrick inline int Munmap(void *addr, size_t length) {
1053cab2bb3Spatrick #if SANITIZER_NETBSD
1063cab2bb3Spatrick   DEFINE__REAL(int, munmap, void *a, size_t b);
1073cab2bb3Spatrick   return _REAL(munmap, addr, length);
1083cab2bb3Spatrick #else
1093cab2bb3Spatrick   return syscall(SYS_munmap, addr, length);
1103cab2bb3Spatrick #endif
1113cab2bb3Spatrick }
1123cab2bb3Spatrick 
Mprotect(void * addr,size_t length,int prot)1133cab2bb3Spatrick inline int Mprotect(void *addr, size_t length, int prot) {
1143cab2bb3Spatrick #if SANITIZER_NETBSD
1153cab2bb3Spatrick   DEFINE__REAL(int, mprotect, void *a, size_t b, int c);
1163cab2bb3Spatrick   return _REAL(mprotect, addr, length, prot);
1173cab2bb3Spatrick #else
1183cab2bb3Spatrick   return syscall(SYS_mprotect, addr, length, prot);
1193cab2bb3Spatrick #endif
1203cab2bb3Spatrick }
1213cab2bb3Spatrick 
1223cab2bb3Spatrick }  // namespace safestack
1233cab2bb3Spatrick 
1243cab2bb3Spatrick #endif  // SAFESTACK_PLATFORM_H
125