Subject: toolchain/32074: dynamic linker pollutes dynamic symbol namespace
To: None <toolchain-manager@netbsd.org, gnats-admin@netbsd.org,>
From: None <stephen@degler.net>
List: netbsd-bugs
Date: 11/15/2005 04:19:00
	Note: There was a bad value `' for the field `Class'.
	It was set to the default value of `sw-bug'.

>Number:         32074
>Category:       toolchain
>Synopsis:       The dynamic linker pollutes dynamic symbol namespace,
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    toolchain-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Nov 15 04:19:00 +0000 2005
>Originator:     Stephen Degler <skd@netbsd.org>
>Release:        NetBSD 3.99.11
>Organization:
Very little, at best.
	
>Environment:
	
	
System: NetBSD pharoh.degler.net 3.99.11 NetBSD 3.99.11 (PHAROH.acpi) #29: Sat Nov 12 22:20:55 EST 2005 sdegler@pharoh.degler.net:/vol1/NetBSD/kernels/PHAROH.acpi i386
Architecture: i386
Machine: i386
>Description:
	ld.elf_so dynamic symbol table contains lobal defitions of statically
	linked libc symbols, which confuses gdb in the cases where there are
	symbol collsions.

	For instance, set a break point in malloc.  gdb invariably finds the
	symbol ebedded in the dynamic linker itself, not the libc.so instance.
	
>How-To-Repeat:
	
% cat test1.c
#include <stdio.h>
#include <sys/stat.h>
#include <sys/mman.h>

int j = 5;
int main(int argc, char **argv)
{
  char *foo;

  foo = malloc(16);

  printf("Hello World %p %p %p\n",&malloc, &foo,foo);
  exit(0);
}

% make CFLAGS=-g test1
% gdb test1
% gdb test1
GNU gdb 5.3nb1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386--netbsdelf"...
(gdb) b main
Breakpoint 1 at 0x8048758: file test1.c, line 14.
(gdb) b malloc
Breakpoint 2 at 0x804849c
(gdb) run
Starting program: /home/sdegler/test1
Breakpoint 2 at 0xbdbf80a0

Breakpoint 1, main (argc=1, argv=0xbfbfec08) at test1.c:10
10        foo = malloc(16);
(gdb) cont
Continuing.
Hello World 0x804849c 0xbfbfeba0 0x804b030

Program exited normally.
(gdb)

Note the breakpoint for malloc is never hit.

>Fix:
	

Adding a ld "version script" removes all of the libc functions
embedded in the dynamic linker from its dynamic symbol table, and
exports only those symbols which should be accessed from the dynamic
linker itself.

The following patch fixes things for me, but others may want to tweak
it for esthetics.  It seems to pass /usr/src/regress/usr.bin/rtld
after the patch is applied as well.

Index: libexec/ld.elf_so/Makefile
===================================================================
RCS file: /cvsroot/src/libexec/ld.elf_so/Makefile,v
retrieving revision 1.72
diff -u -u -r1.72 Makefile
--- libexec/ld.elf_so/Makefile	4 Jun 2005 16:17:17 -0000	1.72
+++ libexec/ld.elf_so/Makefile	15 Nov 2005 04:02:59 -0000
@@ -25,7 +25,7 @@
 
 LDFLAGS+=	-shared -symbolic -nostartfiles
 LDFLAGS+=	-Wl,-non_shared
-
+LDFLAGS+=	-Wl,--version-script=${.CURDIR}/version_script
 # Adds SRCS, CPPFLAGS, LDFLAGS, etc.  Must go first so MD startup source
 # is first.
 .if exists($M/Makefile.inc)
Index: libexec/ld.elf_so/version_script
===================================================================
RCS file: libexec/ld.elf_so/version_script
diff -N libexec/ld.elf_so/version_script
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libexec/ld.elf_so/version_script	15 Nov 2005 04:02:59 -0000
@@ -0,0 +1,2 @@
+{ global: dl*; local: *; };
+

	
	

>Unformatted:
 		which in turn confuses gdb.