Bug 21983

Summary: gcc fails to link shared libraries against libgcc
Product: Base System Reporter: pfeifer <pfeifer>
Component: gnuAssignee: David E. O'Brien <obrien>
Status: Closed FIXED    
Severity: Affects Only Me CC: weigand
Priority: Normal    
Version: 4.1-RELEASE   
Hardware: Any   
OS: Any   

Description pfeifer 2000-10-14 12:50:01 UTC
	When generating an executable, gcc 2.95.2 as shipped with FreeBSD
	4.1 links against libgcc, which includes important helper functions
	like __fixunsdfdi. For shared libraries, this does not happen.

	In some cases, like the example included below or the Wine port,
	shared libraries will have unresolved references to libgcc symbols.

	If such a library is linked against an executable, the unresolved
	libraries will be linked against the executable (sic!) and when
	loading the library upon startup of the executable, the reference
	is resolved.

	If such a library is loaded during run-time (by means of dlopen()),
	the executable may lack these helper functions as these were neeeded
	for the executable itself and dlopen() will fail.

	This is a bug in the hacked version of gcc 2.95.2 shipped with
	FreeBSD 4.1, a version of gcc 2.95.2 from pristine sources does
	not have this bug.
 
	Thanks to Ulrich Weigand <weigand@immd1.informatik.uni-erlangen.de>
	for tracking down and analysing this.

Fix: 

Remove the patch against FSF GCC 2.95.2 that causes this change.

	Modify the GCC specs to link against libgcc_pic?
How-To-Repeat: 
	Execute the following commands

 	  gcc -shared -o test.so test.c
          gcc -o main main.c
	  ./main

	using the following two source files:

	test.c

	  unsigned long long test(double x)
	  {
	  #if 1
	    return (unsigned long long) x;
	  #else
	    return 0;
	  #endif
	  }

	main.c

	  #include <dlfcn.h>

	  unsigned long long (*test)(double x);

	  int main()
	  {
	    void *lib;

	    lib = dlopen("./test.so", RTLD_NOW);
	    if (!lib)
	    {
	      printf("dlopen: %s\n", dlerror());
	      exit(1);
	      }

	    test = dlsym(lib, "test");
	    if (!test)
	    {
	      printf("dlsym: %s\n", dlerror());
	      exit(1);
	    }

	    test(1.0);
	  }
Comment 1 Johan Karlsson freebsd_committer freebsd_triage 2000-10-14 15:07:31 UTC
Responsible Changed
From-To: freebsd-bugs->obrien

Over to GCC maintainer.
Comment 2 David E. O'Brien freebsd_committer freebsd_triage 2000-11-10 17:14:26 UTC
State Changed
From-To: open->closed

Fixed in -current and will be in -stable right after the 4.2 code freeze 
(unless the release engineer decides to allow a MFC, then it will be in 
4.2).