1351282Sdim//===-- safestack_platform.h ----------------------------------------------===// 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// This file implements platform specific parts of SafeStack runtime. 10351282Sdim// 11351282Sdim//===----------------------------------------------------------------------===// 12351282Sdim 13351282Sdim#ifndef SAFESTACK_PLATFORM_H 14351282Sdim#define SAFESTACK_PLATFORM_H 15351282Sdim 16351282Sdim#include "safestack_util.h" 17351282Sdim#include "sanitizer_common/sanitizer_platform.h" 18351282Sdim 19351282Sdim#include <dlfcn.h> 20351282Sdim#include <stdint.h> 21351282Sdim#include <stdio.h> 22351282Sdim#include <stdlib.h> 23351282Sdim#include <sys/mman.h> 24351282Sdim#include <sys/syscall.h> 25351282Sdim#include <sys/types.h> 26351282Sdim#include <unistd.h> 27351282Sdim 28351282Sdim#if !(SANITIZER_NETBSD || SANITIZER_FREEBSD || SANITIZER_LINUX) 29351282Sdim#error "Support for your platform has not been implemented" 30351282Sdim#endif 31351282Sdim 32351282Sdim#if SANITIZER_NETBSD 33351282Sdim#include <lwp.h> 34351282Sdim 35351282Sdimextern "C" void *__mmap(void *, size_t, int, int, int, int, off_t); 36351282Sdim#endif 37351282Sdim 38351282Sdim#if SANITIZER_FREEBSD 39351282Sdim#include <sys/thr.h> 40351282Sdim#endif 41351282Sdim 42351282Sdimnamespace safestack { 43351282Sdim 44351282Sdim#if SANITIZER_NETBSD 45351282Sdimstatic void *GetRealLibcAddress(const char *symbol) { 46351282Sdim void *real = dlsym(RTLD_NEXT, symbol); 47351282Sdim if (!real) 48351282Sdim real = dlsym(RTLD_DEFAULT, symbol); 49351282Sdim if (!real) { 50351282Sdim fprintf(stderr, "safestack GetRealLibcAddress failed for symbol=%s", 51351282Sdim symbol); 52351282Sdim abort(); 53351282Sdim } 54351282Sdim return real; 55351282Sdim} 56351282Sdim 57351282Sdim#define _REAL(func, ...) real##_##func(__VA_ARGS__) 58351282Sdim#define DEFINE__REAL(ret_type, func, ...) \ 59351282Sdim static ret_type (*real_##func)(__VA_ARGS__) = NULL; \ 60351282Sdim if (!real_##func) { \ 61351282Sdim real_##func = (ret_type(*)(__VA_ARGS__))GetRealLibcAddress(#func); \ 62351282Sdim } \ 63351282Sdim SFS_CHECK(real_##func); 64351282Sdim#endif 65351282Sdim 66351282Sdimusing ThreadId = uint64_t; 67351282Sdim 68351282Sdiminline ThreadId GetTid() { 69351282Sdim#if SANITIZER_NETBSD 70351282Sdim DEFINE__REAL(int, _lwp_self); 71351282Sdim return _REAL(_lwp_self); 72351282Sdim#elif SANITIZER_FREEBSD 73351282Sdim long Tid; 74351282Sdim thr_self(&Tid); 75351282Sdim return Tid; 76351282Sdim#else 77351282Sdim return syscall(SYS_gettid); 78351282Sdim#endif 79351282Sdim} 80351282Sdim 81351282Sdiminline int TgKill(pid_t pid, ThreadId tid, int sig) { 82351282Sdim#if SANITIZER_NETBSD 83351282Sdim DEFINE__REAL(int, _lwp_kill, int a, int b); 84351282Sdim (void)pid; 85351282Sdim return _REAL(_lwp_kill, tid, sig); 86351282Sdim#elif SANITIZER_FREEBSD 87351282Sdim return syscall(SYS_thr_kill2, pid, tid, sig); 88351282Sdim#else 89351282Sdim return syscall(SYS_tgkill, pid, tid, sig); 90351282Sdim#endif 91351282Sdim} 92351282Sdim 93351282Sdiminline void *Mmap(void *addr, size_t length, int prot, int flags, int fd, 94351282Sdim off_t offset) { 95351282Sdim#if SANITIZER_NETBSD 96351282Sdim return __mmap(addr, length, prot, flags, fd, 0, offset); 97351282Sdim#elif defined(__x86_64__) && (SANITIZER_FREEBSD) 98351282Sdim return (void *)__syscall(SYS_mmap, addr, length, prot, flags, fd, offset); 99351282Sdim#else 100351282Sdim return (void *)syscall(SYS_mmap, addr, length, prot, flags, fd, offset); 101351282Sdim#endif 102351282Sdim} 103351282Sdim 104351282Sdiminline int Munmap(void *addr, size_t length) { 105351282Sdim#if SANITIZER_NETBSD 106351282Sdim DEFINE__REAL(int, munmap, void *a, size_t b); 107351282Sdim return _REAL(munmap, addr, length); 108351282Sdim#else 109351282Sdim return syscall(SYS_munmap, addr, length); 110351282Sdim#endif 111351282Sdim} 112351282Sdim 113351282Sdiminline int Mprotect(void *addr, size_t length, int prot) { 114351282Sdim#if SANITIZER_NETBSD 115351282Sdim DEFINE__REAL(int, mprotect, void *a, size_t b, int c); 116351282Sdim return _REAL(mprotect, addr, length, prot); 117351282Sdim#else 118351282Sdim return syscall(SYS_mprotect, addr, length, prot); 119351282Sdim#endif 120351282Sdim} 121351282Sdim 122351282Sdim} // namespace safestack 123351282Sdim 124351282Sdim#endif // SAFESTACK_PLATFORM_H 125