summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--CMakeLists.txt35
-rw-r--r--defines.h11
-rw-r--r--print.c9
-rw-r--r--print.h6
-rw-r--r--shim.c27
-rw-r--r--wrap.c19
-rw-r--r--wrap.h21
8 files changed, 129 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..378eac2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+build
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..a7dd4ed
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,35 @@
+cmake_minimum_required(VERSION 3.10)
+
+set(CFLAGS
+ -Wall -Wextra -Wfloat-equal
+ -Wstrict-overflow=5 -Wunreachable-code
+ -Wundef -Wcast-qual -Wconversion
+ -Wswitch-default -Wmissing-include-dirs
+ -Wshadow -Wstrict-aliasing -Winit-self
+ -Wcast-align -Wpointer-arith
+ -Wno-unused-parameter -Wuninitialized
+ -D_GNU_SOURCE
+)
+
+list(APPEND
+ SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/print.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/print.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/shim.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wrap.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/wrap.h
+)
+
+project(shim)
+add_library(shim_objects OBJECT ${SOURCES})
+set_property(TARGET shim_objects PROPERTY POSITION_INDEPENDENT_CODE ON)
+set_property(TARGET shim_objects PROPERTY C_VISIBILITY_PRESET hidden)
+set_property(TARGET shim_objects PROPERTY VISIBILITY_INLINES_HIDDEN ON)
+target_compile_options(shim_objects PUBLIC ${CFLAGS})
+
+add_library(shim SHARED $<TARGET_OBJECTS:shim_objects>)
+target_link_libraries(shim LINK_PUBLIC ${CMAKE_DL_LIBS})
+
+add_library(shim_static STATIC $<TARGET_OBJECTS:shim_objects>)
+
+
diff --git a/defines.h b/defines.h
new file mode 100644
index 0000000..6c04a4e
--- /dev/null
+++ b/defines.h
@@ -0,0 +1,11 @@
+#ifndef DEFINES_H
+#define DEFINES_H
+
+#ifndef NDEBUG
+#define DEBUG
+#endif
+
+#define STR(x) #x
+#define XSTR(x) STR(x)
+
+#endif /* DEFINES_H */
diff --git a/print.c b/print.c
new file mode 100644
index 0000000..5b1be08
--- /dev/null
+++ b/print.c
@@ -0,0 +1,9 @@
+#include <string.h>
+#include <unistd.h>
+
+#include "print.h"
+
+void print(const char* str, ...)
+{
+ write(STDOUT_FILENO, str, strlen(str));
+}
diff --git a/print.h b/print.h
new file mode 100644
index 0000000..08099c5
--- /dev/null
+++ b/print.h
@@ -0,0 +1,6 @@
+#ifndef PRINT_H
+#define PRINT_H
+
+void print(const char* str, ...);
+
+#endif \ No newline at end of file
diff --git a/shim.c b/shim.c
new file mode 100644
index 0000000..b89c748
--- /dev/null
+++ b/shim.c
@@ -0,0 +1,27 @@
+#include <stdlib.h>
+
+#include "print.h"
+#include "wrap.h"
+
+#pragma GCC visibility push(default)
+
+void* malloc(size_t size) {
+ return REAL(malloc)(size);
+}
+
+void free(void* ptr)
+{
+ return REAL(free)(ptr);
+}
+
+void* calloc(size_t nmemb, size_t size)
+{
+ return REAL(calloc)(nmemb, size);
+}
+
+void* realloc(void *ptr, size_t size)
+{
+ return REAL(realloc)(ptr, size);
+}
+
+#pragma GCC visibility pop
diff --git a/wrap.c b/wrap.c
new file mode 100644
index 0000000..5ed0bc8
--- /dev/null
+++ b/wrap.c
@@ -0,0 +1,19 @@
+#include <stddef.h>
+
+#include "wrap.h"
+
+void *(*_REAL(malloc))(size_t size) = NULL;
+void (*_REAL(free))(void *ptr) = NULL;
+void *(*_REAL(calloc))(size_t nmemb, size_t size) = NULL;
+void *(*_REAL(realloc))(void *ptr, size_t size) = NULL;
+
+#ifdef __GNUC__
+void __attribute__((constructor)) __wrap_init()
+{
+ // set the real values up as soon as possible
+ REAL(malloc);
+ REAL(free);
+ REAL(calloc);
+ REAL(realloc);
+}
+#endif
diff --git a/wrap.h b/wrap.h
new file mode 100644
index 0000000..2053efd
--- /dev/null
+++ b/wrap.h
@@ -0,0 +1,21 @@
+#ifndef WRAP_H
+#define WRAP_H
+
+#include <dlfcn.h>
+
+#include "defines.h"
+
+#define _REAL(n) __real_##n
+#define REAL(n) \
+ ({ \
+ if (!_REAL(n)) \
+ _REAL(n) = dlsym(RTLD_NEXT, XSTR(n)); \
+ _REAL(n); \
+ })
+
+extern void *(*_REAL(malloc))(size_t size);
+extern void (*_REAL(free))(void *ptr);
+extern void *(*_REAL(calloc))(size_t nmemb, size_t size);
+extern void *(*_REAL(realloc))(void *ptr, size_t size);
+
+#endif /* WRAP_H */