This is the mail archive of the binutils@sourceware.cygnus.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: A glibc dynamic linker or gld bug?


> Mailing-List: contact libc-hacker-help@sourceware.cygnus.com; run by ezmlm
> Date: Mon, 5 Jul 1999 20:48:14 -0700
> From: Richard Henderson <rth@twiddle.net>
> Cc: hjl@lucon.org, drepper@cygnus.com, ian@cygnus.com,
>         binutils@sourceware.cygnus.com, libc-hacker@sourceware.cygnus.com,
>         jgg@ualberta.ca
> 
> On Mon, Jul 05, 1999 at 02:55:51PM +1000, Geoff Keating wrote:
> > There is no way that a weak symbol defined in an
> > executable can be overriden by anything else, so there should be no
> > relocations referring to it.
> 
> In the weak model prefered by glibc and SGI, sure there is.
> A strong symbol defined in a shared library will override 
> the weak symbol in the main executable.
> 
> But this is not the model Sun prefers, since it kills their
> cute lazy loading scheme.

I now understand the bug report.  The problem on powerpc would look
similar if ld was trying to implement that weak symbol model.

However, clearly it is not, at least not for data objects.  The
problem is that, for instance in the executable given, it is necessary
to emit a R_*_COPY reloc for any data objects which are defined weak.

The current linker (well, the 981225 snapshot), however, only does
this for data objects that go in the .dyn.bss pseudo-section, at least on
i386, sparc, and ppc; that is, data objects that are not defined in
the application.

Note that in this case, ld.so is responsible for determining where the
'true' data for the data object is, and using it for the R_*_COPY
reloc.  It is also responsible for not doing the copy if it turned out
that there is never a strong definition of the symbol.

It must also ensure that any relocs to the weak symbol (from shared
libraries) end up pointed to the copy in the application, in the same
way that relocs to functions in shared libraries end up pointed to a
PLT entry in the application instead of the real function.

To make all this clear, I attach a shell script.  On ppc, it prints
the following at the end:

+ ./weak-w-wp-wm
1 1 1 
+ ./weak-w-sp-wm
1 2 1 
+ ./weak-wp-wm-s
1 1 1 
+ ./weak-sp-wm-s
1 1 1 

On sparc-solaris it prints:

+ ./weak-w-wp-wm 
1 1 1 
+ ./weak-w-sp-wm 
1 1 1 
+ ./weak-wp-wm-s 
1 1 1 
+ ./weak-sp-wm-s 
1 1 1 

which is what I expected.

You're saying that it should print, on glibc

+ ./weak-w-wp-wm
1 1 1 
+ ./weak-w-sp-wm
2 2 2
+ ./weak-wp-wm-s
1 1 1 
+ ./weak-sp-wm-s
1 1 1 

-- 
Geoffrey Keating <geoffk@ozemail.com.au>

===File ~/glibc-tests/weaktest.c============================
#define CONCAT(x,y) x ## y
#define CONCAT2(x,y) CONCAT(x,y)
#define STRING(x) #x
#define STRING2(x) STRING(x)

#ifdef WEAKDATA
#pragma weak dataitem
#endif

const char *dataitem = "weaktest-" STRING2(NUM) ".c";

const char *CONCAT2(getdataitem_,NUM)(void) 
{
  return dataitem;
}

extern const char *getdataitem_1(void);
extern const char *getdataitem_2(void);
extern const char *getdataitem_3(void);
extern const char *getdataitem_4(void);

#ifdef MAIN
#include <stdio.h>
int main(void)
{
  static const char *(*const (funcs[MAIN]))(void) = {
    getdataitem_1,
#if MAIN >= 2
    getdataitem_2,
#endif
#if MAIN >= 3
    getdataitem_3,
#endif
#if MAIN >= 4
    getdataitem_4
#endif
  };
  int i;

  for (i = 0; i < MAIN; i++)
    if (funcs[i])
      printf("getdataitem_%d has getdataitem defined in %s\n", i+1,
	     funcs[i]());
    else
      printf("getdataitem_%d is NULL\n", i+1);
}
#endif
============================================================

===File ~/glibc-tests/weaktest.sh===========================
#!/bin/sh
set -x
set -e
gcc -c -DNUM=1 weaktest.c -O -o weak1-strong.o
gcc -c -DNUM=1 -DWEAKDATA weaktest.c -O -o weak1-weak.o
gcc -c -DNUM=1 -fpic -DWEAKDATA weaktest.c -O -o weak1-weak-pic.o
gcc -shared -DNUM=2 -DWEAKDATA -fpic weaktest.c -O -o weak2-weak-pic.so
gcc -shared -DNUM=2 -DWEAKDATA -fpic weaktest.c -O -o weak2-strong-pic.so
gcc -c -DNUM=3 -DWEAKDATA -DMAIN=3 weaktest.c -O -o weak3-weak-main.o

gcc weak1-weak.o ./weak2-weak-pic.so weak3-weak-main.o -o weak-w-wp-wm
gcc weak1-weak.o ./weak2-strong-pic.so weak3-weak-main.o -o weak-w-sp-wm
gcc weak1-strong.o ./weak2-strong-pic.so weak3-weak-main.o -o weak-s-sp-wm
gcc ./weak2-strong-pic.so weak3-weak-main.o weak1-strong.o -o weak-sp-wm-s

============================================================

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]