Force strong references to several pthread_* functions which are weakly

referenced to by libgcc.a.

This is needed when linking statically as SVR4 (ie, ELF) behavior is to only
link in a module if it satisfies an undefined strong reference from somewhere.
(this surprises a lot of people) Things are different when using shared libs,
the entire library and its modules and their symbols are available at run-time
(when the weak reference is seen to still be unsatisfied and is satisfied on
the spot), this is not the case with static libs.

Thus one can have a static binary with unresolved week references, and at
run-time dereference a NULL pointer.

Submitted by:	eischen
This commit is contained in:
David E. O'Brien 2001-01-06 06:07:52 +00:00
parent 069154d55f
commit cad1dd7bb4
3 changed files with 96 additions and 0 deletions

View File

@ -54,6 +54,31 @@
#include <pthread.h>
#include "pthread_private.h"
/*
* These are needed when linking statically. All references within
* libgcc (and in the future libc) to these routines are weak, but
* if they are not (strongly) referenced by the application or other
* libraries, then the actual functions will not be loaded.
*/
static void *thread_references[] = {
&pthread_once,
&pthread_key_create,
&pthread_key_delete,
&pthread_getspecific,
&pthread_setspecific,
&pthread_mutex_init,
&pthread_mutex_destroy,
&pthread_mutex_lock,
&pthread_mutex_trylock,
&pthread_mutex_unlock,
&pthread_cond_init,
&pthread_cond_destroy,
&pthread_cond_wait,
&pthread_cond_timedwait,
&pthread_cond_signal,
&pthread_cond_broadcast
};
#ifdef GCC_2_8_MADE_THREAD_AWARE
typedef void *** (*dynamic_handler_allocator)();
extern void __set_dynamic_handler_allocator(dynamic_handler_allocator);
@ -98,6 +123,13 @@ _thread_init(void)
/* Only initialise the threaded application once. */
return;
/*
* Make gcc quiescent about thread_references not being
* referenced:
*/
if (thread_references[0] == NULL)
PANIC("Mandatory pthread_* functions not loaded");
/*
* Check for the special case of this process running as
* or in place of init as pid = 1:

View File

@ -54,6 +54,31 @@
#include <pthread.h>
#include "pthread_private.h"
/*
* These are needed when linking statically. All references within
* libgcc (and in the future libc) to these routines are weak, but
* if they are not (strongly) referenced by the application or other
* libraries, then the actual functions will not be loaded.
*/
static void *thread_references[] = {
&pthread_once,
&pthread_key_create,
&pthread_key_delete,
&pthread_getspecific,
&pthread_setspecific,
&pthread_mutex_init,
&pthread_mutex_destroy,
&pthread_mutex_lock,
&pthread_mutex_trylock,
&pthread_mutex_unlock,
&pthread_cond_init,
&pthread_cond_destroy,
&pthread_cond_wait,
&pthread_cond_timedwait,
&pthread_cond_signal,
&pthread_cond_broadcast
};
#ifdef GCC_2_8_MADE_THREAD_AWARE
typedef void *** (*dynamic_handler_allocator)();
extern void __set_dynamic_handler_allocator(dynamic_handler_allocator);
@ -98,6 +123,13 @@ _thread_init(void)
/* Only initialise the threaded application once. */
return;
/*
* Make gcc quiescent about thread_references not being
* referenced:
*/
if (thread_references[0] == NULL)
PANIC("Mandatory pthread_* functions not loaded");
/*
* Check for the special case of this process running as
* or in place of init as pid = 1:

View File

@ -54,6 +54,31 @@
#include <pthread.h>
#include "pthread_private.h"
/*
* These are needed when linking statically. All references within
* libgcc (and in the future libc) to these routines are weak, but
* if they are not (strongly) referenced by the application or other
* libraries, then the actual functions will not be loaded.
*/
static void *thread_references[] = {
&pthread_once,
&pthread_key_create,
&pthread_key_delete,
&pthread_getspecific,
&pthread_setspecific,
&pthread_mutex_init,
&pthread_mutex_destroy,
&pthread_mutex_lock,
&pthread_mutex_trylock,
&pthread_mutex_unlock,
&pthread_cond_init,
&pthread_cond_destroy,
&pthread_cond_wait,
&pthread_cond_timedwait,
&pthread_cond_signal,
&pthread_cond_broadcast
};
#ifdef GCC_2_8_MADE_THREAD_AWARE
typedef void *** (*dynamic_handler_allocator)();
extern void __set_dynamic_handler_allocator(dynamic_handler_allocator);
@ -98,6 +123,13 @@ _thread_init(void)
/* Only initialise the threaded application once. */
return;
/*
* Make gcc quiescent about thread_references not being
* referenced:
*/
if (thread_references[0] == NULL)
PANIC("Mandatory pthread_* functions not loaded");
/*
* Check for the special case of this process running as
* or in place of init as pid = 1: