git » libfiu » commit 8880751

preload: Use constructor attributes for obtaining original functions

author Alberto Bertogli
2009-06-15 01:22:19 UTC
committer Alberto Bertogli
2009-06-15 02:04:40 UTC
parent aa74075e35f231d7846b75c7d0d63d1bc3fb064f

preload: Use constructor attributes for obtaining original functions

This patch adds a new function to the generated code that is called at
library initialization time (after the codegen constructor) which gets
the libc function pointer to use to access the real function.

That way there is no penalty on each call, and the code looks more tidy.

Signed-off-by: Alberto Bertogli <albertito@blitiri.com.ar>

preload/codegen.c +4 -4
preload/codegen.h +10 -5
preload/modules/posix.custom.c +9 -5

diff --git a/preload/codegen.c b/preload/codegen.c
index 33dbee6..8a9c349 100644
--- a/preload/codegen.c
+++ b/preload/codegen.c
@@ -1,4 +1,5 @@
 
+#include <stdio.h>
 #include <dlfcn.h>
 #include "codegen.h"
 
@@ -8,17 +9,16 @@ void *_fiu_libc;
 /* Recursion counter, per-thread */
 int __thread _fiu_called;
 
-static int __attribute__((constructor)) init(void)
+static void __attribute__((constructor(200))) _fiu_init(void)
 {
 	_fiu_called = 0;
 
 	_fiu_libc = dlopen("libc.so.6", RTLD_NOW);
 	if (_fiu_libc == NULL) {
-		printd("Error loading libc: %s\n", dlerror());
-		return 0;
+		printf("Error loading libc: %s\n", dlerror());
+		return;
 	}
 
 	printd("done\n");
-	return 1;
 }
 
diff --git a/preload/codegen.h b/preload/codegen.h
index 245a432..bcae5d9 100644
--- a/preload/codegen.h
+++ b/preload/codegen.h
@@ -13,7 +13,7 @@ extern void *_fiu_libc;
 extern int __thread _fiu_called;
 
 /* Useful macros for recursion and debugging */
-#if 0
+#if 1
 	#define rec_inc() do { _fiu_called++; } while(0)
 	#define rec_dec() do { _fiu_called--; } while(0)
 	#define printd(...) do { } while(0)
@@ -58,15 +58,20 @@ extern int __thread _fiu_called;
 /* Generates the common top of the wrapped function */
 #define mkwrap_top(RTYPE, NAME, PARAMS, PARAMSN, PARAMST)	\
 	static RTYPE (*_fiu_orig_##NAME) PARAMS = NULL;		\
+								\
+	static void __attribute__((constructor(201))) _fiu_init_##NAME(void) \
+	{							\
+		rec_inc();					\
+		_fiu_orig_##NAME = (RTYPE (*) PARAMST)		\
+				dlsym(_fiu_libc, #NAME);	\
+		rec_dec();					\
+	}							\
+								\
 	RTYPE NAME PARAMS					\
 	{ 							\
 		RTYPE r;					\
 		int fstatus;					\
 								\
-		/* cast it just to be sure */			\
-		if (_fiu_orig_##NAME == NULL)			\
-			_fiu_orig_##NAME = (RTYPE (*) PARAMST) dlsym(_fiu_libc, #NAME); \
-								\
 		if (_fiu_called) {				\
 			printd("orig\n");			\
 			return (*_fiu_orig_##NAME) PARAMSN;	\
diff --git a/preload/modules/posix.custom.c b/preload/modules/posix.custom.c
index 43ae6ea..e85adee 100644
--- a/preload/modules/posix.custom.c
+++ b/preload/modules/posix.custom.c
@@ -17,6 +17,15 @@
 /* Wrapper for open(), we can't generate it because it has a variable number
  * of arguments */
 static int (*_fiu_orig_open) (const char *pathname, int flags, ...) = NULL;
+
+static void __attribute__((constructor(201))) _fiu_init_open(void)
+{
+	rec_inc();
+	_fiu_orig_open = (int (*) (const char *, int, ...))
+			 dlsym(_fiu_libc, "open");
+	rec_dec();
+}
+
 int open(const char *pathname, int flags, ...)
 {
 	int r;
@@ -36,11 +45,6 @@ int open(const char *pathname, int flags, ...)
 		mode = 0;
 	}
 
-	/* cast it just to be sure */
-	if (_fiu_orig_open == NULL)
-		_fiu_orig_open = (int (*) (const char *, int, ...)) \
-				dlsym(_fiu_libc, "open");
-
 	if (_fiu_called) {
 		printd("orig\n");
 		return (*_fiu_orig_open) (pathname, flags, mode);