1//===-- safestack_platform.h ----------------------------------------------===// 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// This file implements platform specific parts of SafeStack runtime. 10// 11//===----------------------------------------------------------------------===// 12 13#ifndef SAFESTACK_PLATFORM_H 14#define SAFESTACK_PLATFORM_H 15 16#include "safestack_util.h" 17#include "sanitizer_common/sanitizer_platform.h" 18 19#include <dlfcn.h> 20#include <stdint.h> 21#include <stdio.h> 22#include <stdlib.h> 23#include <sys/mman.h> 24#include <sys/syscall.h> 25#include <sys/types.h> 26#include <unistd.h> 27 28#if !(SANITIZER_NETBSD || SANITIZER_FREEBSD || SANITIZER_LINUX) 29#error "Support for your platform has not been implemented" 30#endif 31 32#if SANITIZER_NETBSD 33#include <lwp.h> 34 35extern "C" void *__mmap(void *, size_t, int, int, int, int, off_t); 36#endif 37 38#if SANITIZER_FREEBSD 39#include <sys/thr.h> 40#endif 41 42namespace safestack { 43 44#if SANITIZER_NETBSD 45static void *GetRealLibcAddress(const char *symbol) { 46 void *real = dlsym(RTLD_NEXT, symbol); 47 if (!real) 48 real = dlsym(RTLD_DEFAULT, symbol); 49 if (!real) { 50 fprintf(stderr, "safestack GetRealLibcAddress failed for symbol=%s", 51 symbol); 52 abort(); 53 } 54 return real; 55} 56 57#define _REAL(func, ...) real##_##func(__VA_ARGS__) 58#define DEFINE__REAL(ret_type, func, ...) \ 59 static ret_type (*real_##func)(__VA_ARGS__) = NULL; \ 60 if (!real_##func) { \ 61 real_##func = (ret_type(*)(__VA_ARGS__))GetRealLibcAddress(#func); \ 62 } \ 63 SFS_CHECK(real_##func); 64#endif 65 66using ThreadId = uint64_t; 67 68inline ThreadId GetTid() { 69#if SANITIZER_NETBSD 70 DEFINE__REAL(int, _lwp_self); 71 return _REAL(_lwp_self); 72#elif SANITIZER_FREEBSD 73 long Tid; 74 thr_self(&Tid); 75 return Tid; 76#else 77 return syscall(SYS_gettid); 78#endif 79} 80 81inline int TgKill(pid_t pid, ThreadId tid, int sig) { 82#if SANITIZER_NETBSD 83 DEFINE__REAL(int, _lwp_kill, int a, int b); 84 (void)pid; 85 return _REAL(_lwp_kill, tid, sig); 86#elif SANITIZER_FREEBSD 87 return syscall(SYS_thr_kill2, pid, tid, sig); 88#else 89 return syscall(SYS_tgkill, pid, tid, sig); 90#endif 91} 92 93inline void *Mmap(void *addr, size_t length, int prot, int flags, int fd, 94 off_t offset) { 95#if SANITIZER_NETBSD 96 return __mmap(addr, length, prot, flags, fd, 0, offset); 97#elif SANITIZER_FREEBSD && (defined(__aarch64__) || defined(__x86_64__)) 98 return (void *)__syscall(SYS_mmap, addr, length, prot, flags, fd, offset); 99#else 100 return (void *)syscall(SYS_mmap, addr, length, prot, flags, fd, offset); 101#endif 102} 103 104inline int Munmap(void *addr, size_t length) { 105#if SANITIZER_NETBSD 106 DEFINE__REAL(int, munmap, void *a, size_t b); 107 return _REAL(munmap, addr, length); 108#else 109 return syscall(SYS_munmap, addr, length); 110#endif 111} 112 113inline int Mprotect(void *addr, size_t length, int prot) { 114#if SANITIZER_NETBSD 115 DEFINE__REAL(int, mprotect, void *a, size_t b, int c); 116 return _REAL(mprotect, addr, length, prot); 117#else 118 return syscall(SYS_mprotect, addr, length, prot); 119#endif 120} 121 122} // namespace safestack 123 124#endif // SAFESTACK_PLATFORM_H 125