Skip to content

Commit

Permalink
Added some interception macros that work on linux and macos
Browse files Browse the repository at this point in the history
  • Loading branch information
drowaudio committed May 23, 2024
1 parent 7e29408 commit 4a87fe0
Showing 1 changed file with 71 additions and 0 deletions.
71 changes: 71 additions & 0 deletions src/interception.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#pragma once

//==============================================================================
// 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.
//===----------------------------------------------------------------------===//

#ifdef __linux__
#define INTERCEPTOR_ATTRIBUTE

#define INTERCEPTOR(ret_type, func, ...) \
extern "C" INTERCEPTOR_ATTRIBUTE ret_type func(__VA_ARGS__)

#define INTERCEPT_FUNCTION(ret_type, func, ...) static auto real = (ret_type (*)(__VA_ARGS__))dlsym(RTLD_NEXT, #func);

#define REAL(func, ...) real __VA_ARGS__
#elif __APPLE__
using uptr = size_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<const uptr>(WRAP(func_name)), \
reinterpret_cast<const uptr>(func_name) } \
}

#define WRAP(x) wrap_##x
#define TRAMPOLINE(x) WRAP(x)
#define INTERCEPTOR_ATTRIBUTE
#define DECLARE_WRAPPER(ret_type, func, ...)

// #define REAL(func, ...) WRAP(func) (__VA_ARGS__)
#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__)

#define INTERCEPT_FUNCTION(...)
#endif

0 comments on commit 4a87fe0

Please sign in to comment.