Subject: port-alpha/5099: Link error on large C++ program
To: None <gnats-bugs@gnats.netbsd.org>
From: Cliff Romash <romash@bbn.com>
List: netbsd-bugs
Date: 03/02/1998 15:54:13
>Number:         5099
>Category:       port-alpha
>Synopsis:       Link error on large C++ program
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Mar  2 13:05:01 1998
>Last-Modified:
>Originator:     Cliff Romash
>Organization:
	BBN Technologies/GTE Internetworking
>Release:        NetBSD 1.2G (I think the problem is also in 1.3)
>Environment:
System: NetBSD nec3.bbn.com 1.2G NetBSD 1.2G (SRDEV) #10: Tue Sep 9 19:45:01 EDT 1997 yba@nec3.bbn.com:/usr/src/sys/arch/alpha/compile/SRDEV alpha
/usr/lib/crtbegin.o

>Description:
	A user at our site has a C++ program with a .text section of greater than 4 meg. It fails to link with the 
	error message:
	
	/usr/lib/crtbegin.o: In function `__dtors':
	crtbegin.c(.fini+0x10): relocation truncated to fit: BRADDR text

	After investigation, I believe that /usr/lib/crtbegin.o has a bsr instruction for the call from __fini to __dtors.
	Since these are in different sections (one of which is loaded first, but with the user's .text, and the other after,
	the displacement field in the bsr is not large enough to reach the routine __dtors, resulting in the link error.

	There are two issues here. First, why are __fini and __dtors in different sections (also __init and __ctors)? 
	Second, since they are, I think that the C compiler should NOT generate a bsr to call __dtors from __fini. Note
	that it is smart enough to use a JSR instruction for external calls.

	Here is the output of objdump -disassemble /usr/lib/crtbegin.o :


/usr/lib/crtbegin.o:     file format elf64-alpha

Disassembly of section .init:

0000000000000000 <__init>:
   0:	00 00 bb 27 	ldah	gp,0(t12)
   4:	00 00 bd 23 	lda	gp,0(gp)
   8:	f0 ff de 23 	lda	sp,-16(sp)
   c:	00 00 5e b7 	stq	ra,0(sp)
  10:	00 00 5d a4 	ldq	t1,0(gp)
  14:	00 00 22 a0 	ldl	t0,0(t1)
  18:	03 00 20 f4 	bne	t0,28 <__init+28>
  1c:	01 34 e0 47 	mov	0x1,t0
  20:	00 00 22 b0 	stl	t0,0(t1)
  24:	00 00 40 d3 	bsr	ra,28 <__init+28>
  28:	00 00 5e a7 	ldq	ra,0(sp)
  2c:	1e 14 c2 43 	addq	sp,0x10,sp
  30:	01 80 fa 6b 	ret	zero,(ra),0x1
  34:	00 00 00 00 	halt
Disassembly of section .text:

0000000000000000 <.text>:
   0:	00 00 bb 27 	ldah	gp,0(t12)
   4:	00 00 bd 23 	lda	gp,0(gp)
   8:	e0 ff de 23 	lda	sp,-32(sp)
   c:	00 00 5e b7 	stq	ra,0(sp)
  10:	08 00 3e b5 	stq	s0,8(sp)
  14:	10 00 5e b5 	stq	s1,16(sp)
  18:	00 00 5d a4 	ldq	t1,0(gp)
  1c:	00 00 22 a5 	ldq	s0,0(t1)
  20:	01 34 20 41 	addq	s0,0x1,t0
  24:	0b 00 20 f4 	bne	t0,54 <.text+54>
  28:	09 34 e0 47 	mov	0x1,s0
  2c:	08 00 22 a4 	ldq	t0,8(t1)
  30:	07 00 20 e4 	beq	t0,50 <.text+50>
  34:	1f 04 ff 47 	nop	
  38:	1f 04 ff 47 	nop	
  3c:	1f 04 ff 47 	nop	
  40:	09 34 20 41 	addq	s0,0x1,s0
  44:	41 06 22 41 	s8addq	s0,t1,t0
  48:	00 00 21 a4 	ldq	t0,0(t0)
  4c:	fc ff 3f f4 	bne	t0,40 <.text+40>
  50:	29 35 20 41 	subq	s0,0x1,s0
  54:	00 00 3d a4 	ldq	t0,0(gp)
  58:	4a 06 21 41 	s8addq	s0,t0,s1
  5c:	05 00 e0 c3 	br	74 <.text+74>
  60:	00 00 6a a7 	ldq	t12,0(s1)
  64:	2a 15 41 41 	subq	s1,0x8,s1
  68:	00 40 5b 6b 	jsr	ra,(t12),6c <.text+6c>
  6c:	00 00 ba 27 	ldah	gp,0(ra)
  70:	00 00 bd 23 	lda	gp,0(gp)
  74:	29 35 20 41 	subq	s0,0x1,s0
  78:	01 34 20 41 	addq	s0,0x1,t0
  7c:	f8 ff 3f f4 	bne	t0,60 <.text+60>
  80:	00 00 5e a7 	ldq	ra,0(sp)
  84:	08 00 3e a5 	ldq	s0,8(sp)
  88:	10 00 5e a5 	ldq	s1,16(sp)
  8c:	1e 14 c4 43 	addq	sp,0x20,sp
  90:	01 80 fa 6b 	ret	zero,(ra),0x1
  94:	1f 04 ff 47 	nop	
  98:	00 00 bb 27 	ldah	gp,0(t12)
  9c:	00 00 bd 23 	lda	gp,0(gp)
  a0:	f0 ff de 23 	lda	sp,-16(sp)
  a4:	00 00 5e b7 	stq	ra,0(sp)
  a8:	08 00 3e b5 	stq	s0,8(sp)
  ac:	00 00 3d a4 	ldq	t0,0(gp)
  b0:	09 14 21 40 	addq	t0,0x8,s0
  b4:	08 00 21 a4 	ldq	t0,8(t0)
  b8:	08 00 20 e4 	beq	t0,dc <.text+dc>
  bc:	1f 04 ff 47 	nop	
  c0:	00 00 69 a7 	ldq	t12,0(s0)
  c4:	09 14 21 41 	addq	s0,0x8,s0
  c8:	00 40 5b 6b 	jsr	ra,(t12),cc <.text+cc>
  cc:	00 00 ba 27 	ldah	gp,0(ra)
  d0:	00 00 bd 23 	lda	gp,0(gp)
  d4:	00 00 29 a4 	ldq	t0,0(s0)
  d8:	f9 ff 3f f4 	bne	t0,c0 <.text+c0>
  dc:	00 00 5e a7 	ldq	ra,0(sp)
  e0:	08 00 3e a5 	ldq	s0,8(sp)
  e4:	1e 14 c2 43 	addq	sp,0x10,sp
  e8:	01 80 fa 6b 	ret	zero,(ra),0x1
	...
Disassembly of section .fini:

0000000000000000 <__fini>:
   0:	00 00 bb 27 	ldah	gp,0(t12)
   4:	00 00 bd 23 	lda	gp,0(gp)
   8:	f0 ff de 23 	lda	sp,-16(sp)
   c:	00 00 5e b7 	stq	ra,0(sp)
  10:	00 00 40 d3 	bsr	ra,14 <__fini+14>
  14:	00 00 5e a7 	ldq	ra,0(sp)
  18:	1e 14 c2 43 	addq	sp,0x10,sp
  1c:	01 80 fa 6b 	ret	zero,(ra),0x1



	


>How-To-Repeat:
	Build a C++ program with a .text section greater than 4MB.

>Fix:
Here is a diff of the change we are using to work around the problem,
although I think that either removing the section statements altogether, or
putting __dtors in the same section as __fini would be better.


108c108
< extern void __fini(void) __attribute__((section(".fini")));
---
> extern void __fini(void);

>Audit-Trail:
>Unformatted: