From 8880751a6e76773ac6616957a2990e43fe212d37 Mon Sep 17 00:00:00 2001
From: Alberto Bertogli <albertito@blitiri.com.ar>
Date: Sun, 14 Jun 2009 22:22:19 -0300
Subject: [PATCH 23/48] 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              |    8 ++++----
 preload/codegen.h              |   15 ++++++++++-----
 preload/modules/posix.custom.c |   14 +++++++++-----
 3 files changed, 23 insertions(+), 14 deletions(-)

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);
-- 
1.6.2.2.646.gb214

