diff --git a/src/lib_rt_check.cpp b/src/lib_rt_check.cpp index 948d877..d69b180 100644 --- a/src/lib_rt_check.cpp +++ b/src/lib_rt_check.cpp @@ -1,50 +1,9 @@ #include -#include -#include -#include #include -#include -#include #include "lib_rt_check.h" +#include "interception.h" -// namespace rt_check -// { -// std::atomic& get_error_mode_flag() -// { -// static std::atomic em { error_mode::exit }; -// return em; -// } -// -// void set_error_mode (error_mode em) -// { -// get_error_mode_flag().store (em, std::memory_order_release); -// } -// -// error_mode get_error_mode() -// { -// return get_error_mode_flag().load (std::memory_order_acquire); -// } -// } - -// Pointer to the real pthread_mutex_lock function -// static int (*real_pthread_mutex_lock)(pthread_mutex_t*); - -// // Interposed function -// extern "C" int pthread_mutex_lock(pthread_mutex_t *mutex) -// { -// printf("Locking mutex at %p\n", mutex); -// int result = real_pthread_mutex_lock(mutex); -// printf("Mutex at %p locked\n", mutex); -// return result; -// } - -// // Load the real pthread_mutex_lock function -// __attribute__((constructor)) -// void load_real_pthread_mutex_lock() -// { - // real_pthread_mutex_lock = (int (*)(pthread_mutex_t *))dlsym(RTLD_NEXT, "pthread_mutex_lock"); -// } inline void log_function_if_realtime_context (const char* function_name) { @@ -61,90 +20,112 @@ inline void log_function_if_realtime_context (const char* function_name) //============================================================================== // memory //============================================================================== -extern "C" void *malloc(size_t size) +// extern "C" void *malloc(size_t size) +// { +// log_function_if_realtime_context (__func__); +// +// static auto real = (void* (*)(size_t))dlsym(RTLD_NEXT, "malloc"); +// return real(size); +// } + + +#ifndef __APPLE__ +INTERCEPTOR(void*, malloc, size_t size) { log_function_if_realtime_context (__func__); + INTERCEPT_FUNCTION(void*, malloc, size_t); - static auto real = (void* (*)(size_t))dlsym(RTLD_NEXT, "malloc"); - return real(size); + return REAL(malloc)(size); } +#endif + -extern "C" void *calloc(size_t size, size_t item_size) +INTERCEPTOR(void*, calloc, size_t size, size_t item_size) { log_function_if_realtime_context (__func__); - static auto real = (void* (*)(size_t, size_t))dlsym(RTLD_NEXT, "calloc"); - return real(size, item_size); + INTERCEPT_FUNCTION(void*, calloc, size_t, size_t); + return REAL(calloc)(size, item_size); } -extern "C" void *realloc(void *ptr, size_t new_size) +INTERCEPTOR(void*, realloc, void *ptr, size_t new_size) { log_function_if_realtime_context (__func__); - static auto real = (void* (*)(void*, size_t))dlsym(RTLD_NEXT, "realloc"); - return real(ptr, new_size); + INTERCEPT_FUNCTION(void*, realloc, void*, size_t); + return REAL(realloc)(ptr, new_size); } -extern "C" void *valloc(size_t size) +INTERCEPTOR(void*, valloc, size_t size) { log_function_if_realtime_context (__func__); - static auto real = (void* (*)(size_t))dlsym(RTLD_NEXT, "valloc"); - return real(size); + INTERCEPT_FUNCTION(void*, valloc, size_t); + return REAL(valloc)(size); } -extern "C" void free(void* ptr) +INTERCEPTOR(void, free, void* ptr) { log_function_if_realtime_context (__func__); + INTERCEPT_FUNCTION(void, free, void*); - static auto real = (void (*)(void*))dlsym(RTLD_NEXT, "free"); - return real(ptr); + return REAL(free)(ptr); } -extern "C" int posix_memalign(void **memptr, size_t alignment, size_t size) +INTERCEPTOR(int, posix_memalign, void **memptr, size_t alignment, size_t size) { log_function_if_realtime_context (__func__); - static auto real = (int (*)(void**, size_t, size_t))dlsym(RTLD_NEXT, "posix_memalign"); - return real(memptr, alignment, size); + INTERCEPT_FUNCTION(int, posix_memalign, void**, size_t, size_t); + return REAL(posix_memalign)(memptr, alignment, size); } -extern "C" void *mmap(void* addr, size_t length, int prot, int flags, - int fd, off_t offset) +INTERCEPTOR(void *, mmap, void* addr, size_t length, int prot, int flags, int fd, off_t offset) { log_function_if_realtime_context (__func__); - static auto real = (void* (*)(void*, size_t, int, int, int, off_t))dlsym(RTLD_NEXT, "mmap"); - return real(addr, length, prot, flags, fd, offset); + INTERCEPT_FUNCTION(void*, mmap, void*, size_t, int, int, int, off_t); + return REAL(mmap)(addr, length, prot, flags, fd, offset); } -extern "C" int munmap(void* addr, size_t length) +INTERCEPTOR(int, munmap, void* addr, size_t length) { log_function_if_realtime_context (__func__); - static auto real = (int (*)(void*, size_t))dlsym(RTLD_NEXT, "munmap"); - return real(addr, length); + INTERCEPT_FUNCTION(int, munmap, void*, size_t); + return REAL(munmap)(addr, length); } -// //============================================================================== -// // threads -// //============================================================================== -extern "C" int pthread_mutex_lock(pthread_mutex_t *mutex) + +//============================================================================== +// threads +//============================================================================== +INTERCEPTOR(int, pthread_mutex_lock, pthread_mutex_t *mutex) { log_function_if_realtime_context (__func__); - static auto real_pthread_mutex_lock = (int (*)(pthread_mutex_t *))dlsym(RTLD_NEXT, "pthread_mutex_lock"); - return real_pthread_mutex_lock(mutex); + INTERCEPT_FUNCTION(int, pthread_mutex_lock, pthread_mutex_t*); + return REAL(pthread_mutex_lock)(mutex); } -extern "C" int pthread_mutex_unlock(pthread_mutex_t *mutex) +INTERCEPTOR(int, pthread_mutex_unlock, pthread_mutex_t *mutex) { log_function_if_realtime_context (__func__); - static auto real_pthread_mutex_unlock = (int (*)(pthread_mutex_t *))dlsym(RTLD_NEXT, "pthread_mutex_unlock");; - return real_pthread_mutex_unlock(mutex); + INTERCEPT_FUNCTION(int, pthread_mutex_unlock, pthread_mutex_t*); + return REAL(pthread_mutex_unlock)(mutex); } +#ifndef __APPLE__ +INTERCEPTOR(int, futex, int *uaddr, int op, int val, const struct timespec *timeout, int *uaddr2, int val3) +{ + log_function_if_realtime_context (__func__); + + INTERCEPT_FUNCTION(int, futex, int*, int, int, const struct timespec*, int*, int); + return REAL(futex)(uaddr, op, val, timeout, uaddr2, val3); +} +#endif + //============================================================================== // sleep //============================================================================== @@ -195,36 +176,36 @@ extern "C" int fstat(int fd, struct stat *statbuf) extern "C" int open(const char *path, int oflag, ...) { log_function_if_realtime_context (__func__); - + va_list args; va_start(args, oflag); static auto real_open = (int (*)(const char*, int, ...))dlsym(RTLD_NEXT, "open"); auto result = real_open (path, oflag, args); va_end(args); - + return result; } extern "C" FILE* fopen(const char *path, const char *mode) { log_function_if_realtime_context (__func__); - + static auto real_fopen = (FILE* (*)(const char*, const char*))dlsym(RTLD_NEXT, "fopen"); auto result = real_fopen (path, mode); - + return result; } extern "C" int openat(int fd, const char *path, int oflag, ...) { log_function_if_realtime_context (__func__); - + va_list args; va_start(args, oflag); static auto real_openat = (int (*)(int, const char*, int, ...))dlsym(RTLD_NEXT, "openat"); auto result = real_openat (fd, path, oflag, args); va_end(args); - + return result; } @@ -232,10 +213,26 @@ extern "C" int openat(int fd, const char *path, int oflag, ...) //============================================================================== // system //============================================================================== +extern "C" long schedule(void) +{ + log_function_if_realtime_context (__func__); + + static auto real = (long (*)(void))dlsym(RTLD_NEXT, "schedule"); + return real(); +} + +extern "C" long context_switch(struct task_struct *prev, struct task_struct *next) +{ + log_function_if_realtime_context (__func__); + + static auto real = (long (*)(struct task_struct *, struct task_struct *))dlsym(RTLD_NEXT, "context_switch"); + return real(prev, next); +} + extern "C" long int syscall(long int sid, ...) { log_function_if_realtime_context (__func__); - + va_list args; va_start(args, sid); static auto real_syscall = (long (*)(long, ...))dlsym(RTLD_NEXT, "syscall"); @@ -244,125 +241,15 @@ extern "C" long int syscall(long int sid, ...) return real_syscall (sid); } -// The following is extracted from LLVM: -//===-- interception.h ------------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file is a part of AddressSanitizer, an address sanity checker. -// -// Machinery for providing replacements/wrappers for system functions. -//===----------------------------------------------------------------------===// - //============================================================================== -// macOS +// init //============================================================================== -// #ifdef __APPLE__ -// #include -// -// #define SIZE_T size_t; -// -// using uptr = SIZE_T; -// // using sptr = SSIZE_T; -// // using sptr = PTRDIFF_T; -// // using s64 = INTMAX_T; -// // using u64 = UINTMAX_T; -// // using OFF_T = OFF_T; -// // using OFF64_T = OFF64_T; -// -// struct interpose_substitution { -// const uptr replacement; -// const uptr original; -// }; -// -// // For a function foo() create a global pair of pointers { wrap_foo, foo } in -// // the __DATA,__interpose section. -// // As a result all the calls to foo() will be routed to wrap_foo() at runtime. -// #define INTERPOSER(func_name) __attribute__((used)) \ -// const interpose_substitution substitution_##func_name[] \ -// __attribute__((section("__DATA, __interpose"))) = { \ -// { reinterpret_cast(WRAP(func_name)), \ -// reinterpret_cast(func_name) } \ -// } -// -// // For a function foo() and a wrapper function bar() create a global pair -// // of pointers { bar, foo } in the __DATA,__interpose section. -// // As a result all the calls to foo() will be routed to bar() at runtime. -// #define INTERPOSER_2(func_name, wrapper_name) __attribute__((used)) \ -// const interpose_substitution substitution_##func_name[] \ -// __attribute__((section("__DATA, __interpose"))) = { \ -// { reinterpret_cast(wrapper_name), \ -// reinterpret_cast(func_name) } \ -// } -// -// # define WRAP(x) wrap_##x -// # define TRAMPOLINE(x) WRAP(x) -// # define INTERCEPTOR_ATTRIBUTE -// # define DECLARE_WRAPPER(ret_type, func, ...) -// -// # define REAL(x) x -// # define DECLARE_REAL(ret_type, func, ...) \ -// extern "C" ret_type func(__VA_ARGS__); -// # define ASSIGN_REAL(x, y) -// -// #define INTERCEPTOR_ZZZ(suffix, ret_type, func, ...) \ -// extern "C" ret_type func(__VA_ARGS__) suffix; \ -// extern "C" ret_type WRAP(func)(__VA_ARGS__); \ -// INTERPOSER(func); \ -// extern "C" INTERCEPTOR_ATTRIBUTE ret_type WRAP(func)(__VA_ARGS__) -// -// #define INTERCEPTOR(ret_type, func, ...) \ -// INTERCEPTOR_ZZZ(/*no symbol variants*/, ret_type, func, __VA_ARGS__) -// -// #define INTERCEPTOR_WITH_SUFFIX(ret_type, func, ...) \ -// INTERCEPTOR_ZZZ(__DARWIN_ALIAS_C(func), ret_type, func, __VA_ARGS__) -// -// // Override |overridee| with |overrider|. -// #define OVERRIDE_FUNCTION(overridee, overrider) \ -// INTERPOSER_2(overridee, WRAP(overrider)) -// -// INTERCEPTOR(void, free, void *ptr) -// { -// if (ptr != NULL) -// log_function_if_realtime_context (__func__); -// -// return REAL(free)(ptr); -// } -// -// INTERCEPTOR(void*, malloc, size_t size) -// { -// log_function_if_realtime_context (__func__); -// return REAL(malloc)(size); -// } -// -// INTERCEPTOR(int, stat, const char* pathname, struct stat* statbuf) -// { -// log_function_if_realtime_context (__func__); -// return REAL(stat)(pathname, statbuf); -// } -// -// #define INTERCEPT_FUNCTION_MAC(func) -// #define INTERCEPT_FUNCTION_VER_MAC(func, symver) -// -// # define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_MAC(func) -// # define INTERCEPT_FUNCTION_VER(func, symver) \ -// INTERCEPT_FUNCTION_VER_MAC(func, symver) -// -// //============================================================================== -// // init -// //============================================================================== -// __attribute__((constructor)) -// void init() -// { -// INTERCEPT_FUNCTION(malloc) -// INTERCEPT_FUNCTION(free) -// INTERCEPT_FUNCTION(stat) -// printf ("Hello librt_check!\n"); -// } -// -// #endif //__APPLE__ +__attribute__((constructor)) +void init() +{ + // INTERCEPT_FUNCTION(malloc); + // INTERCEPT_FUNCTION(free) + // INTERCEPT_FUNCTION(stat) + printf ("Hello librt_check!\n"); +}