This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Undo dynamic symbol state after regular object sym type mismatch


Hi Alan,

 CC-ing `libc-alpha' for any feedback on the dynamic loader issue.

> >  In an attempt to prevent new MIPS target failures in preparation for the 
> > 2.29 release I have now looked into it and what the MIPS backend produces 
> > looks correct to me according to the MIPS psABI.
> > 
> >  Specifically, while linking the `indirect5a' executable, in the 
> > `indirect5a.o' object supplied we have a locally-defined global `bar' 
> > symbol referred to -- in the case of the o32 ABI -- with an R_MIPS_GOT16 
> > relocation, which is absolutely fine for a MIPS SVR4 psABI executable.  
> > In response the MIPS backend creates the mandatory global GOT entry and 
> 
> That's fine.

 If we want to prevent some global symbols from being exported, then not 
according to the SVR4 MIPS psABI, which requires each global GOT entry to 
have a corresponding global dynamic symbol table entry.

> > its corresponding dynsym entry for `bar'.
> 
> But in my opinion this is a bug.  A symbol in an executable shouldn't
> be made dynamic unless it is referenced by a dynamic object, or by
> --export-dynamic or other similar options.  Since "bar" in the
> executable is a variable and "bar" in the dynamic library a function,
> the dynamic library can't be referencing the executable "bar".  The
> executable GOT entry for "bar" will need a dynamic relocation in a
> PIE, but that can be a relative relocation not needing a symbol.

 The MIPS SVR4 psABI uses implicitly relocated GOT, there are no dynamic 
GOT relocations defined (the only dynamic reloc is R_MIPS_REL32, for 
static references to global symbols) and dynamic GOT relocation is 
performed according to the DT_MIPS_GOTSYM dynamic entry: all entries whose 
index is lower are relocated by the base address and the entries that 
follow are relocated according to the external part of the dynamic symbol 
table, which has to be identity mapped to the external part of GOT.  So an 
external GOT entry by definition is associated with an external dynamic 
symbol.

 So if we want to prevent a global symbol from being exported, then (as 
long as it is locally referenced) it has to be assigned to the local part 
of the GOT, which in turn means either giving it a local dynamic symbol 
table entry or (IMO preferably) none at all.  However this will cause 
trouble for undefined weak symbols in PIE executables, as making these 
symbols local will make the corresponding GOT entries relocated by the 
base address and consequently any NULL pointer checks which typically 
guard the use of such symbols will not work anymore, as already noted in 
PR ld/21375.

 Note that in the SVR4 MIPS psABI there is no way defined for a GOT entry 
to remain unchanged in dynamic loading: each is either relocated by the 
base address or refers to a global dynamic symbol table entry.  
Contrariwise static references to global symbols are not an issue as 
R_MIPS_REL32 relocations can be simply omitted, leaving the reference 
unrelocated in the dynamic load.

 The only solution to PR ld/21375 I have come up with so far is using a 
global absolute symbol for GOT entries used for any local references to 
undefined weak symbols, either by tweaking the attributes of the original 
symbol (setting SHN_ABS/STB_GLOBAL combined with STV_HIDDEN or 
STV_INTERNAL; but that breaks strict gABI compliance) or by redirecting to 
a special reserved symbol, say `__gnu_absolute_zero', whose value is 
globally zero (and SHN_ABS/STB_GLOBAL/STV_DEFAULT).  The latter approach 
has the advantage of reducing the number of GOT entries (which is always 
advantageous) where multiple undefined weak symbols are present.

 However this merely shifts the issue with PIE binaries to the dynamic 
loader, which currently does not tell absolute and regular symbols apart 
and relocates both kinds by the base address, as noted in glibc BZ 19818.

 This is PR ld/21805 now, for tracking purposes.  I have experimented with 
a preliminary fix, and in addition to cleaning indirect.exp test results 
it indeed makes a number of other test cases crash, that work fine right 
now.  In the course of this investigation I have also identified what I 
think are a generic ELF linker bug and an issue in the Cris backend 
respectively, both of which I'll be sending patches for soon.

 So I think the correct way to address the problem with the MIPS backend 
is to:

1. Fix glibc BZ 19818, the dynamic loader's absolute symbol bug.

2. Bump ABIVERSION up in `ld.so' for correct SHN_ABS support.

3. Fix PR ld/21375, the local undefined weak symbol bug.

4. Document `--export-dynamic' as the default with MIPS PIE binaries.

5. Fix PR ld/21805, this issue, by making `--no-export-dynamic' work for
   SVR4 executables in the first place and then with a PIE executable 
   produce SHN_ABS symbol GOT references for undefined weak symbols and 
   make the executable request the corresponding dynamic loader's 
   ABIVERSION for processing, possibly only where such a SHN_ABS symbol 
   has indeed been produced.

6. Set the defaults for `--export-dynamic'/`--no-export-dynamic' as 
   documented.

-- in this order.

 I am yet reviewing past discussions about our handling of undefined weak 
symbols in PIE executables, in particular PR ld/2218 and the corresponding 
thread at: <https://sourceware.org/ml/binutils/2006-01/msg00193.html> and 
then <https://sourceware.org/ml/binutils/2006-02/msg00023.html>, because 
it seems we're a bit inconsistent here among targets as far as making them 
global or local is concerned, and this is not covered by the ELF gABI 
AFAICT.

 Personally to keep their handling consistent between the static link and 
the dynamic load I am leaning towards thinking that weak symbol references 
from the main executable that are not satisfied at the static link time 
ought to resolve to zero with the original reference removed, and ones 
that are satisfied by a dynamic dependency ought to be converted to a 
global symbol reference.

 Questions or comments?  I will appreciate further input.  This is 
obviously too complex an issue for the pending 2.29 binutils release.

  Maciej


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