Subject: toolchain/15593: new-toolchain linker doesn't set DT_TEXTREL often enough
To: None <gnats-bugs@gnats.netbsd.org>
From: None <thorpej@shagadelic.org>
List: netbsd-bugs
Date: 02/12/2002 19:39:41
>Number:         15593
>Category:       toolchain
>Synopsis:       new-toolchain linker doesn't set DT_TEXTREL often enough
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    toolchain-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Feb 12 19:41:00 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Jason R. Thorpe
>Release:        NetBSD 1.5Z
>Organization:
Wasabi Systems, Inc.
>Environment:
	
	
System: NetBSD dr-evil 1.5Z NetBSD 1.5Z (DR-EVIL) #252: Sun Dec 9 17:39:53 PST 2001 thorpej@dr-evil:/u1/netbsd/src/sys/arch/i386/compile/DR-EVIL i386
Architecture: i386
Machine: i386
>Description:
	The new-toolchain linker does not set DT_TEXTREL in
	the .dynamic section in all cases where it is necesasry.

	Consider the following shared library (liblcms.so.1.6,
	used by Magicpoint):

Dynamic segment at offset 0xb598 contains 18 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libm.so.0]
 0x0000000e (SONAME)                     Library soname: [liblcms.so.1]
 0x0000000f (RPATH)                      Library rpath: [/usr/pkg/lib]
 0x0000000c (INIT)                       0x192c
 0x0000000d (FINI)                       0xab54
 0x00000004 (HASH)                       0xb4
 0x00000005 (STRTAB)                     0xe6c
 0x00000006 (SYMTAB)                     0x51c
 0x0000000a (STRSZ)                      1775 (bytes)
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000003 (PLTGOT)                     0xc660
 0x00000002 (PLTRELSZ)                   800 (bytes)
 0x00000014 (PLTREL)                     REL
 0x00000017 (JMPREL)                     0x15a4
 0x00000011 (REL)                        0x155c
 0x00000012 (RELSZ)                      72 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x00000000 (NULL)                       0x0

Relocation section '.rel.rodata' at offset 0x155c contains 6 entries:
  Offset    Info  Type            Symbol's Value  Symbol's Name
  0000ae14  00008 R_386_RELATIVE       
  0000ae30  00008 R_386_RELATIVE       
  0000ae4c  00008 R_386_RELATIVE       
  0000ae68  00008 R_386_RELATIVE       
  0000ae84  00008 R_386_RELATIVE       
  0000aea0  00008 R_386_RELATIVE       

	When processing the first of these relocations, ld.elf_so
	faults, because it only mprotect's the "text" section if
	DT_TEXTREL is set in .dynamic.

>How-To-Repeat:
	Build and install the Magicpoint package and all of its
	dependencies from scratch with the new-toolchain.

	Attempt to run the resulting mgp binary.
>Fix:
	The following hack in ld.elf_so works around the problem, but
	is obviously not the correct long-term solution.


Index: reloc.c
===================================================================
RCS file: /cvsroot/basesrc/libexec/ld.elf_so/reloc.c,v
retrieving revision 1.51
diff -c -r1.51 reloc.c
*** reloc.c	2002/02/03 23:34:42	1.51
--- reloc.c	2002/02/13 03:32:58
***************
*** 749,755 ****
  		    (long)(obj->pltrellim - obj->pltrel),
  		    (long)(obj->pltrelalim - obj->pltrela)));
  
! 		if (obj->textrel) {
  			/*
  			 * There are relocations to the write-protected text
  			 * segment.
--- 749,755 ----
  		    (long)(obj->pltrellim - obj->pltrel),
  		    (long)(obj->pltrelalim - obj->pltrela)));
  
! 		if (1||obj->textrel) {
  			/*
  			 * There are relocations to the write-protected text
  			 * segment.
***************
*** 792,798 ****
  					ok = 0;
  			}
  		}
! 		if (obj->textrel) {	/* Re-protected the text segment. */
  			if (mprotect(obj->mapbase, obj->textsize,
  				     PROT_READ | PROT_EXEC) == -1) {
  				_rtld_error("%s: Cannot write-protect text "
--- 792,798 ----
  					ok = 0;
  			}
  		}
! 		if (1||obj->textrel) {	/* Re-protected the text segment. */
  			if (mprotect(obj->mapbase, obj->textsize,
  				     PROT_READ | PROT_EXEC) == -1) {
  				_rtld_error("%s: Cannot write-protect text "
>Release-Note:
>Audit-Trail:
>Unformatted: