diff options
author | jdp <jdp@FreeBSD.org> | 1999-06-06 15:59:08 +0000 |
---|---|---|
committer | jdp <jdp@FreeBSD.org> | 1999-06-06 15:59:08 +0000 |
commit | eef63afd3db4c6c587a87131d0ee987cbe4fdda8 (patch) | |
tree | c0c7f39cc463192de0bdb8ee07f7b4a7ffa4721b /lib/csu/alpha | |
parent | ebc36fcc1a6eae39c46fe22dbf37bb62b99009cb (diff) | |
download | FreeBSD-src-eef63afd3db4c6c587a87131d0ee987cbe4fdda8.zip FreeBSD-src-eef63afd3db4c6c587a87131d0ee987cbe4fdda8.tar.gz |
Call do_ctors() and do_dtors() using indirect calls through function
pointers. The calls are in different sections from the functions
being called, and they can potentially be far away. On a very large
program, the 21-bit displacement field of the BSR instruction
overflowed at link time.
Diffstat (limited to 'lib/csu/alpha')
-rw-r--r-- | lib/csu/alpha/crtbegin.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/lib/csu/alpha/crtbegin.c b/lib/csu/alpha/crtbegin.c index c3fefff..ee88aa1 100644 --- a/lib/csu/alpha/crtbegin.c +++ b/lib/csu/alpha/crtbegin.c @@ -22,7 +22,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: crtbegin.c,v 1.1.1.1 1998/03/07 20:27:10 jdp Exp $ + * $Id: crtbegin.c,v 1.3 1998/03/11 20:48:56 jb Exp $ */ typedef void (*fptr)(void); @@ -51,12 +51,21 @@ do_dtors(void) (**fpp)(); } +/* + * On very large programs, it is possible to get a relocation overflow + * of the 21-bit BSR displacements. It is particularly likely for the + * calls from _init() and _fini(), because they are in separate sections. + * Avoid the problem by forcing indirect calls. + */ +static void (*p_do_ctors)(void) = do_ctors; +static void (*p_do_dtors)(void) = do_dtors; + extern void _init(void) __attribute__((section(".init"))); void _init(void) { - do_ctors(); + (*p_do_ctors)(); } extern void _fini(void) __attribute__((section(".fini"))); @@ -64,5 +73,5 @@ extern void _fini(void) __attribute__((section(".fini"))); void _fini(void) { - do_dtors(); + (*p_do_dtors)(); } |