author | Alberto Bertogli
<albertito@blitiri.com.ar> 2009-10-15 02:21:08 UTC |
committer | Alberto Bertogli
<albertito@blitiri.com.ar> 2009-10-15 02:21:08 UTC |
parent | 0a45ab3aa3660b3d7e9116336aa164ac28f21ece |
preload/posix/codegen.c | +15 | -4 |
preload/posix/codegen.h | +8 | -0 |
preload/posix/modules/posix.custom.c | +4 | -0 |
diff --git a/preload/posix/codegen.c b/preload/posix/codegen.c index 0f078e8..71644c5 100644 --- a/preload/posix/codegen.c +++ b/preload/posix/codegen.c @@ -9,7 +9,7 @@ void *_fiu_libc; /* Recursion counter, per-thread */ -int __thread _fiu_called; +int __thread _fiu_called = 0; /* Let the user know if there is no constructor priorities support, just in * case there are bugs when building/running without them */ @@ -17,17 +17,28 @@ int __thread _fiu_called; #warning "Building without using constructor priorities" #endif -static void constructor_attr(200) _fiu_init(void) +void constructor_attr(200) _fiu_init(void) { - _fiu_called = 0; + static int initialized = 0; + + /* When built without constructor priorities, we could be called more + * than once during the initialization phase: one because we're marked + * as a constructor, and another when one of the other constructors + * sees that it doesn't have _fiu_libc set. */ + + printd("_fiu_init() start (%d)\n", initialized); + if (initialized) + goto exit; _fiu_libc = dlopen("libc.so.6", RTLD_NOW); if (_fiu_libc == NULL) { fprintf(stderr, "Error loading libc: %s\n", dlerror()); exit(1); } + initialized = 1; - printd("done\n"); +exit: + printd("_fiu_init() done\n"); } /* this runs after all function-specific constructors */ diff --git a/preload/posix/codegen.h b/preload/posix/codegen.h index c90a951..6a3444e 100644 --- a/preload/posix/codegen.h +++ b/preload/posix/codegen.h @@ -8,6 +8,7 @@ /* Pointer to the dynamically loaded library */ extern void *_fiu_libc; +void _fiu_init(void); /* Recursion counter, per-thread */ extern int __thread _fiu_called; @@ -75,6 +76,10 @@ extern int __thread _fiu_called; static void constructor_attr(201) _fiu_init_##NAME(void) \ { \ rec_inc(); \ + \ + if (_fiu_libc == NULL) \ + _fiu_init(); \ + \ _fiu_orig_##NAME = (RTYPE (*) PARAMST) \ dlsym(_fiu_libc, #NAME); \ rec_dec(); \ @@ -146,6 +151,9 @@ extern int __thread _fiu_called; #define mkwrap_bottom(NAME, PARAMSN) \ \ + if (_fiu_orig_##NAME == NULL) \ + _fiu_init_##NAME(); \ + \ r = (*_fiu_orig_##NAME) PARAMSN; \ \ exit: \ diff --git a/preload/posix/modules/posix.custom.c b/preload/posix/modules/posix.custom.c index 84322a5..5caff6f 100644 --- a/preload/posix/modules/posix.custom.c +++ b/preload/posix/modules/posix.custom.c @@ -21,6 +21,10 @@ static int (*_fiu_orig_open) (const char *pathname, int flags, ...) = NULL; static void constructor_attr(201) _fiu_init_open(void) { rec_inc(); + + if (_fiu_libc == NULL) + _fiu_init(); + _fiu_orig_open = (int (*) (const char *, int, ...)) dlsym(_fiu_libc, "open"); rec_dec();